sections in this module | City
College of San Francisco - CS260A Unix/Linux System Administration Module: StartupShutdown I |
module list |
init (upstart) is the ancestor of all real processes on Unix. Started in one of the kernel's 'spontaneous processes', it is the progenitor of all others. As a kindly grandparent, it also takes care of its progeny: if a process is orphaned, init unhesitatingly adopts it. This handshake mechanism avoids the occurance of 'parent-less' children, which become zombies when they attempt to exit. init must always be running on a functioning Unix system.
Most Unix users would say that init initializes the system. In
actuality, init
simply triggers events. Most of these are scripts that perform the
actual initialization work.
Recent versions of linux, including ours, have replaced the traditional init (which we will call System5 init) with the new event-driven daemon called upstart. The new system functions totally differently than the old System5 init. However, most of the system parts on our systems currently function in what we could call compatibility (or legacy) mode. As time goes on, more and more of these parts (which we will call subsystems) will be rewritten for the new upstart daemon, but, for the foreseeable future, we will have to become acquainted with both systems.
Because it is still so important, most of this module will
concern itself with System5 init
and its use of subsystems and runlevels. After we learn about the
legacy system we will revisit upstart at the end of this module.
Whichever version of init
is being used, it still only triggers
the steps of system initialization that occur outside of the
kernel. Some of the more prominent steps in this initialization
include:
init orchestrates this process in response to changes in the overall system state, which is indicated by its runlevel.
The runlevel
According to System5 init, the overall state of the system at any time is indicated by its current runlevel. init is used to manage the change in system configuration when this runlevel changes. A change in system runlevel can be affected by
telinit N
where N is the new
[target] runlevel. The shutdown
command also invokes telinit
to change the runlevel during the shutdown procedure.
init's runlevel is a small integer that traditionally only has a few values:
0 - the system is halted
S
- when the system is booted to single-user state, a single user
shell (running as root) is started and minimal system capabilities
are available. Exactly which filesystems are accessible is
implementation-defined, as are their read/write status.
1 - maintenance mode. If the system is currently running and services need to be shut down to perform some critical system configuration, state 1 may be entered. As with S state, a single-user shell is activated. Other differences between S and 1 are hazy at best, and for most discussions the two levels are synonymous. If the runlevel is reduced to 1 it is probably wise to reboot the system completely rather than returning to a higher runlevel.
2 - the system is in multi-user mode with less system services than normal operation. Historically, this runlevel was used to provide user logins on a standalone system - i.e. when the network was unavailable. Today, there is little difference between states 2 and 3.
3
- the system is in full multi-user mode, but the interface is
text-only. This runlevel is often used for servers.
4 - unused on linux.
5 - starts the window manager, X windows.
6 - reboot the system
In practice, the only runlevels that are often used are 0,1,3 and
5. On current Ubuntu systems, in fact, only a couple of runlevels
are in use besides 0 and 6.
Querying the runlevel
The current runlevel can be ascertained by who -r or by /sbin/runlevel. Both
commands show the current runlevel, and the runlevel command also
shows the previous runlevel, as many of the events triggered
are dependent on the change
in runlevel. The runlevel command indicates 'no previous runlevel'
as N, which means
that the current runlevel was entered immediately from system
boot.
The following command was executed on linux. It shows the previous runlevel (N for 'none') followed by the current runlevel of 5.
Changing runlevel
init is always running. If it isn't, you are in real trouble. Thus, changing runlevels consists simply of letting init know the runlevel to change to. The solution to this involves invoking a separate command named telinit (for tell init). telinit takes a single character argument. This character is the target runlevel (0-6). On systems that do not use upstart, the character could also be q. (q told init to reread its configuration file, but this is no longer necessary with upstart.)
The current [abbreviated] inittab
For brevity, we have deleted the discussion of the inittab format, as current systems that use upstart do not use it. If you are interested you can read about it in the last section in this page. It is still used on hills and on other Unix variants.
Some systems that use upstart (including ours) still store the default runlevel in the inittab. This is a single line like this
xxx:N:initdefault:
Here, xxx is a [redundant] label, N is the default runlevel (a single digit 1-5). The line format conforms to the old inittab format. When upstart starts it reads the inittab to determine what runlevel to go to. It then starts that runlevel.
Runlevel events
When a change in runlevel occurs, the legacy System5 init
sequence is emulated by upstart
and it mimicks what the old inittab
commands used to do:
When the system boots, the system initialization script rc.sysinit is executed.
When the runlevel changes, the master initialization script rc is executed. The following events cause a change in runlevel:
when the initdefault is read from the inittab
when a telinit N command is issued either by root or by shutdown.
The runlevel also triggers the start or stop of login processes on the virtual consoles tty1-6, which are accessible by cntl-alt-FN, where F means 'function key' and N is the function key number which corresponds to the virtual console number. (On upstart systems, starting consoles is detailed in start-ttys.conf.) Currently tty1 is reserved for X.
The rc scripts, as
they are called, drive the legacy System5 initialization process.
inittab on System5 systems
[This section is kept
for informational purposes only. If you are only concerned with
linux systems you can skip this section.]
As we have said, the System5 init sequence is being emulated by upstart. On systems that use traditional System5 init, init uses the configuration in the inittab to tell it what to do when the system changes state (either a runlevel change or a different state in the boot process). Let's explore the inittab format in-depth. The format of an inittab entry is
id:runlevels:action:process
id is a unique label identifying the entry. The id is required, and the length of the label is severly limited. Traditionally this limit was two characters, although most systems now allow up to four charcters(!) There is only one instance that I know of that the id is important, and that has to do with archaic accounting programs that charged for terminal connect time. For those programs, the label had to be the same as the number of the terminal line on the inittab entries that controlled a terminal login.
runlevels is a sequence of runlevels at which the process should be run. Only valid runlevels (0-6) are allowed. If the action is ondemand, the only allowed runlevels are the ondemand runlevels ABC (or abc). An empty field here means 'all appropriate runlevels' for this action. (Runlevels are ignored for sysinit, boot, and bootwait actions.) Example: 134 means runlevels 1,3, and 4.
process is a simple shell command, which can include redirection.
action indicates how the entry is managed.
The actions are:
initdefault - the default system runlevel is iset to the (required) single runlevel in the initdefault entry. In the absence of an initdefault entry, init will request the target runlevel from the system console. The process field is ignored. Example:
sets the default runlevel to 3.
once - execute the process once on entry to the runlevel. (start it unless it is already running) Don't wait for the process to complete before continuing on to the next entry.
wait - same as once, but wait for the process to complete before continuing to the next entry.
off - if the process is running, kill it. (this is also used to comment out entries, although comment lines (lines that start with #) are allowed.)
respawn - start the process and automatically restart it if it completes. (keep it running)
ondemand - same as respawn, but only for ondemand runlevels A,B, and C.
sysinit - start the process at boot time before anything else, and wait for it to complete before continuing.
boot - start this process once at boot time (after sysinit entries) and don't wait for it to complete before continuing.
bootwait - same as boot, but wait for the process to complete before continuing.
powerfail,powerokwait,powerwait,powerfailnow - entries performed in response to UPS events.
ctrlaltdel - start the process in response to a control-alt-delete keystroke. (Control-Alt-Delete may be ignored if it is typed at the GUI. It must be typed at a virtual console.)
Example
Suppose we had the inittab entries below:
id:3:initdefault:
x0::boot:/etc/rc.d/rcx "system starting"
x1:12345:wait:/sbin/xxx 2>/dev/null
1:2345:respawn:/sbin/mingetty tty1
ab:2:once:/bin/foo
xx::sysinit:/etc/rc.d/rc.sysinit
What commands would be executed, and in what order, when the system started?
the /etc/rc.d/rc.sysinit program is run, and init waits until it exits before proceeding.
the /etc/rc.d/rcx process is run with the single argument "system starting". This time, init does not wait for the prcess to exit before proceeding.
the default runlevel is 3, as seen by the initdefault, so runlevel 3 is entered
the /sbin/xxx process is run. init waits for it to exit before proceeding.
the /sbin/mingetty process is run with the single argument tty1. If this process exits, init will restart it.
Note that
the sysinit was done before the boot entry even though the line with the boot action came first.
Both sysinit and boot were performed before the runlevel was entered.
The /bin/foo process was never started since the system default runlevel was 3. (The default runlevel is entered immediately.)
Preview question: In legacy System5 initialization, detailed system initialization is divided among subsystems, whose initialization is triggered indirectly by the scripts that init starts. List the status of each subsystem available on your linux system using the command /sbin/service --status-all |
Prev | This page was made entirely
with free software on linux: the Mozilla Project and Openoffice.org |
Next |