A command to execute (optional)
There is no command to execute in the preceding initdefault
example because a command doesn't make sense in the context of setting the
default runlevel. Look a little further down in inittab, until you see a
line like this:
l5:5:wait:/etc/rc.d/rc 5
This line triggers most of the system configuration and services through
the rc*.d and init.d directories. You can see that init is set
to execute a command called /etc/rc.d/rc 5 when in runlevel 5. The wait
action tells when and how init runs the command: run rc 5
once when entering runlevel 5, and then wait for this command to finish
before doing anything else.
There are several different actions in addition to initdefault
and wait, especially pertaining to power management, and the
inittab(5) manual page tells you all about them. The ones that you're most
likely to encounter are explained in the following sections.
respawn
The respawn action causes init to run the command that
follows, and if the command finishes executing, to run it again. You're
likely to see something similar to this line in your inittab file:
1:2345:respawn:/sbin/mingetty tty1
The getty programs provide login prompts. The preceding line
is for the first virtual console (/dev/tty1), the one you see when you press
ALT-F1 or CONTROL-ALT-F1. The respawn action brings the login
prompt back after you log out.
ctrlaltdel
The ctrlaltdel action controls what the system does when you
press CONTROL-ALT-DELETE on a virtual console. On most systems, this is some
sort of reboot command using the shutdown command.
sysinit
The sysinit action is the very first thing that init
should run when it starts up, before entering any runlevels.
How processes in runlevels start
You are now ready to learn how init starts the system services, just
before it lets you log in. Recall this inittab line from earlier:
l5:5:wait:/etc/rc.d/rc 5
This small line triggers many other programs. rc stands for run
commands, and you will hear people refer to the commands as scripts,
programs, or services. So, where are these commands, anyway?
For runlevel 5, in this example, the commands are probably either in
/etc/rc.d/rc5.d or /etc/rc5.d. Runlevel 1 uses rc1.d, runlevel 2 uses rc2.d,
and so on. You might find the following items in the rc5.d directory:
S10sysklogd S20ppp S99gpm
S12kerneld S25netstd_nfs S99httpd
S15netstd_init S30netstd_misc S99rmnologin
S18netbase S45pcmcia S99sshd
S20acct S89atd
S20logoutd S89cron
The rc 5 command starts programs in this runlevel directory
by running the following commands:
S10sysklogd start
S12kerneld start
S15netstd_init start
S18netbase start
...
S99sshd start
Notice the start argument in each command. The S
in a command name means that the command should run in start mode, and the
number (00 through 99) determines where in the sequence rc
starts the command.
The rc*.d commands are usually shell scripts that start programs in /sbin
or /usr/sbin. Normally, you can figure out what one of the commands actually
does by looking at the script with less or another pager
program.
You can start one of these services by hand. For example, if you want to
start the httpd Web server program manually, run S99httpd
start. Similarly, if you ever need to kill one of the services when
the machine is on, you can run the command in the rc*.d directory with the stop
argument (S99httpd stop, for instance).
Some rc*.d directories contain commands that start with K
(for "kill," or stop mode). In this case, rc runs the
command with the stop argument instead of start.
You are most likely to encounter K commands in runlevels that
shut the system down.
Adding and removing services
If you want to add, delete, or modify services in the rc*.d directories,
you need to take a closer look at the files inside. A long listing reveals a
structure like this:
lrwxrwxrwx . . . S10sysklogd -> ../init.d/sysklogd
lrwxrwxrwx . . . S12kerneld -> ../init.d/kerneld
lrwxrwxrwx . . . S15netstd_init -> ../init.d/netstd_init
lrwxrwxrwx . . . S18netbase -> ../init.d/netbase
...
The commands in an rc*.d directory are actually symbolic links to files
in an init.d directory, usually in /etc or /etc/rc.d. Linux distributions
contain these links so that they can use the same startup scripts for all
runlevels. This convention is by no means a requirement, but it often makes
organization a little easier.
To prevent one of the commands in the init.d directory from running in a
particular runlevel, you might think of removing the symbolic link in the
appropriate rc*.d directory. This does work, but if you make a mistake and
ever need to put the link back in place, you might have trouble remembering
the exact name of the link. Therefore, you shouldn't remove links in the rc*.d
directories, but rather, add an underscore (_) to the beginning of the link
name like this:
mv S99httpd _S99httpd
At boot time, rc ignores _S99httpd because it
doesn't start with S or K. Furthermore, the
original name is still obvious, and you have quick access to the command if
you're in a pinch and need to start it by hand.
To add a service, you must create a script like the others in the init.d
directory and then make a symbolic link in the correct rc*.d directory. The
easiest way to write a script is to examine the scripts already in init.d,
make a copy of one that you understand, and modify the copy.
When adding a service, make sure that you choose an appropriate place in
the boot sequence to start the service. If the service starts too soon, it
may not work, due to a dependency on some other service. For non-essential
services, most systems administrators prefer numbers in the 90s, after most
of the services that came with the system.
Linux distributions usually come with a command to enable and disable
services in the rc*.d directories. For example, in Debian, the command is update-rc.d,
and in Red Hat Linux, the command is chkconfig. Graphical user
interfaces are also available. Using these programs helps keep the startup
directories consistent and helps with upgrades.
HINT: One of the most common Linux installation problems is an
improperly configured XFree86 server that flicks on and off, making the
system unusable on console. To stop this behavior, boot into single-user
mode and alter your runlevel or runlevel services. Look for something
containing xdm, gdm, or kdm in your rc*.d directories,
or your /etc/inittab.
Controlling init
Occasionally, you need to give init a little kick to tell it
to switch runlevels, to re-read the inittab file, or just to shut down the
system. Because init is always the first process on a system, its process ID
is always 1.
You can control init with telinit. For example,
if you want to switch to runlevel 3, use this command:
telinit 3
When switching runlevels, init tries to kill off any
processes that aren't in the inittab file for the new runlevel. Therefore,
you should be careful about changing runlevels.
When you need to add or remove respawning jobs or make any other change
to the inittab file, you must tell init about the change and
cause it to re-read the file. Some people use kill -HUP 1 to
tell init to do this. This traditional method works on most
versions of Unix, as long as you type it correctly. However, you can also
run this telinit command:
telinit q
You can also use telinit s to switch to single-user mode.
Shutting down
init also controls how the system shuts down and reboots.
The proper way to shut down a Linux machine is to use the shutdown
command.
There are two basic ways to use shutdown. If you halt the system,
it shuts the machine down and keeps it down. To make the machine halt
immediately, use this command:
shutdown -h now
On most modern machines with reasonably recent versions of Linux, a halt
cuts the power to the machine. You can also reboot the machine. For a
reboot, use -r instead of -h.
The shutdown process takes several seconds. You should never reset or
power off a machine during this stage.
In the preceding example, now is the time to shut down. This
argument is mandatory, but there are many ways of specifying it. If you want
the machine to go down sometime in the future, one way is to use +n,
where n is the number of minutes shutdown should wait before doing
its work. For other options, look at the shutdown(8) manual page.
To make the system reboot in 10 minutes, run this command:
shutdown -r +10
On Linux, shutdown notifies anyone logged on that the
machine is going down, but it does little real work. If you specify a time
other than now, shutdown creates a file called
/etc/nologin. When this file is present, the system prohibits logins by
anyone except the superuser.
When system shutdown time finally arrives, shutdown tells init
to switch to runlevel 0 for a halt and runlevel 6 for a reboot. When init
enters runlevel 0 or 6, all of the following takes place, which you can
verify by looking at the scripts inside rc0.d and rc6.d:
init kills every process that it can (as it would when
switching to any other runlevel).