Subject: Re: PR 7170 -- init and /dev/console
To: NetBSD Kernel Technical Discussion List <tech-kern@NetBSD.ORG>
From: Bill Studenmund <wrstuden@zembu.com>
List: tech-kern
Date: 04/23/2001 14:45:16
On Mon, 23 Apr 2001, Greg A. Woods wrote:

> [ On Monday, April 23, 2001 at 08:45:17 (-0700), Bill Studenmund wrote: ]
> > Subject: Re: PR 7170 -- init and /dev/console
> 
> Yup.  Crafting a file descriptor for a device should be a lot easier
> though than crafting one for a file at a specific filename.  One need
> only call the device open function, fill out the vnode, and tidy up any
> references, no?

It's easier than that. We can re-arrange fhopen so that it does the file
handle processing to get a vnode, then does the file descriptor making
from the vnode. Split the latter into another routine. Then just have MD
code export a dev_t for the console device & call cdevvp() to make the
vnode. We then execute all the same code for this "open" as we do
normally.

> Given that the current virtual console driver will have already been
> initialised long before the new init-to-be process is forked, and given
> that from within the kernel we know what major,minor number it'll be at,
> calling its open function while preparing the file descriptor entry for
> init is easy to arrange.  In fact one could probably even get away with
> just calling cnopen() directly, though we'd still want to fill out the
> vnode with the right major/minor numbers so jumping through cdevsw[] is
> probably still a good idea, no?

Yeah, we can do it very cleanly - we don't need to cut corners. :-)

> > The vnode code needs no changing.
> 
> I should hope not!  :-)  After all it "crafts" file descriptors for a
> living!  The only difference here is that we don't have/want to find the
> root filesystem character device file node by following its pathname.
> We already know its major/minor number and just need to "open" it.

Yep.

> > The presence of warn() does not mean that init has open file descriptors.
> > :-) It means that someone who wrote the code assumed it did.
> 
> my point exactly!  ;-)
> 
> Two of those errors can only (well maybe that's a bit strong) be
> triggered if someone tries to call /sbin/init from user-land, but the
> third I think is possible if things get really scrambled.
> 

> Also someone else mentioned a scheme, apparently used by Linux, where
> init will try to open /dev/console and only fall back to using the file
> descriptors the kernel hands to it if that fails.  I think that would be
> flat-out wrong.  Init's idea of the physical system console should
> *always* match exactly that held by the kernel and the only way to
> ensure that is to always use only the stdio descriptors handed to it by
> the kernel.  Once we have a proper way to hand init its proper stdio
> file descriptiors it should be impossible to either accidentally or
> purposefully re-direct its idea of where the real console is.  If such a
> mechanism is desirable then we need a second pseudo-console analagous to
> the /dev/syscon in AT&T Unix.

The problem with wanting to use file descriptors is that one of the first
things init does when setting up the console is to fire off a
revoke(). This operation is needed in the case of dropping (back) down to
single-user mode - we don't want any processes which might have opened the
console to still be able to get at it. Unfortunatly this action will blow
away the file descriptors the kernel opened for us (well, will make them
useless).

> In AT&T Unix (I'll give the names for SysVr4.2 -- they were different in
> older releases) the physical console is /dev/systty (this is can still a
> redirect device like BSD's /dev/console) if the underlying system can
> support multiple console locations that will be probed by the kernel).
> Normally /dev/syscon is a link to /dev/systty.  However if the user
> requests a switch to single user mode (via "telinit s") then /dev/syscon
> is made to be a link to the terminal on which that command was "sent
> from".  Init generally works with /dev/syscon (eg. when it starts a
> single-user shell).  It'll fall back to using the default system console
> (aka what /dev/systty points to), if opening /dev/syscon fails (and
> it'll also try relinking /dev/syscon to /dev/systty too).  Note also
> that if /dev/syscon is not linked to /dev/ssytty when init prompts for a
> new run level (eg. at boot) then generating an interrupt character on
> the physical console will also re-direct init back to using the physical
> console.  (The only trick being knowing when to type the interrupt
> character.  Had I had source at the time I would have modified it to
> also print a warning about this event on the physical console.)  SysV
> init also does a few additional things to keep track of the proper stty
> settings to use for /dev/ssycon in case it's a modem line or some such.
> 
> This scheme makes it possible to safely reboot the system from any
> terminal and still be able to enter single user mode from that
> terminal and to see all the /etc/rc* messages on that terminal
> (obviously you won't see kernel messages there, but that's not the end
> of the world).

This type of setup would be interesting, but is a different subject from
this one. :-)

Take care,

Bill