Subject: Re: revoke(2), /dev/console and /dev/ttyE0
To: None <tech-kern@netbsd.org>
From: David Laight <david@l8s.co.uk>
List: tech-kern
Date: 10/14/2003 12:44:18
On Mon, Oct 13, 2003 at 06:41:48PM +0100, David Laight wrote:
> I've found a 'little' problem with the way revoke interacts with the console.
> Under some circumstances, not all the users of the underlying tty
> go away, which leaves the session attached to the tty.
> This stops the next getty from creating the controlling terminal - leaving
> a tty session with no stdout or stderr!

I've stirred the stew...

When /dev/console is a controlling terminal, s_ttyvp is the vnode for
/dev/console and s_ttyp points to the data area for /dev/ttyE0.

When the login shell exits and all its files are closed, a hack in
spec_close detects that the controlling tty is being closed and dumps
the reference from the session.  This causes /dev/console to be closed,
and its reference on /dev/ttyE0 to be lost.
However this isn't necessarily the last reference to /dev/ttyE0 so
ttyclose isn't always called and the tty is left referencing the session
(but the session doesn't reference the tty).
This state cannot be cleared from the session side.

The following seems to fix the usual case of the session leader being
the last process with the controlling tty open:

Index: spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.69
diff -u -p -r1.69 spec_vnops.c
--- spec_vnops.c	7 Aug 2003 16:32:44 -0000	1.69
+++ spec_vnops.c	14 Oct 2003 11:25:40 -0000
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: spec_vnops.c
 #include <sys/file.h>
 #include <sys/disklabel.h>
 #include <sys/lockf.h>
+#include <sys/tty.h>
 
 #include <miscfs/genfs/genfs.h>
 #include <miscfs/specfs/specdev.h>
@@ -666,9 +667,13 @@ spec_close(v)
 		 */
 		if (count == 2 && ap->a_p &&
 		    vp == ap->a_p->p_session->s_ttyvp) {
+			ap->a_p->p_session->s_ttyvp = NULL;
+			/* and remove reference to session from tty */
+			ap->a_p->p_session->s_ttyp->t_pgrp = NULL;
+			ap->a_p->p_session->s_ttyp->t_session = NULL;
+			SESSRELE(ap->a_p->p_session);
 			vrele(vp);
 			count--;
-			ap->a_p->p_session->s_ttyvp = NULL;
 		}
 		/*
 		 * If the vnode is locked, then we are in the midst

A similar change is needed to exit1() to handle the case where the
session leader exits while other processes (in the session) have the
ctty open.

I think that these changes make the code in ttyclose that clears
t_pgrp and t_session redundant.

Further thoughs anyone?

	David

-- 
David Laight: david@l8s.co.uk