Re: revocation of /dev/console at the end of rc sequence

From: Andriy Gapon <avg_at_freebsd.org>
Date: Wed, 26 Mar 2025 18:58:27 UTC
On 26/03/2025 6:54 pm, Warner Losh wrote:
> 
> 
> On Wed, Mar 26, 2025 at 10:23 AM Andriy Gapon <avg@freebsd.org 
> <mailto:avg@freebsd.org>> wrote:
> 
> 
>     Not sure what would be the best forum to talk about this issue, so posting here.
> 
>     I observe a kind of unexpected problem related to /dev/console.
>     Here is my understanding of what is happening.
> 
>     Thanks to DTrace I was able to capture /dev/console getting "revoked", its
>     vnode
>     getting recycled (at least, destroyed):
> 
>         1  15949                     vgonel:entry
>     2025 Mar 25 21:45:33 vgone vnode fffff8000607b540, console rdev by sh (21)
> 
>                     kernel`vgone+0x2f
>                     kernel`devfs_revoke+0x41
>                     kernel`VOP_REVOKE_APV+0x71
>                     kernel`killjobc+0x15a
>                     kernel`exit1+0x707
>                     kernel`0xffffffff808bd00d
>                     kernel`amd64_syscall+0x189
>                     kernel`0xffffffff80c4fbfb
> 
>     My understanding is that this is the rc shell process exiting.
> 
>     init forks a process that exec-s bin/sh (or alternative init shell) to run
>     /etc/rc (or alternative init script).
>     The process sets up itself as a session leader and /dev/console as its
>     controlling terminal (as well as stdin, stdout and stderr).
>     It does that by calling login_tty() which internally uses setsid() and
>     tcsetsid() to do the job.
>     See runcom -> run_script -> execute_script -> open_console in sbin/init/init.c.
> 
>     I guess that this makes total sense given the nature of /etc/rc.
> 
>     When a session leader process exits, it revokes its controlling terminal.
>     That's the standard behavior.
>     I guess that the idea is that any descendant processes in the session get
>     disassociated from the terminal.
> 
>     Both things make sense, but they lead to a problem as well.
>     The problem is that by the time /etc/rc finishes there can be a daemon (so, not
>     a member of the session) that opened /dev/console for its own needs.
>     The daemon would then lose its /dev/console access which it may not expect.
> 
>     One such daemon is console-kit-daemon.
>     Here is how /dev/console descriptor looks afterwards (as reported by
>     procstat -f):
>         PID COMM                FD T V FLAGS    REF  OFFSET PRO NAME
>        3323 console-kit-daemon    10 v x r-------  10       0 -   -
> 
>     More details here: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285394
>     <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285394>
>     (Note that some earlier comments have incorrect information and assumptions).
> 
>     Can we do something better here given the special nature of /dev/console?
>     May something in FreeSBD?
> 
>     For console-kit-daemon I have an idea of using /dev/ttyv0 instead of
>     /dev/console.  The daemon needs the device for things like observing VT
>     switching and similar operations
> 
> 
> So what is it using /dev/console for? I think the answer to this question will help
> understand the right solution. What does console-kit think it can do with /dev/ 
> console?

I guess I should have expanded on "things like observing VT switching and 
similar operations".
So, console-kit issues ioctl-s like VT_WAITACTIVE, VT_ACTIVATE and similar.

I also would like to mention that those ioctl-s are not documented in the manual 
pages.  Perhaps, screen(4) would have been a good place for that.

I guess I could say that console-kit needs a control device for video console.
It presently uses /dev/console for that role and it works but it may not be the 
best choice.

I do not think that we have an explicitly designed control device for video 
consoles.  From the code I get an impression that any video console terminal 
(ttyvX) should be suitable for that role.  E.g., vidcontrol just uses whatever 
device happens to be its stdin.
But maybe that's not so.

> /dev/console, even if we didn't do the revoke, seems like the wrong thing for it
> to be opening.
> 
> Seems like
>       TIOCCONS int *on
>                   If on points to a non-zero integer, redirect kernel console
>                   output (kernel printf's) to this terminal.  If on points to a
>                   zero integer, redirect kernel console output back to the
>                   normal console.  This is usually used on workstations to
>                   redirect kernel messages to a particular window.
> is what it should be doing.
> Is the standard way to redirect / scrape the console.

I guess that this not useful at all for console-kit.

> Also, ttyv0 is always wrong to hard-code. It might have nothing at all
> to do with the console.

Given what console-kit actually does, it might not be so wrong.
But I am not sure.

> There's a couple of different notions of "the console" today, and they
> are a bit poorly defined. There's the "console" for the kernel. And it's really
> a collection of devices that get kernel output and are prompted for kernel
> input.
> 
> There's the "console" used for /etc/rc. This is /dev/console. It's just an
> alias for the first tty device in the kernel console list (sometimes called the
> primary console). there's little special beyond that, though Kyle and I
> keep threatening to make it a mux of all the kernel consoles on that list.
> It's functionality is somewhat limited (and has been since phk separated
> it out from the tty that underlies it around FreeBSD 2 or 3).
> 
> So what is it that console-kit-daemon is wanting to do?

So, just for the sake of quoting, console-kit-daemon needs a control device for 
video console (video terminals).

-- 
Andriy Gapon