Subject: Re: PR 7170 -- init and /dev/console
To: NetBSD Kernel Technical Discussion List <tech-kern@NetBSD.ORG>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 04/23/2001 17:54:25
[ On Monday, April 23, 2001 at 08:45:17 (-0700), Bill Studenmund wrote: ]
> Subject: Re: PR 7170 -- init and /dev/console

I'll combine two of Bill's messages here....

> On Sat, 21 Apr 2001, Greg A. Woods wrote:
> 
> > I don't think hand crafting a descriptor should be all that much work
> > either (though I've not actually tried implementing it, yet :-).
> > There's already some crafting of file descriptors for process zero.
> 
> That code just sets up a clean, empty set of file descriptors.

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?

Certainly trying to find "/dev/console" in the file system is exactly
the wrong thing to do in this case since the lack of such a pathname is
exactly one of the main reasons to connect the init-to-be process to the
real console before exec'ing its binary.....

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?

> 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.

> 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.

> AFAICT, init starts with no open file descriptors.

AFAICT, that's right.....


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.

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).

[[ I'm not sure whether or not the kernel hands init its file
descriptors on SysV, or not, though obviously it is able to send it
signals generated from there.... ]]

Since the BSD init state machine is significantly simpler the handling
of a virtual system console could be somewhat simplified (there's never
any need for init to prompt for a run level).  However it would probably
still be wise to duplicate some status messages to the physical console
and to accept an interrupt on the system console as a way to interrupt
the boot (at which point init would start a single user shell on the
physical system console, perhaps after asking for a password if the ttys
file doesn't list /dev/console as secure).

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods@acm.org>     <woods@robohack.ca>
Planix, Inc. <woods@planix.com>;   Secrets of the Weird <woods@weird.com>