Q's on: System V /etc/init....

Greg Noel greg at ncr-sd.UUCP
Sun Nov 17 21:38:11 AEST 1985


>>> This is a reply to two long articles.  Even though I've tried <<<
>>> to cut it back to the minimum, it's still quite long (about   <<<
>>> 175 lines).  If you are adverse to long articles, stop now.   <<<

One of the more interesting innovations to recent Unix has been the
new scheme by which /etc/init brings up terminals.  (I first saw it
in System V and I don't know if it was in System III, so pardon me
if I term it a "System V" enhancement.)  It is interesting because
could have been so very useful had it been fully implemented.

What has happened is that /etc/init has become a superdaemon, capable
of keeping track of other processes (not just login processes), starting
and stopping them based upon a control file and a settable run level.
Mats Wichmann (below) identifies some flaws and Guy Harris tries to
offer some help (but may have missed the point), but I think the real
flaw was that the \only/ product in System V that can be run under
/etc/init is getty.  There are at least three other standard products
that could have been trivially modified to run under the superdaemon
(cron, lpsched, and errdemon); this would have made them more visible,
more controllable, and more useful, and it would have provided a model
for other daemons to follow.  And it would have made the system easier
to control and manage.

Instead these daemons are hidden in /etc/rc, they exert magic (that can't
be circumvented) to put themselves in the background, and stopping and
restarting them is essentially a black art.  I have requested that AT&T
fix this, but the last I heard, they weren't planning to.

Sigh.  I'll get off my soapbox and try to be useful now.  I'm sorry to have
foamed at the mouth so, but it really bugs me that an idea as good as this
has been essentially crippled by incomplete implementation.

In article <5749 at fortune.UUCP> mats at fortune.UUCP (Mats Wichmann) writes:
> ..... Basically, the 
> secnario I would like is the following (which I think is reasonable):

> 1. Bring system directly up to multi-user without operator
>    intervention.

Yeah, I agree.  All of that operator intervention is unnecessary.  If
you are blessed with a battery-backup clock on your machine so that the
date is usually set correctly, \none/ of it is necessary.  If your
system reboots on power failures and there is no operator in attendance,
it is \very/ irritating to have to drive all the way in to work to tell
it that I don't want to set the silly date.  I ended up taking that out;
I'd rather have the system up with the incorrect time than be awakened
at 3am and have to go hit a carriage return.

And you \always/ want filesystem checks when the system goes down; only
in a development environment where you are rebooting frequently can I
imagine any other choice, and in that environment something special can
be done.  My particular wrinkle was that if the file /down was present,
it was assumed that the system was taken down cleanly and the filesystem
checks were skipped.  (The standard shutdown procedure set this file; it
encouraged its use -- and people quickly learned that taking the extra
minute to shut the system down cleanly saved ten minutes when rebooting.)
And if a file /.AskCheck was present, the operator would be asked for a
decision.  (This was for the times when you were testing something that
crashed the system; it was assumed you knew what you were doing and would
remove the file before normal use.)  Otherwise, the filesystems were
always checked; it was simply a part of the reboot process.

> 2. Be able to terminate the boot->multi-user sequence in some
>    way, leaving the system in single-user mode (like, if the
>    system was damaged so that it can't come up multi-user,
>    it would be nice to be able to perform repairs...).

Absolutely.  First, I will describe a technique that \usually/ works;
then I will froth at the mouth a little more about how it \should/ have
been done.

Some background:  I use init level 2 for normal multiprogramming and
init level 1 for "single user" mode (it's actually multiprogramming
but the only terminals enabled are those within shouting distance of
the computer itself).  (I also use init level 0 to shut the system
down; it runs a locally-modified /etc/shutdown script.)  Normally,
the system tries to come up at level 2, but if one of the /etc/*rc
scripts detects a failure, it executes "/etc/init 1; exec sleep 90"
which, assuming it isn't a full moon, bring the system up at level 1.
(When the moon is full, it will wedge the system.  Also, when the
moon is new, this has no effect.  But it's better than nothing.)  The
system can then be repaired as necessary.  Unfortunately, it is usually
necessary to reboot the system again as it is not generally possible
to restart the initialization sequence.

What should happen?  Simple.  It's not commonly known that initdefault
can contain more than one value; init just selects the highest run level
as the one to execute.  If an initwait entry fails (returns non-zero),
init should just select the \lowest/ initdefault level instead.  This
would go a long way toward making this whole thing easier to use.  Are
you listening AT&T?

> 3. Be able to take the machine down to single-user to perform
>    backups and such, and then come back up to multi-user.

> 4. Be able to toggle between levels in multi-user mode to
>    allow different default conditions (I use init mode 2
>    to enable a login on a dialin line, and init mode 3 to 
>    turn it off so I can use it as a dialout) without the multi-
>    user initialization sequence being executed each time.

I think both of these are really the same complaint, and that is that
it is difficult for /etc/rc to determine which daemons need to be
started or stopped for the new run level.  But this is \exactly/ what
/etc/init does already.  If it were only possible to run the daemons
by specifying them in /etc/inittab, /etc/init could start and stop
them for you.  In fact, I am fortunate to have sources so this is just
what I have done.  The only change to the source is to find the line
that says approximately "if (fork()) exit(0);" and comment it out.
You can't really avoid running /etc/rc when changing levels, but now
the job that it has to do is managable.

> 5. Be able to insure that the hardware console port is in fact
>    the virtual system console, even if I shut down from another
>    terminal (consider the case when the console hangs but
>    you still want to do a clean shutdown...)

I have reported this bug to AT&T, but I'm told that it is still being
released.  It's actually very strange, because the manual entries very
carefully explain what \not/ to put in a inittab entry.  The actual
command in the file has an "exec" prepended to it and the whole thing
is passed to the shell.  This means that exactly one command can be
executed.  Now, you can just see someone thinking, "I need to execute
more than one command on this line, so how can I do it?  Why, of course,
I get the shell to run a subshell!  I just put the entire command string
in parenthesis!"  So /etc/init constructs "exec (rm .....)" and hands it
to a shell.  The shell throws up its hands in disgust, and the virtual
system console never gets relinked to the hardware console.  The solution
is to put the code sequence into one of the /etc/*rc files -- it's not
particularly critical which.  This one is \so/ flagrant that I didn't
believe it when I saw it -- I wondered if some joker put it in deliberatly
just so he could snicker every time he looked at a S5 port and found it
there, since he would know that the vendor's checkout process was so poor.
(Take a look in your /etc/inittab file -- does it have the line?)

In article <2968 at sun.uucp> guy at sun.uucp (Guy Harris) replys:
> .... ((( some commentary about fsck, not related to the actual problem
> of getting the /etc/rc script to interrupt and switch to single user)))....
>S5 isn't really set up to automatically go multi-user.  For one thing, it
>dutifully records in "/etc/utmp" the fact that it's running "/etc/brc"
>(which is what's normally run by a "bootwait" item) *BEFORE* it checks the
>file systems.  Whichever genius committed this act should be sentenced to
>... (((a punishment that I don't consider severe enough))).  ....
>We fixed this at CCI.  I added a "bootcheck" "inittab" item; this item is
>NOT recorded in /etc/utmp.  ....  (((More details about the overall flow
>of the scheme.))) ....

This is a good point.  I don't know if an extra entry is necessary, though.
If bootwait entries didn't write on /etc/utmp it would probably be enough.
My trick to provide a single-user mode is that the first entry in inittab
is a bootwait entry for getty with a timeout on it.  If you don't log in
on the console within 60 seconds, it times out and the rest of the boot
sequence is run.  If that fails, it tries to go into init level 1.  I am
reasonably happy with this; the safety net seems sufficient.

> .... (((Some more stuff about fsck, not relevant here.  A plug for
> Chris Torek's "preen" program, which I will second.  I'll never figure
> out why "fsck -p" wasn't like this all along...))) .....

>This calls into question the entire utility of this "syscon" and "systty"
>stuff.  First of all, "/dev/console" is still an official part of the
>system; how is this different from "/dev/systty" (or are they always just
>two names for the same device)?  .....

Because of the way I manage the system, I haven't had the problems with
the virtual console comming up in a funny mode, but I \have/ wondered
what the logic behind /dev/{console,syscon,systty} is.  And have you
ever tried to boot a system with no /dev/syscon?  Even if /dev/console
is there, if it can't find /dev/syscon, it just tries to print out an
error message (which gets lost because /dev/syscon isn't there) and
dies.  It's \hard/ to get it out of that state.....

Pardon the spelling; it's 3am and I just don't feel like editing this.
-- 
-- Greg Noel, NCR Rancho Bernardo    Greg at ncr-sd.UUCP or Greg at nosc.ARPA



More information about the Comp.unix mailing list