Date: Sat, 24 May 1997 04:54:40 +0200 From: Tor Egge <Tor.Egge@idi.ntnu.no> To: Tor.Egge@idi.ntnu.no Cc: freebsd-bugs@hub.freebsd.org Subject: Re: kern/3581: trap 12 in lockstatus() Message-ID: <199705240254.EAA17882@pat.idt.unit.no> In-Reply-To: Your message of "Fri, 23 May 1997 10:10:01 -0700 (PDT)" References: <199705231710.KAA02145@hub.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Some more info: skarven:~$ ps axl -M /var/crash/vmcore.1 | grep 28620 28620 9144 151711 0 -14 0 972 0 vn_loc DEs p0- 0:00.00 (bash) 28620 9159 151711 257 28 0 384 0 - Z p0- 0:00.00 (desclient- Here the vnode for /dev/ttyp0 had two references, one from the controlling tty, and one from the system file table. process 9144 and 9159 got SIGHUP and started to exit. Since process 9144 was the session leader, it called vop_revoke which called vgone which called vclean. When vclean was called, vp->v_usecount was 2. vclean increased vp->usecount to 3. Then vclean blocked in vinvalbuf (in order to read inodes from disks, to update time stamps). Process 9159 then continued to close its file descriptors, reducing the reference counts in the system file table to 0 for the stdin/stdout/stderr entry which referenced the vnode for /dev/ttyp0. Thus vn_close was called, and v_usecount was reduced from 3 to 2. Process 9159 then became a zombie. Then process 9144 continued, called VOP_CLOSE, and a special hack removed the controlling terminal and reduced v_usecount from 2 to 1. When vrele was called, v_usecount became 0, and vn_lock was called with a deadlock as a result. Suggested Fix: First part: Don't enable the special `close controlling terminal hack' if cleaning of the vnode is in progress. Second part: Release references to the vnode for the controlling terminal when the session structure is freed. This should take care of any dangling references introduced by the first part. -------- Index: spec_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/specfs/spec_vnops.c,v retrieving revision 1.39 diff -c -r1.39 spec_vnops.c *** spec_vnops.c 1997/05/01 19:12:22 1.39 --- spec_vnops.c 1997/05/24 00:39:29 *************** *** 595,600 **** --- 595,601 ---- * plus the session), release the reference from the session. */ if (vcount(vp) == 2 && ap->a_p && + (vp->v_flag & VXLOCK) == 0 && vp == ap->a_p->p_session->s_ttyvp) { vrele(vp); ap->a_p->p_session->s_ttyvp = NULL; Index: kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.26 diff -u -r1.26 kern_proc.c --- kern_proc.c 1997/03/24 11:24:36 1.26 +++ kern_proc.c 1997/05/24 02:03:59 @@ -56,6 +56,7 @@ #include <vm/pmap.h> #include <vm/vm_map.h> #include <sys/user.h> +#include <sys/vnode.h> struct prochd qs[NQS]; /* as good a place as any... */ struct prochd rtqs[NQS]; /* Space for REALTIME queues too */ @@ -285,12 +286,21 @@ register struct pgrp *pgrp; { - if (pgrp->pg_session->s_ttyp != NULL && - pgrp->pg_session->s_ttyp->t_pgrp == pgrp) - pgrp->pg_session->s_ttyp->t_pgrp = NULL; + struct session *sp; + + sp = pgrp->pg_session; + + if (sp->s_ttyp != NULL && + sp->s_ttyp->t_pgrp == pgrp) + sp->s_ttyp->t_pgrp = NULL; LIST_REMOVE(pgrp, pg_hash); - if (--pgrp->pg_session->s_count == 0) - FREE(pgrp->pg_session, M_SESSION); + if (--sp->s_count == 0) { + if (sp->s_ttyvp) + VOP_REVOKE(sp->s_ttyvp, REVOKEALL); + if (sp->s_ttyvp) + vrele(sp->s_ttyvp); + FREE(sp, M_SESSION); + } FREE(pgrp, M_PGRP); } ---------
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705240254.EAA17882>