Run Levels
Most users are only familiar with two run
states or run levels. The one that is most commonly experienced is what is
referred to a multiuser mode. This is where logins are enabled on terminals when
the network
is running and the system is behaving "normally." The
other run level is system maintenance or single-user mode,
when only a single user is on the system (root), probably doing some kind of maintenance
tasks. Although it could be configured to allow logins by other users, usually the system is
so configured that only one login is allowed on the system console.
On every system that I have encountered, Linux will automatically
boot into run-level
3. This is the normal operating mode. To get to a lower run
level (for example, to do system maintenance), the system administrator
must switch levels manually.
It is generally said that the "system" is in a particular run-level.
However, it is more accurate to say that the init
process is in a particular run level, because init
determines what other processes are started at each run-level.
In addition to the run levels most of us are familiar with, there are several others that the system
can run in. Despite this fact, few of them are hardly ever used. For more details on
what these run levels are, take a look at the init
man-page.
The system
administrator can change to a particular run level by using that run level as
the argument
to init.
For example, running init 2 would change the system to
run-level 2. To determine what processes to start in each run level, init
reads
the /etc/inittab file. This is defined by the second field in the /etc/inittab
file. Init reads this file and executes each program defined for that run level
in order. When the system boots, it decides what run level to go into based on
the initdefault entry in /etc/inittab.
The fields in the inittab file are:
id | unique identity for that entry
| rstate | run level in which the entry will be processed
| action | tells init how to treat the process specifically
| process | what process will be started
|
One thing I need to point out is that the entries in inittab are
not run exactly according to the order in which they appear. If you are
entering a run level other than S for the first time since boot-up, init
will
first execute those entries with a boot
or bootwait in the third
column. These are those processes that should be started before users are
allowed access to the system, such as checking then mounting the status of the
file systems.
In run-level
3, the /sbin/mingetty process is started on the
terminals specified. The getty process gives you your login: prompt. When you
have entered your logname
for the first time, getty starts the login
process,
which asks you for your password. If your password is incorrect, you are
prompted to input your logname
again. If your password is correct, then the
system starts your "login shell.
" Note that what gets started may not
be a shell
at all, but some other program. The term "login shell" is
the generic term for whatever program is started when you login.
This is defined
by the last field of the corresponding entry in /etc/passwd.
Keep
in mind that you can move in either direction, that is, from a lower to higher
run level or from a higher to lower run level without having to first reboot.
init will read the inittab and start or stop the necessary processes. If a
particular process is not defined at a particular run level, then init
will kill
it. For example, assume you are in run-level
3 and switch to run-level 1. Many
of the processes defined do not have a 1 in the second field. Therefore, when
you switch to run-level
1, those processes and all their children will be
stopped.
If we look at the scripts in rc1.d, we see there all the scripts
are kill scripts, with the exception of one start script. It is this start
script that actually kills all the processes. It does exec init
-t1 S, which
brings the system into maintenance mode
in one (-t1) minute.
To shutdown the system immediately, you could run
which will bring the
system immediately into run-level
0. As with run-level 1, there is only one
start script for run-level
0. It is this script that kills all the processes,
unmounts all the file systems, turns off swap, and brings the system
down.
After it has started the necessary process from inittab, init
just
waits. When one of its "descendants" dies (a child process
of a child
process of a child process,
etc., of a process that init
started), init
rereads the inittab to see what should be done. If, for example,
there is a respawn entry in the third field, init
will start the specified
process again. This is why when you log out, you immediately get a new login:
prompt.
Because init
just waits for processes to die, you cannot simply
add an entry to inittab and expect the process to start up. You have to tell init
to reread the inittab. However, you can force init
to reread the
inittab by running init
(or telinit) Q.
In addition to the run levels we discussed here,
several more are possible. There are three "pseudo" run-levels a, b, and c. These are used to
start specific programs as needed or "on demand". Any listed in inittab with the approapriate run-level
will be started, however no actual run-level change occurs.
If you're curious about the details, take a look at the init(8) man-page
or the section on init-scripts.
Action | Meaning
| boot | Executed during system boot.
| bootwait | Executed during system boot, but init waits until they have completed.
| initdefault | The default run level init starts after the system boots.
| ondemand | Executed when one of the "on demand" run levels is called (a,b, and c)
| powerwait | Executed when the system power fails. Init will wait until the command completes.
| powerfail | Executed when the system power fails, but init will not wait for completion.
| powerokwait | Executed when init is informed that power has been restored.
| powerfailnow | Executed when init is informed that the external battery is empty.
| resume | Executed when init is told by the kernel that "Software Suspend"
| sysinit | Executed during system boot before any boot or bootwait entries.
| respawn | Restarted if the processes stops.
| wait | Started once when the specific run-level is entered and init waits for completion.
| once | Started once when the specific run-level is entered but init does not wait for completion.
| ctrlaltdel | Execute when someone on the system console presses CTRL-ALT-DEL.
|
Table - List of inittab actions.
If necessary, you can add your own entries into /etc/inittab. However, what is typically done is
that init-scripts are added to the appropriate directory for the run-level where you want to
start it. Depending on your Linux distribution, you could simply copy it into /etc/rc.d and
use the appropriate admin tool, like Yast2 to add the script to the appropriate directory.
For more details see the section on init-scripts.
Note however, that simply changing /etc/inittab is not enough. You need to tell the init process
to re-read it. Normally init will re-read the file when it changes run levels or by sending it a
hangup signal with
kill -HUP <PID_OF_ID>.
Also running the command
telinit q
will tell init to reread it.
Be extremely careful if you edit the /etc/inittab file by hand. An editing mistake could
prevent your system from booting into a specific run level.
If you use the boot, bootwait or sysinit actions, you could prevent your system from booting at
all. Therefore, like with any system file it is good idea to make a backup copy first.
If you make a mistake that prevents a particular program from starting, and the action is
respawned, init might get caught in a loop.
That is, init tries to start the program, cannot, for whatever reason and
then tries to start it again. If init finds that it is starting the program more than 10 times
within 2 minutes, it will treat this as an error and stops trying. Typically you will get
messages in the system log that the process is "respawning too rapidly".
|