Date: Tue, 3 Jul 2001 18:44:17 +0300 From: Ruslan Ermilov <ru@FreeBSD.ORG> To: Bruce Evans <bde@zeta.org.au> Cc: current@FreeBSD.ORG Subject: Re: TIOCSCTTY Message-ID: <20010703184417.A69095@sunbay.com> In-Reply-To: <Pine.BSF.4.21.0107032328020.41126-100000@besplex.bde.org>; from bde@zeta.org.au on Wed, Jul 04, 2001 at 01:15:17AM %2B1000 References: <20010703152523.C39090@sunbay.com> <Pine.BSF.4.21.0107032328020.41126-100000@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Jul 04, 2001 at 01:15:17AM +1000, Bruce Evans wrote: > On Tue, 3 Jul 2001, Ruslan Ermilov wrote: > > > Weird. I figured out what causes this, it's moused(8). I have inserted > > some debug code into it to see what's going on: > > ... > > LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC > > cuaa1 0 0 0 512 448 216 60 0 OCcl 0 0 term > > consolectl 0 0 0 512 448 1296 256 98 OCc c0b14700 6 term > > 0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyp0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyv0 0 0 0 512 448 1296 256 0 - 0 0 term > > > > As you can see, process 6 (sh /etc/rc autoboot) is the session leader with > > /dev/console as the controlling terminal, and the same session is referenced > > from the `tty' structure for the consolectl device. > > The bug seems to be caused by a combination of sloppy code in moused, > dubious aliasing in syscons and a known bug in cnclose(): > 1. moused opens /dev/consolectl before becoming a daemon. This shouldn't > be a problem, since /dev/consolectl should be a completely different device > from the controlling terminal (which is /dev/console, although you can't > really see that from the ps output since "consolectl" is a poorly chosen > name which is indistinguishable from "console" after ps truncates it to > 3 characters). However: > But my "emulation" program opens /dev/consolectl _after_ becoming a daemon. And yes, I can distinguish "console" from "consolectl" with ``-O tty''. > 2. syscons.c makes /dev/consolectl a sort of alias for /dev/consolectl: > > dev = make_dev(&sc_cdevsw, SC_CONSOLECTL, > UID_ROOT, GID_WHEEL, 0600, "consolectl"); > dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty); > > This obviously breaks the pstat output and complicates debugging (pstat > should display "console" instead of "consolectl"). It apparently also > breaks last-close stuff when /dev/console is closed. > 3. cnclose() already has broken handling of controlling terminals when > /dev/console is last-closed while the physical device underlying the > console is open and /dev/console is a controlling terminal. > /dev/consolectl is different from the physical device underlying > /dev/console (even if the latter is /dev/ttyv0), and is not understood > by cnclose(), but I think the same problem and fix apply. > > > Next, this is after moused(8) calls daemon(3): > > > > USER PID PPID PGID SESS JOBC STAT TT TIME COMMAND > > ... > > root 221 1 221 bf8280 0 Ss ?? 0:00.00 moused -3 -p /dev/cuaa1 -t auto > > root 223 221 221 bf8280 0 S ?? 0:00.00 sh -c (ps axjww; pstat -t) >>/1 > > root 225 223 221 bf8280 0 S ?? 0:00.00 sh -c (ps axjww; pstat -t) >>/1 > > root 227 225 221 bf8280 0 R ?? 0:00.00 ps axjww > > root 6 1 6 b14700 0 Ss+ con 0:00.14 sh /etc/rc autoboot > > root 228 6 6 b14700 0 R+ con 0:00.00 sh /etc/rc autoboot > > No problem here. > I did not mean there is. :-) > > LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC > > cuaa1 0 0 0 512 448 216 60 0 OCcl 0 0 term > > consolectl 0 0 0 512 448 1296 256 109 OCc c0b14700 6 term > > 0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyp0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyv0 0 0 0 512 448 1296 256 0 - 0 0 term > > > > Nothing has changed re: consolectl. It still has session c0b14700 (with > > the session leader PID = 6) bound to it. > > Nothing should have changed, since moused only closed a dup'ed descriptor > for /dev/console. > Sure, this is normal. > The last-close bugs will bite later when ancestors of > moused all close all their descriptors for /dev/console. > Here we can still see the consolectl vs console confusion. > How this applies to my "emulation" program, which opens /dev/consolectl only when in a new session? > > Next, this is the output after the system has booted into multi-user: > > ... > > The session c0b14700 has disappeared from the ps(1) output, but it is still > > referenced from the `tty' structure: > > > > LINE RAW CAN OUT IHIWT ILOWT OHWT LWT COL STATE SESS PGID DISC > > ttyvb 0 0 0 512 448 1296 256 0 - 0 0 term > > ttyva 0 0 0 512 448 2052 256 7 OCc c0c02c80 263 term > > ttyv9 0 0 0 512 448 2052 256 7 OCc c0c02d40 262 term > > ttyv8 0 0 0 512 448 2052 256 7 OCc c0c02e00 261 term > > ttyv7 0 0 0 512 448 2052 256 7 OCc c0c02800 260 term > > ttyv6 0 0 0 512 448 2052 256 7 OCc c0c028c0 259 term > > ttyv5 0 0 0 512 448 2052 256 7 OCc c0c02900 258 term > > ttyv4 0 0 0 512 448 2052 256 7 OCc c0c02940 257 term > > ttyv3 0 0 0 512 448 2052 256 7 OCc c0c02980 256 term > > ttyv2 0 0 0 512 448 2052 256 7 OCc c0c02a40 255 term > > ttyv1 0 0 0 512 448 2052 256 0 OCc c0c02b00 279 term > > cuaa1 0 0 0 512 448 216 60 0 OCcl 0 0 term > > consolectl 0 0 0 512 448 1296 256 0 OCc c0b14700 0 term > > 0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyp0 0 0 0 0 0 0 0 0 - 0 0 term > > ttyv0 0 0 0 512 448 2052 256 7 OCc c0c02bc0 253 term > > Hmm. ttyv0 apparently doesn't share a tty struct with consolectl/console. > I'm familiar with this feature from old versions of syscons but thought that > it was lost. This used to prevent bug (3) for syscons (it always affected > sio and maybe pcvt), but we now have it via the consolectl alias. > > I wonder if the bogus line of zeros is related to miscounting the single > tty struct for console/consolectl as two structs. > > > What I can't understand is how opening a /dev/consolectl in a new session > > doesn't allow the t_session tty pointer to be reset that points to another > > (not existing) session. > > > > (This is probably somehow relates to the fact that the device's close() > > routine is called only on a last reference drop, but I'm not sure.) > > I think I understand the details now: > - on i386's, sccnprobe() sets the physical device for /dev/console to > /dev/consolectl. Thus /dev/consolectl is more than "sort of" an > alias for /dev/console, and bug (3) bites. I don't understand the > minor detail that pstat prefers the "consolectl" alias. > - on alphas, sccnattach() sets the physical device for /dev/console to > /dev/ttyv0. Thus the bugs are gratuitously different. > > I use the following fix for (3). This is not suitable for committing, > due to probable races clearing the state. E.g., p_session can apparently > change before d_close() returns, so my closing_ctty flag may become > invalid, but since there is no explicit locking it's not clear that > other fatal changes can't happen. Hopefully everything is protected > by Giant until d_close() blocks, but the code after d_close() blocks > isn't very careful about the state. It needs to be, because d_open() > can be called successfully while d_close() is blocked! Note that > d_close() can block for arbitrarily long waiting for output to drain, > and it is useful for d_open() to succeed while d_close() is busy, > if only to unblock the close by changing the drain wait time. > I will try this patch tomorrow and see if it works. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010703184417.A69095>