|
楼主 |
发表于 2006-4-10 20:08:12
|
显示全部楼层
原英文版本:
[php]
Slack's INIT
1. Runlevels.
There will be a lot of talk about runlevels. So perhaps this is a good
time to give a bit of explanation about runlevels. A runlevel is a *nix
method to determine the service level of a certain machine. Per runlevel
one would be able to define which services will be active and which not.
In principle there can be many runlevels. In practice this is limited to
5:
* A single user runlevel in which an absolute minimum of services is
running. This runlevel is often used for system maintenance.
* A multi user runlevel in which all the services run which are to be
offered. These services can be a HTTP server , e-mail server, SQL
server or what ever else. Just what the sysop (you!) wants.
* A multi user runlevel, same as before, only this time with a graphical
login manager.
One of these multi user runlevels will be the normal operation state of
the machine. It is up to you to define extra runlevels. For instance a
single user runlevel with network support for remote maintenance.
Beside these runlevels there are 2 special runlevels:
* A runlevel to halt the system.
* A runlevel to reboot the system.
3.2. Init, the mother of all processes.
If I ask for a forest view of all the processes on my box, I would get
something like this:
bilbo@bilbo:~$ pstree
init-+-4*[agetty]
|-atd
|-bash
|-bash---startx---xinit-+-X
| `-xinitrc-+-bbmail
| `-blackbox-+-mozilla-bin---mozilla-bin---4+
| `-rxvt---bash---pstree
|-crond
|-dhcpcd
|-fetchmail
|-gpm
|-gvim
|-httpd---7*[httpd]
|-inetd---in.identd---in.identd---5*[in.identd]
|-keventd
|-khubd
|-klogd
|-kreiserfsd
|-loop0
|-loop1
|-lpd
|-mdrecoveryd
|-named
|-2*[sendmail]
`-syslogd
bilbo@bilbo:~$
What pstree shows is a sort of "tree structure" view of all the processes
on my box. It looks a bit like a directory structure. What catches the eye
(mine at least) is that the "root" in this view is "init". From init all
other processes spawn. And that is not by chance.
From the manpage:
INIT(8) Linux System Administrator's Manual INIT(8)
NAME
init, telinit - process control initialization
SYNOPSIS
/sbin/init [ -a ] [ -s ] [ -b ] [ -z xxx ] [ 0123456Ss ]
/sbin/telinit [ -t sec ] [ 0123456sSQqabcUu ]
DESCRIPTION
Init
Init is the parent of all processes. Its primary role is
to create processes from a script stored in the file
/etc/inittab (see inittab(5)). This file usually has
entries which cause init to spawn gettys on each line that
users can log in. It also controls autonomous processes
required by any particular system.
There are a few important remarks in here:
* Init is the parent of all processes.
* Init starts processes from a file /etc/inittab.
* Init is in control of autonomous processes (daemons).
In the pstree view above you can see those autonomous processes. They are
all direct children of init. Among them are agetty (4x), sendmail (2x),
lpd and syslogd to name a few.
But why is it that init is the "mother of all processes"?
From the manpage (regel 43)
BOOTING
After init is invoked as the last step of the kernel boot
sequence, it looks for the file /etc/inittab to see if there is an
entry of the type initdefault (see inittab(5)). The initdefault
entry determines the initial runlevel of the system. If there is
no such entry (or no /etc/inittab at all), a runlevel must be
entered at the system console.
So the last thing the kernel does when it boots is to start init. Init on
its turn will work its way through /etc/inittab.
Init's manpage gives a lot more info. But perhaps for us it is a good time
to take a look at /etc/inittab. This seems to be a pretty important file.
3.3. /etc/inittab
From the manpage:
INITTAB(5) Linux System Administrator's Manual INITTAB(5)
NAME
inittab - format of the inittab file used by the sysv-compatible
init process
DESCRIPTION
The inittab file describes which processes are started at bootup
and during normal operation (e.g. /etc/init.d/boot,
/etc/init.d/rc, gettys...). Init(8) distinguishes multiple run-
levels, each of which can have its own set of processes that are
started. Valid runlevels are 0-6 plus A, B, and C for ondemand
entries. An entry in the inittab file has the following format:
id:runlevels:action:process
Whoha, shock!. It says: "Used by the sysv-compatible init process". And
this is Slackware?
Yes this is Slackware, and Slackware uses Sys V init. Just for kicks, lets
have a look at the Slackware package description:
bilbo@bilbo:~$ head -n 14 /var/log/packages/sysvinit-2.84-i386-18
PACKAGE NAME: sysvinit-2.84-i386-18
COMPRESSED PACKAGE SIZE: 232 K
UNCOMPRESSED PACKAGE SIZE: 560 K
PACKAGE LOCATION: /var/log/mount/slackware/a/sysvinit-2.84-i386-18.tgz
PACKAGE DESCRIPTION:
sysvinit: sysvinit (init, the parent of all processes)
sysvinit:
sysvinit: System V style init programs by Miquel van Smoorenburg that control
sysvinit: the booting and shutdown of your system. These support a number of
sysvinit: system runlevels, each with a specific set of utilities spawned.
sysvinit: For example, the normal system runlevel is 3, which starts agetty
sysvinit: on virtual consoles tty1 - tty6. Runlevel 4 starts xdm.
sysvinit: Runlevel 0 shuts the system down.
sysvinit:
bilbo@bilbo:~$
So let nobody ever tell you that Slackware does not use Sys V init. It
just uses it in a "BSD style".
Enough fun..... lets have a look at /etc/inittabs format:
Again from the manpage:
id:runlevels:action:process
Lines beginning with `#' are ignored.
id is a unique sequence of 1-4 characters which iden-
tifies an entry in inittab (for versions of
sysvinit compiled with libraries < 5.2.18 or a.out
libraries the limit is 2 characters).
Note: For gettys or other login processes, the id
field should be the tty suffix of the corresponding
tty, e.g. 1 for tty1. Otherwise, the login
accounting might not work correctly.
runlevels
lists the runlevels for which the specified action
should be taken.
action describes which action should be taken.
process
specifies the process to be executed. If the pro-
cess field starts with a `+' character, init will
not do utmp and wtmp accounting for that process.
This is needed for gettys that insist on doing
their own utmp/wtmp housekeeping. This is also a
historic bug.
The file is consists of lines, each made out of 4 fields, separated by a
":"
* id - an identifier for the line
* runlevels - a list with zero 1 or more runlevels for which this action
should take place
* action - the action that should take place, you will find them
summarized in inittab's manpage. I'll quote them when appropriate
* process - the process which will be started by init
Complex? It is not that bad.... here is my /etc/inittab:
bilbo@bilbo:~$ cat /etc/inittab
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Version: @(#)inittab 2.04 17/05/93 MvS
# 2.10 02/10/95 PV
# 3.00 02/06/1999 PV
# 4.00 04/10/2002 PV
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified by: Patrick J. Volkerding, <volkerdi@slackware.com>
#
# These are the default runlevels in Slackware:
# 0 = halt
# 1 = single user mode
# 2 = unused (but configured the same as runlevel 3)
# 3 = multiuser mode (default Slackware runlevel)
# 4 = X11 with KDM/GDM/XDM (session managers)
# 5 = unused (but configured the same as runlevel 3)
# 6 = reboot
# Default runlevel. (Do not set to 0 or 6)
id:3:initdefault:
# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.S
# Script to run when going single user (runlevel 1).
su:1S:wait:/etc/rc.d/rc.K
# Script to run when going multi user.
rc:2345:wait:/etc/rc.d/rc.M
# What to do at the "Three Finger Salute".
ca::ctrlaltdel:/sbin/shutdown -t5 -r now
# Runlevel 0 halts the system.
l0:0:wait:/etc/rc.d/rc.0
# Runlevel 6 reboots the system.
l6:6:wait:/etc/rc.d/rc.6
# What to do when power fails.
pf::powerfail:/sbin/genpowerfail start
# If power is back, cancel the running shutdown.
pg::powerokwait:/sbin/genpowerfail stop
# These are the standard console login getties in multiuser mode:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:1235:respawn:/sbin/agetty 38400 tty2 linux
c3:1235:respawn:/sbin/agetty 38400 tty3 linux
c4:1235:respawn:/sbin/agetty 38400 tty4 linux
c5:1235:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
# Local serial lines:
#s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
#s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100
# Dialup lines:
#d1:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS0 vt100
#d2:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100
# Runlevel 4 used to be for an X window only system, until we discovered
# that it throws init into a loop that keeps your load avg at least 1 all
# the time. Thus, there is now one getty opened on tty6. Hopefully no one
# will notice. ;^)
# It might not be bad to have one text console anyway, in case something
# happens to X.
x1:4:wait:/etc/rc.d/rc.4
# End of /etc/inittab
bilbo@bilbo:~$
Only 74 lines of text (just about an A4 (ok folio)), if you would take
away the comments there would be only 16 lines left! But you will learn
that the comments are worth reading.
Lets start by taking /etc/inittab apart....
3.4. Comments to start with
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified by: Patrick J. Volkerding, <volkerdi@slackware.com>
The last version of the file has been made by Miquel van Smoorenburg
(sounds dutch) and it is modified for Slackware by Patrick J. Volkerding
(Slackware's maintainer(yes Slackware is a one mans job)). The comment
does not do much, but it does belong there. Lets call it GPL at work.
3.5. The Slackware runlevels
# These are the default runlevels in Slackware:
# 0 = halt
# 1 = single user mode
# 2 = unused (but configured the same as runlevel 3)
# 3 = multiuser mode (default Slackware runlevel)
# 4 = X11 with KDM/GDM/XDM (session managers)
# 5 = unused (but configured the same as runlevel 3)
# 6 = reboot
Again a piece of comment, which of course does not do anything. But it
makes what is to follow a lot clearer. What you see is a description of
the 7 runlevels as in use by Slackware. Run levels 2 and 5 are not in use,
you will see later on that they use the same scripts as runlevels 3.
3.6. The default runlevel
# Default runlevel. (Do not set to 0 or 6)
id:3:initdefault:
Finally something is actually done. It is a normal inittab line; 4 fields,
separated by a ":". The action here is "initdefault", according to the
manpage:
initdefault
An initdefault entry specifies the runlevel which should be entered after system boot.
If none exists, init will ask for a runlevel on the console. The process field is ignored.
Here the default runlevel is configured. But of course that is what it
said in the leading comment. So the default runlevel for Slackware is
runlevel 3; a multi-user runlevel with console/text login.
This is the runlevel init will enter if its not signaled (by a command
like `telinit 1`) to enter an other runlevel, i.e. when the system boots.
3.7. Systeem initialisation
# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.S
The action here is "sysinit" and it's meaning is quite obvious, but lets
have a look at the manpage anyway:
sysinit
The process will be executed during system boot. It will be executed before any boot or
bootwait entries. The runlevels field is ignored.
Allthough the runlevel "S" is stated, it is actually ignored. The program
that will run is /etc/rc.d/rc.S, which is a script. You will see that all
of Slackware's init scripts are in /etc/rc.d. In /etc/rc.d/rc.S the system
will be initialised as we will see when we discuss the script later on.
3.8. The runlevel scripts
# Script to run when going single user (runlevel 1).
su:1S:wait:/etc/rc.d/rc.K
The action here is wait:
wait The process will be started once when the specified runlevel is entered and init will wait for its
termination.
The script (that is what it is) will be called when entering runlevels 1
and S (S for single). The action "wait" makes that init will hold all
other actions until the processing of /etc/rc.d/rc.K finishes. In
/etc/rc.d/rc.K the services are started needed for a singe user runlevel.
Later on you will see those are not a whole lot.
# Script to run when going multi user.
rc:2345:wait:/etc/rc.d/rc.M
Again the action is wait. This says the script /etc/rc.d/rc.M is called
for the runlevels 2,3,4 and 5. So in essence for all the "normal"
runlevels except runlevel 1. In /etc/rc.d/rc.M all the services for a
multi-user runlevel are started. Quite a script as we will see in a while.
The lines we have seen so far are used to determine what hapens after a
system boots. In all cases init will wait till the started process (the
script) terminates. The next couple of lines are actions that init should
take in special circumstances and do not really belong to any specific
runlevel.
3.9. Special circumstances
# What to do at the "Three Finger Salute".
ca::ctrlaltdel:/sbin/shutdown -t5 -r now
Not just MS knows about the "3 finger salute". But in Linux you can decide
for youself what happen when it is given. To be complete here is init's
manpage entry about this action:
ctrlaltdel
The process will be executed when init receives the SIGINT signal. This means that someone on the
system console has pressed the CTRL-ALT-DEL key combination. Typically one wants to execute some sort
of shutdown either to get into single-user level or to reboot the machine.
On a Slackware system the command `/sbin/shutdown -t5 -r now` is executed.
SHUTDOWN(8) Linux System Administrator's Manual SHUTDOWN(8)
NAME
shutdown - bring the system down
SYNOPSIS
/sbin/shutdown [-t sec] [-arkhncfF] time [warning-message]
DESCRIPTION
shutdown brings the system down in a secure way. All
logged-in users are notified that the system is going
down, and login(1) is blocked. It is possible to shut the
system down immediately or after a specified delay. All
processes are first notified that the system is going down
by the signal SIGTERM. This gives programs like vi(1) the
time to save the file being edited, mail and news process
ing programs a chance to exit cleanly, etc. shutdown does
its job by signalling the init process, asking it to
change the runlevel. Runlevel 0 is used to halt the sys
tem, runlevel 6 is used to reboot the system, and runlevel
1 is used to put to system into a state where administra
tive tasks can be performed; this is the default if nei
ther the -h or -r flag is given to shutdown. To see which
actions are taken on halt or reboot see the appropriate
entries for these runlevels in the file /etc/inittab.
The -r means that a reboot will follow, this is done by signaling init to
enter runlevel 6. The delay is 5 seconds from now. If you are a uptime
junkie you could make the "3 finger salute" do something completely
different, and in effect force a user to give the shutdown command
explicitly. (Disabling ctrl-alt-del is not such a bad idea if you have a
server farm mix with NT like systems and Linux.)
Off course there is no need for the second field for the runlevel. Init
reacts on a signal from the outside world.
# Runlevel 0 halts the system.
l0:0:wait:/etc/rc.d/rc.0
Again the action is wait, so init will once again wait for the script to
finish. On entering runlevel 0 init will execute /etc/rc.d/rc.0 (that's a
zero ;)). What this script does is bring all started processes down in a
safe way. Not every program likes when you would simply pull the plug. As
a last action it will call poweroff which will shutsdown the system or
signal the user that he can pull the plug.
# Runlevel 6 reboots the system.
l6:6:wait:/etc/rc.d/rc.6
This entry is verry simular to the previous entry. That simular in fact
that /etc/rc.d/rc.0 is a symbolic link to /etc/rc.d/rc.6. The two scripts
are identical. The way the script is called determines what the last step
will be. In the case of runlevel 6 (this case) the last command will be
reboot.
# What to do when power fails.
pf::powerfail:/sbin/genpowerfail start
# If power is back, cancel the running shutdown.
pg::powerokwait:/sbin/genpowerfail stop
These next two entries can be adressed in one go. They have a lot to do
with each other. The actions are:
powerokwait
This process will be executed as soon as init is
informormed that the power has been restored.
powerfailnow
This process will be executed when init is told
that the battery of the external UPS is almost
empty and the power is failing (provided that the
external UPS and the monitoring process are able to
detect this condition).
Both lines have something to do with the action that will be taken as a
result of a power faillure (or actually the draining of the UPS battries).
`/sbin/genpowerfail start' begins by bringing the system down.
`/sbin/genpowerfail stop` tries to interrupt the system going down in case
the power is restored. Perhaps you notice that the start action does not
wait for the script to finish. If it would have waited, one would not be
able to ineterrupt the shutdown. `/sbin/genpowerfail` is a script which
uses 'shutdown', if you have an UPS you should read the script
/sbin/genpowerfail.
3.10. A way to logon
We've now reached the point where the system is just about operational.
The sysinit scrip has executed. The default runlevel script(s) have been
executed, /etc/rc.d/rc.K for the single user runlevel 1 and /etc/rc.d/rc.M
for the multi user runlevels 2,3,4 and 5. All intended daemons are
running. And in a multi users runlevel one would be able to logon with
telnet or ssh, assuming these daemons have been started in /etc/rc.d/rc.M.
If your system is a server without display and keyboard you could actually
leave it like this.
What isn't possible at the moment is to logon at the console. And from
time to time being able to log in comes in quite handy. Console logons are
the next task of init.
# These are the standard console login getties in multiuser mode:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:1235:respawn:/sbin/agetty 38400 tty2 linux
c3:1235:respawn:/sbin/agetty 38400 tty3 linux
c4:1235:respawn:/sbin/agetty 38400 tty4 linux
c5:1235:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
And right away we have a new action, the inittab manpage:
respawn
The process will be restarted whenever it termi-
nates (e.g. getty).
So the started process, /sbin/agetty, will be restarted when it
terminates. And apperently are started for virtual consoles tty1 through
tt6 for the runlevels 1,2,3 and 5. These are the runlevels without X.
Except for the agetty on tty6 which is allso started for runlevel 4. The
runlevel with X.
The agetty man page gives us an idea what agetty actually does:
AGETTY(8) AGETTY(8)
NAME
agetty - alternative Linux getty
SYNOPSIS
agetty [-ihLmnw] [-f issue_file] [-l login_program] [-I
init] [-t timeout] [-H login_host] port baud_rate,...
[term]
agetty [-ihLmnw] [-f issue_file] [-l login_program] [-I
init] [-t timeout] [-H login_host] baud_rate,... port
[term]
DESCRIPTION
agetty opens a tty port, prompts for a login name and
invokes the /bin/login command. It is normally invoked by
init(8).
So agetty waits on a tty port untill somebody tries to login, at which
moment is will execute /bin/login.
LOGIN(1) LOGIN(1)
NAME
login - begin session on the system
SYNOPSIS
login [-p] [username] [ENV=VAR ...]
login [-p] [-h host] [-f username]
login [-p] -r host
DESCRIPTION
login is used to establish a new session with the system.
It is normally invoked automatically by responding to the
login: prompt on the user's terminal. login may be spe-
cial to the shell and may not be invoked as a sub-process.
Typically, login is treated by the shell as exec login
which causes the user to exit from the current shell.
Attempting to execute login from any shell but the login
shell will produce an error message.
And with login a new session is started on the system.
Lets look back at the output of pstree:
bilbo@bilbo:~$ pstree
init-+-4*[agetty]
|-atd
|-bash
|-bash---startx---xinit-+-X
| `-xinitrc-+-bbmail
| `-blackbox-+-mozilla-bin---mozilla-bin---4+
| `-rxvt---bash---pstree
Shoot! Shouldn't there be 6 agetty's?
Well.... yes, and at one time there actually were 6. But apperantly I have
logged in twice via a virtual console. Once without any other program
started, and once with an startx running.... an X session it seems.
Agetty wil start again whenever I logout, with that respawn... remember.
It would be kinda funny if agetty would start sooner, multiple users that
could log in on the same virtual console?
3.11. Another way to logon.
*Nix has allways given different ways to connect to a system. We have
allready seen 2 of them:
* Via the network - with telnet, ssh or such.
* Via the keyboard, monitor and mouse connected to the system directly.
But *nix has yet other ways to connect to the system
# Local serial lines:
#s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
#s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100
# Dialup lines:
#d1:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS0 vt100
#d2:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100
The above 2 blocks start agetty's for serial lines. Those are used for
serail terminals or dialin connections via modems.
As you can see they are marked out by default. But this is the code you
will have to deal with if lay you hands on one those good old vtxxx
terminals or want to dial in to your box.
3.12. And then there is X.
And at the verry end, there is X to give us a graphical runlevel
# Runlevel 4 used to be for an X window only system, until we discovered
# that it throws init into a loop that keeps your load avg at least 1 all
# the time. Thus, there is now one getty opened on tty6. Hopefully no one
# will notice. ;^)
# It might not be bad to have one text console anyway, in case something
# happens to X.
x1:4:wait:/etc/rc.d/rc.4
The comment first of all gives an explanation for the one getty left over
on tty6 running in runlevel 6
It is a "wait" action which executes /etc/rc.d/rc.4. This script will look
in sequence for kdm (the kde login manager), gdm (the gnome login manager)
and last xdm (a default login manager). It will execute the first it
finds. These login managers can be compared to agetty in that they will
wait for a user to login an start themselves again when the user logs out.
bilbo@bilbo:~$ man kdm
No manual entry for kdm
bilbo@bilbo:~$
So far for the kdm manpage, appently they did not get to it at KDE.
bilbo@bilbo:~$ man gdm
No manual entry for gdm
bilbo@bilbo:~$
And so far for the gdm manpage, and the Gnome people do not care either.
XDM(1) XDM(1)
NAME
xdm - X Display Manager with support for XDMCP, host
chooser
SYNOPSIS
xdm [ -config configuration_file ] [ -nodaemon ] [ -debug
debug_level ] [ -error error_log_file ] [ -resources
resource_file ] [ -server server_entry ] [ -session ses-
sion_program ]
DESCRIPTION
Xdm manages a collection of X displays, which may be on
the local host or remote servers. The design of xdm was
guided by the needs of X terminals as well as The Open
Group standard XDMCP, the X Display Manager Control Proto-
col. Xdm provides services similar to those provided by
init, getty and login on character terminals: prompting
for login name and password, authenticating the user, and
running a ``session.''
And, finally we have got a hit, here is an abstract from the XDM manpage.
Since I am allways in runlevel 3 I can't really tell you a lot about it.
En hier die van xdm. Ik kan je er verder weinig van vertellen. Ik zit
altijd in runlevel 3, en gebruik dus geen grafische inlog managers.
3.13. Where did that get us.
We have seen that "init" - as the mother of all processes - got controll
over the machine from the kernal. "Init" will than process the file
"/etc/inittab". With the input from "inittab" "init" will in sequence:
* Set the default runlevel.
* Run the sytem initialisation script /etc/rc.d/rc.S, and wait for its
completion.
* Run the script for the decided runlevel, and wait for its completion.
* /etc/rc.d/rc.K for the single user runlevel 1
* /etc/rc.d/rc.M for the multi user runlevels 2,3,4 en 5
* /etc/rc.d/rc.0 for runlevel 0 (system halt)
* /etc/rc.d/rc.6 for runlevel 6 (system reboot)
* Determine which action should be taken in special circumstances like;
ctrl-alt-del and power faillure.
* Start agetty's for the consoles in runlevels 1, 2, 3 en 5 so users can
logon locally. (And 1 for runlevel 4 on console 6, but that has a
special reason)
* Start agetty's for serial connection, not the default behaviour
though..
* Start a graphical logon manager for runlevel 4.
This in fact is all there is to it for init. What rests are "just
scripts". But they can be fun to look over; otherwise you still would not
know where your modules get loaded and the network started.
[/php] |
|