init
Uuno on numero yksi
(Slogan for a series of Finnish movies.)
This chapter describes the init process,
which is the first user level process started by the kernel.
init has many important duties, such as
starting getty (so that users can log in),
implementing run levels, and taking care of orphaned processes.
This chapter explains how init is configured
and how you can make use of the different run levels.
init comes first
init is one of those programs that
are absolutely essential to the operation of a Linux system,
but that you still can mostly ignore. A good Linux distribution
will come with a configuration for init
that will work for most systems, and on these systems there is
nothing you need to do about init. Usually,
you only need to worry about init if you hook
up serial terminals, dial-in (not dial-out) modems, or if you
want to change the default run level.
When the kernel has started itself (has been loaded
into memory, has started running, and has initialized all
device drivers and data structures and such), it finishes its
own part of the boot process by starting a user level program,
init. Thus, init is always
the first process (its process number is always 1).
The kernel looks for init
in a few locations that have been historically used
for it, but the proper location for it (on a Linux
system) is /sbin/init. If the
kernel can't find init, it tries to run
/bin/sh, and if that also fails, the startup
of the system fails.
When init starts, it finishes the
boot process by doing a number of administrative tasks, such
as checking filesystems, cleaning up /tmp,
starting various services, and starting a getty
for each terminal and virtual console where users should be able
to log in (see ).
After the system is properly up, init
restarts getty for each terminal
after a user has logged out (so that the next user can log
in). init also adopts orphan processes: when
a process starts a child process and dies before its child, the
child immediately becomes a child of init.
This is important for various technical reasons, but it is good
to know it, since it makes it easier to understand process lists
and process tree graphs.
There are a few variants of init
available. Most Linux distributions
use sysvinit (written by Miquel
van Smoorenburg), which is based on the System V
init design. The BSD versions of Unix have
a different init. The primary difference
is run levels: System V has them, BSD does not (at least
traditionally). This difference is not essential. We'll look
at sysvinit only.
Configuring init to start
getty: the
/etc/inittab file
When it starts up, init reads the
/etc/inittab
configuration file. While the system is running, it will
re-read it, if sent the HUP signal (kill -HUP 1);
this feature makes it unnecessary to boot the system to make
changes to the init configuration take
effect.
The /etc/inittab file is
a bit complicated. We'll start with the simple case
of configuring getty lines. Lines in
/etc/inittab consist of four colon-delimited
fields:
id:runlevels:action:process
The fields are described below. In addition,
/etc/inittab can contain empty lines, and
lines that begin with a number sign (`#');
these are both ignored.
id
This identifies the line in the file. For
getty lines, it specifies the terminal
it runs on (the characters after /dev/tty
in the device file name). For other lines,
it doesn't matter (except for length restrictions),
but it should be unique.
runlevels
The run levels the line should be considered
for. The run levels are given as single digits,
without delimiters. (Run levels are described
in the next section.)
action
What action should be taken by the line, e.g.,
respawn to run the command in the
next field again, when it exits, or once
to run it just once.
process
The command to run.
To start a getty on the first virtual terminal
(/dev/tty1), in all the normal multi-user
run levels (2-5), one would write the following line:
1:2345:respawn:/sbin/getty 9600 tty1
The first field says that this is the line for
/dev/tty1.
The second field says that it applies to run levels 2, 3, 4,
and 5. The third field means that the command should be run
again, after it exits (so that one can log in, log out, and
then log in again). The last field is the command that runs
getty on the first virtual terminal.
Different versions of getty are run
differently. Consult your manual page, and make sure it is
the correct manual page.
If you wanted to add terminals or dial-in modem lines to a
system, you'd add more lines to /etc/inittab,
one for each terminal or dial-in line. For more details, see the
manual pages init, inittab,
and getty.
If a command fails when it starts,
and init is configured to
restart it, it will use a lot of
system resources: init starts it,
it fails, init starts it, it fails,
init starts it, it fails, and so on, ad
infinitum. To prevent this, init will keep
track of how often it restarts a command, and if the frequency
grows to high, it will delay for five minutes before restarting
again.
Run levels
A run level is a state of
init and the whole system that defines what
system services are operating. Run levels are identified by
numbers. Some system administrators
use run levels to define which subsystems are working, e.g.,
whether X is running, whether the network is operational, and
so on. Others have all subsystems always running or start and
stop them individually, without changing run levels, since run
levels are too coarse for controlling their systems. You need
to decide for yourself, but it might be easiest to follow the
way your Linux distribution does things.
The following table defines how most Linux Distributions
define the different run levels. However, run-levels 2 through 5
can be modified to suit your own tastes.
Run level numbers
0 Halt the system.
1 Single-user mode (for special
administration).
2 Local Multiuser with Networking
but without network service (like NFS)
3 Full Multiuser with Networking
4 Not Used
5 Full Multiuser with Networking
and X Windows(GUI)
6 Reboot.
Services that get started at a certain runtime are determined
by the contents of the various rcN.d directories.
Most distributions locate these directories either at
/etc/init.d/rcN.d or
/etc/rcN.d. (Replace the N with the run-level
number.)
In each run-level you will find a series of if links pointing
to start-up scripts located in /etc/init.d.
The names of these links all start as either K or S, followed by a
number. If the name of the link starts with an S, then that indicates
the service will be started when you go into that run level. If the
name of the link starts with a K, the service will be killed (if
running).
The number following the K or S indicates the order the scripts
will be run. Here is a sample of what an
/etc/init.d/rc3.d may look like.
# ls -l /etc/init.d/rc3.d
lrwxrwxrwx 1 root root 10 2004-11-29 22:09 K12nfsboot -> ../nfsboot
lrwxrwxrwx 1 root root 6 2005-03-29 13:42 K15xdm -> ../xdm
lrwxrwxrwx 1 root root 9 2004-11-29 22:08 S01pcmcia -> ../pcmcia
lrwxrwxrwx 1 root root 9 2004-11-29 22:06 S01random -> ../random
lrwxrwxrwx 1 root root 11 2005-03-01 11:56 S02firewall -> ../firewall
lrwxrwxrwx 1 root root 10 2004-11-29 22:34 S05network -> ../network
lrwxrwxrwx 1 root root 9 2004-11-29 22:07 S06syslog -> ../syslog
lrwxrwxrwx 1 root root 10 2004-11-29 22:09 S08portmap -> ../portmap
lrwxrwxrwx 1 root root 9 2004-11-29 22:07 S08resmgr -> ../resmgr
lrwxrwxrwx 1 root root 6 2004-11-29 22:09 S10nfs -> ../nfs
lrwxrwxrwx 1 root root 12 2004-11-29 22:40 S12alsasound -> ../alsasound
lrwxrwxrwx 1 root root 8 2004-11-29 22:09 S12fbset -> ../fbset
lrwxrwxrwx 1 root root 7 2004-11-29 22:10 S12sshd -> ../sshd
lrwxrwxrwx 1 root root 8 2005-02-01 09:24 S12xntpd -> ../xntpd
lrwxrwxrwx 1 root root 7 2004-12-02 20:34 S13cups -> ../cups
lrwxrwxrwx 1 root root 6 2004-11-29 22:09 S13kbd -> ../kbd
lrwxrwxrwx 1 root root 13 2004-11-29 22:10 S13powersaved -> ../powersaved
lrwxrwxrwx 1 root root 9 2004-11-29 22:09 S14hwscan -> ../hwscan
lrwxrwxrwx 1 root root 7 2004-11-29 22:10 S14nscd -> ../nscd
lrwxrwxrwx 1 root root 10 2004-11-29 22:10 S14postfix -> ../postfix
lrwxrwxrwx 1 root root 6 2005-02-04 13:27 S14smb -> ../smb
lrwxrwxrwx 1 root root 7 2004-11-29 22:10 S15cron -> ../cron
lrwxrwxrwx 1 root root 8 2004-12-22 20:35 S15smbfs -> ../smbfs
How run levels start are configured in
/etc/inittab by lines like the following:
l2:2:wait:/etc/init.d/rc 2
The first field is an arbitrary label, the second one means
that this applies for run level 2. The third field means
that init should run the command in the
fourth field once, when the run level is entered, and that
init should wait for it to complete. The
/etc/init.d/rc command runs whatever
commands are necessary to start and stop services to enter run
level 2.
The command in the fourth field does all the hard work of
setting up a run level. It starts services that aren't already
running, and stops services that shouldn't be running in the
new run level any more. Exactly what the command is, and how run
levels are configured, depends on the Linux distribution.
When init starts, it looks for a line
in /etc/inittab that specifies the default
run level:
id:2:initdefault:
You can ask init to go to a non-default run
level at startup by giving the kernel a command line argument
of single or emergency.
Kernel command line arguments can be given via LILO, for example.
This allows you to choose the single user mode (run level 1).
While the system is running, the telinit
command can change the run level. When the run level is
changed, init runs the relevant command from
/etc/inittab.
Special configuration in
/etc/inittab
The /etc/inittab has some special
features that allow init to react to special
circumstances. These special features are marked by special
keywords in the third field. Some examples:
powerwait
Allows init to shut the system
down, when the power fails. This assumes the use of
a UPS, and software that watches the UPS and informs
init that the power is off.
ctrlaltdel
Allows init to reboot the system, when
the user presses ctrl-alt-del on the console keyboard.
Note that the system administrator can configure the
reaction to ctrl-alt-del to be something else instead,
e.g., to be ignored, if the system is in a public
location. (Or to start nethack.)
sysinit
Command to be run when the system is booted. This command
usually cleans up /tmp, for example.
The list above is not exhaustive. See your
inittab manual page for all possibilities,
and for details on how to use the above ones.
Booting in single user mode
An important run level is single user
mode (run level 1),
in which only the system administrator is using the machine
and as few system services, including logins, as possible are
running. Single user mode is necessary for a few administrative
tasks, such as running fsck on a
/usr partition, since this requires that
the partition be unmounted, and that can't happen, unless just
about all system services are killed.
A running system can be taken to single user mode by using
telinit to request run level 1. At bootup,
it can be entered by giving the word single
or emergency on the kernel command line: the
kernel gives the command line to init as well,
and init understands from that word that it
shouldn't use the default run level. (The kernel command line is
entered in a way that depends on how you boot the system.)
Booting into single user mode is sometimes necessary so
that one can run fsck by hand, before anything
mounts or otherwise touches a broken /usr
partition (any activity on a broken filesystem is likely to
break it more, so fsck should be run as soon
as possible).
The bootup scripts init runs
will automatically enter single user mode, if the automatic
fsck at bootup fails. This is an attempt to
prevent the system from using a filesystem that is so broken that
fsck can't fix it automatically. Such breakage
is relatively rare, and usually involves a broken hard disk or an
experimental kernel release, but it's good to be prepared.
As a security measure, a properly configured system
will ask for the root password before starting the shell in
single user mode. Otherwise, it would be simple to just enter
a suitable line to LILO to get in as root. (This will break if
/etc/passwd has been broken by filesystem
problems, of course, and in that case you'd better have a boot
floppy handy.)