Rute User's Tutorial and Exposition. 32. init, getty, and UNIX Run Levels
Next: 33. Sending Faxes
Up: rute
Previous: 31. lilo, initrd, and
  Contents
Subsections
This chapter explains how LINUX (and a UNIX system in general)
initializes itself. It follows on from the
kernel boot explained in
Section 31.2. We also go into some advanced
uses for
mgetty, like receiving of
faxes.
After the kernel has been unpacked into memory, it begins to execute,
initializing hardware. The last thing it does is mount the root file system,
which necessarily contains a program
/sbin/init, which the kernel
executes.
init is one of the only programs the kernel ever executes
explicitly; the onus is then on
init to bring the UNIX system up.
init always has the process ID
1.
For the purposes of
init, the (rather arbitrary) concept of a UNIX
run level was invented. The run level is the current operation of the
machine, numbered run level
0 through run level
9. When the
UNIX system is at a particular run level, it means that a certain
selection of services is running. In this way, the machine could be a
mail server or an X Window workstation depending on what run level it is
in.
The traditionally defined run levels are:
|
0 |
Halt. |
|
1 |
Single-user mode. |
|
2 |
Multiuser, without network file system (NFS). |
|
3 |
Full multiuser mode. |
|
4 |
Unused. |
|
5 |
X Window System Workstation (usually identical to run level
3). |
|
6 |
Reboot. |
|
7 |
Undefined. |
|
8 |
Undefined. |
|
9 |
Undefined. |
The idea here is that
init begins at a particular run level
that can then be manually changed to any other by the superuser.
init uses
a list of scripts for each run level to start or stop each of
the many services pertaining to that run level. These scripts
are
/etc/rc?
.d/KNNservice
or
/etc/rc?
.d/SNNservice [On some
systems
/etc/rc.d/rc?
.d/... .], where
NN,
K, or
S is a prefix to force the order of
execution (since the files are executed in alphabetical order).
These scripts all take the options
start and
stop on the
command-line, to begin or terminate the service.
For example, when
init enters, say, run level
5 from
run level
3, it executes the particular scripts from
/etc/rc3.d/
and
/etc/rc5.d/ to bring up or down the appropriate services. This may
involve, say, executing
and similar commands.
init has one config file:
/etc/inittab which is
scanned once on bootup.
A minimal
inittab file might consist of the
following.
5
10
15
20
|
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
ud::once:/sbin/update
1:2345:respawn:/sbin/getty 38400 tty1
2:2345:respawn:/sbin/getty 38400 tty2
3:2345:respawn:/sbin/getty 38400 tty3
4:2345:respawn:/sbin/getty 38400 tty4
S0:2345:respawn:/sbin/mgetty -n 3 -s 115200 ttyS0 57600
S4:2345:respawn:/sbin/mgetty -r -s 19200 ttyS4 DT19200
x:5:respawn:/usr/bin/X11/xdm -nodaemon
|
The lines are colon-separated fields and have the following meaning
(lots more can be gotten from
inittab(5)):
-
id:3:initdefault:
- This dictates that the default
run level is
3. It is the run level that the system will
boot up into. This field usually has a
3 or a
5,
which are most often the only two run levels that the system ever
sits in.
-
si::sysinit:/etc/rc.d/rc.sysinit
- This says to run
a script on bootup to initialize the system. If you view the file
/etc/rc.d/rc.sysinit, you will
see a fairly long script that does the following: mounts the proc file system; initializes
the keyboard maps, console font, NIS domain, host name, and swap partition;
runs
isapnp and
depmod -a;
cleans the
utmp file;
as well as other things. This script is only run once on bootup.
On Debian this is a script,
/etc/init.d/rcS, that runs
everything under
/etc/rcS.d/. [As usual, Debian gravitated
to the most clean, elegant and extensible solution.]
-
l3:3:wait:/etc/rc.d/rc 3
- The first field is a descriptive tag and could be anything.
The second is a list of run levels under which the particular script (last field) is
to be invoked: in this case,
/etc/rc.d/rc 3 is to be run when
entering run level
3. The
wait means to pause until
/etc/rc.d/rc has finished execution. If you view the file
/etc/rc.d/rc, you will see it merely executes scripts
under
/etc/rc?
.d/ as appropriate for a run level
change.
-
ud::once:/sbin/update
- This flushes the disk cache on each run level
change.
-
1:2345:respawn:/sbin/getty 38400 tty1
- This says to
run the command
/sbin/getty 38400 tty1 when in run level
2
through
5.
respawn means to restart the process if it dies.
-
x:5:respawn:/usr/bin/X11/xdm -nodaemon
- This says to
run the command
/usr/bin/X11/xdm -nodaemon when in run level
5.
This is the X Window System graphical login program.
If you modify the
inittab file,
init
will probably not notice until you issue it a
SIGHUP.
This is the same as typing
which causes
init to reread
/etc/inittab.
You get a
respawning too fast error when an
inittab line makes no sense [These errors
are common and very irritating when you are doing console work,
hence an explicit section on it.]:
like a
getty running on a non-functioning serial port.
Simply comment out or delete the appropriate line and then run
Switching run levels manually is something that is rarely done.
The most common way of shutting down the machine is to use:
which effectively goes to run level
0, and
which effectively goes to run level
6.
You can also specify the run level at the
LILO:
prompt. Type
or
to enter single-user mode when booting your machine. You
change to single-user mode on a running system with:
You can forcefully enter any run level with
The
getty man page begins with:
getty opens a tty port, prompts for a login name and
invokes the /bin/login command. It is normally invoked by
init(8).
Note that
getty,
agetty,
fgetty and
mingetty are
just different implementations of
getty.
The most noticeable effect of
init running at all is that it
spawns a login to each of the LINUX virtual consoles. It is the
getty (or sometimes
mingetty) command as
specified in the
inittab line above that displays this login. Once the
login name is entered,
getty invokes the
/bin/login program,
which then prompts the user for a password.
The
login program (discussed in Section 11.7)
then executes a shell. When the shell dies (as a result of the user
exiting the session)
getty is just
respawned.
Together with Chapter 31 you should now have a
complete picture of the entire bootup process:
- 1.
- First sector loaded into RAM and executed--
LILO: prompt appears.
- 2.
- Kernel loaded from sector list.
- 3.
- Kernel executed; unpacks.
- 4.
- Kernel initializes hardware.
- 5.
- Kernel mounts root file system, say
/dev/hda1.
- 6.
- Kernel executes
/sbin/init as PID
1.
- 7.
-
init executes all scripts for default run level.
- 8.
-
init spawns
getty programs on each terminal.
- 9.
-
getty prompts for login.
- 10.
-
getty executes
/bin/login to
authentic user.
- 11.
-
login starts shell.
The original purpose of
getty was to manage
character terminals on
mainframe computers.
mgetty is a more comprehensive
getty
that deals with proper serial devices. A typical
inittab entry is
|
S4:2345:respawn:/sbin/mgetty -r -s 19200 ttyS4 DT19200
|
which would open a login on a
terminal connected to a serial
line on
/dev/ttyS4. See page
for information on configuring
multiport serial cards.
(The LINUX devices
/dev/tty1
through
/dev/tty12 as used
by
getty emulate classic terminals in this way.)
mgetty will log to
/var/log/mgetty.log.ttyS?. This log
file contains everything you need for troubleshooting. It is worthwhile running
tail -f on these files while watching a login take place.
Running
mgetty (see
mgetty(8)) is a common and
trivial way to get a dial login to a LINUX machine. Your
inittab entry is just
|
S0:2345:respawn:/sbin/mgetty -n 3 -s 115200 ttyS0 57600
|
where
-n 3 says to answer the phone after the
3rd ring. Nothing more is needed than to plug your
modem into a telephone. You can then use
dip -t, as done
in Section 41.1.1, to dial this machine from another
LINUX machine. Here is an example session: [This example
assumes that an initialization string
of
AT&F1 is
sufficient. See Section 3.5.]
5
10
15
|
[root@cericon]# dip -t
DIP: Dialup IP Protocol Driver version 3.3.7o-uri (8 Feb 96)
Written by Fred N. van Kempen, MicroWalt Corporation.
DIP> port ttyS0
DIP> speed 57600
DIP> term
[ Entering TERMINAL mode. Use CTRL-] to get back ]
AT&F1
OK
ATDT5952521
CONNECT 19200/ARQ/V34/LAPM/V42BIS
Red Hat Linux release 6.1 (Cartman)
Kernel 2.2.12-20 on an i686
remote.dialup.private login:
|
Note that this is purely a login session having nothing
to do with PPP dialup.
mgetty receives faxes by default, provided your modem supports
faxing [If your modem says it supports faxing, and this still does not work,
you will have to spend a lot of time reading through your modem's
AT
command set manual, as well as the
mgetty
info documentation.]and provided it has not been explicitly disabled with the
-D option.
An appropriate
inittab line is,
|
S0:2345:respawn:/sbin/mgetty -x 4 -n 3 -s 57600 -I '27 21 7654321' ttyS0 57600
|
The options mean, respectively, to set the debug level to
4,
answer after
3 rings, set the port speed to
57600,
and set the fax ID number to
27 21 7654321. Alternatively,
you can use the line
|
S0:2345:respawn:/sbin/mgetty ttyS0 57600
|
and instead put your configuration options in the file
mgetty.config
under
/etc/mgetty+sendfax/:
|
debug 4
rings 3
speed 57600
fax-id 27 21 7654321
|
Faxes end up in
/var/spool/fax/incoming/ as
useless
.g3 format files, but note how the command
|
strings /sbin/mgetty | grep new_fax
|
gives
|
/etc/mgetty+sendfax/new_fax
|
which is a script that
mgetty secretly runs when new
faxes arrive. It can be used to convert faxes into something (like
.gif graphics files [I recommend
.png over
.gif any day, however.]) readable
by typical office programs. The following example
/etc/mgetty+sendfax/new_fax script puts incoming
faxes into
/home/fax/ as
.gif files
that all users can
access. [Modified from the
mgetty contribs.] Note
how it uses the CPU-intensive
convert program from the
ImageMagic
package.
5
10
15
20
25
30
|
#!/bin/sh
# you must have pbm tools and they must be in your PATH
PATH=/usr/bin:/bin:/usr/X11R6/bin:/usr/local/bin
HUP="$1"
SENDER="$2"
PAGES="$3"
shift 3
P=1
while [ $P -le $PAGES ] ; do
FAX=$1
BASENAME=`basename $FAX`
RES=`echo $BASENAME | sed 's/.\(.\).*/\1/'`
if [ "$RES" = "n" ] ; then
STRETCH="-s"
else
STRETCH=""
fi
nice g32pbm $STRETCH $FAX > /tmp/$BASENAME.pbm \
&& rm -f $FAX \
&& nice convert -colorspace gray -colors 16 -geom \
'50%x50%' /tmp/$BASENAME.pbm /home/fax/$BASENAME.gif \
&& rm -f /tmp/$BASENAME.pbm \
&& chmod 0666 /home/fax/$BASENAME.gif
shift
P=`expr $P + 1`
done
exit 0
|
Next: 33. Sending Faxes
Up: rute
Previous: 31. lilo, initrd, and
  Contents
|