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

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Wed, 26 Mar 2025 16:22:34 UTC
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
(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.

-- 
Andriy Gapon