源文章链接:
Linux系統的啟動程序
Linux的啟動
Linux Runlevel
7 RunLevel
因應不同需求,Linux(UNIX)可以分為七種不同啟動模式,或七種不同執行等級,一般正常使用的系統多開啟為Level 3 或5
Runlevel
代表意義
0 關機
1 單人模式(Single User Mode)
2 多人使用模式,無NFS功能(網路是啟動的)
3 完整多人使用模式
4 unused
5 完整多人使用模式,xdm啟動(圖形Login畫面)
6 重新開機(Reboot)
Run Level的改變
root可以使用init或telinit切換到不同Run Level
init 0 = shutdown -h
init 6 = reboot
/etc/inittab內容解讀
/etc/inittab內容(Just For RedHAT Linux)
id : 3 : initdefault :
si : : sysinit: /etc/rc.d/rc.sysinit
l0 : 0 : wait: /etc/rc.d/rc 0
l1 : 1 : wait: /etc/rc.d/rc 1
l2 : 2 : wait: /etc/rc.d/rc 2
l3 : 3 : wait: /etc/rc.d/rc 3
l4 : 4 : wait: /etc/rc.d/rc 4
l5 : 5 : wait: /etc/rc.d/rc 5
l6 : 6 : wait: /etc/rc.d/rc 6
ud : : once : /sbin/update
ca : : ctrlaltdel : /sbin/shutdown -t3 -r now
pf : : powerfail :/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
pr : 12345 : powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
1 : 2345 : respawn : /sbin/mingetty tty1
2 : 2345 : respawn : /sbin/mingetty tty2
3 : 2345 : respawn : /sbin/mingetty tty3
4 : 2345 : respawn : /sbin/mingetty tty4
5 : 2345 : respawn : /sbin/mingetty tty5
6 : 2345 : respawn : /sbin/mingetty tty6
x : 5 : respawn : /etc/X11/prefdm -nodaemon
|
/etc/inittab每一行的格式
code:runlevels:action:process
code: 這是每"項目"(行)的識別碼,他的格式可以是一個字元或兩個字元,某些特殊動作必須搭配特酥識別碼,系統預定的識別碼建議不要更動它。
runlevels:這是這個"項目"(行)指定的Run Level,他的格式可以是0~6任何數目字元的組合,只要系統目前Run Level符合這個項目指定的層級,則這行的內容會自動生效,這行所指定的Command也將會被執行。
例如:當系統開機至Run Level 5時,項目『x : 5 : respawn : /etc/X11/prefdm -nodaemon』就會被執行,當系統開機至Run Level 2、3、4、5時,項目『1 : 2345 : respawn : /sbin/mingetty tty1』都會生效。
action:這個欄位告訴"init"如何處理這個項目,可用選項有:initdefault、wait、respawn等共15種不同的值,他們所代表的意義請用"man initttab"一窺究竟。
process:要執行的命令與參數。
id : 3 : initdefault :
action "initdefault"告訴 init 將系統開至Run Level 3
si : : sysinit: /etc/rc.d/rc.sysinit
runlevel 欄位空白告訴init不管系統開到哪一個Run Level都要執行這一項目(rc.sysinit)
action "sysinit"告訴init優先執行這個項目。"sysinit"將忽略runlevel欄位。
ca : : ctrlaltdel : /sbin/shutdown -t3 -r now
action "ctrlaltdel"告訴init當系統收到SIGINT(or User同時按下Alt+Ctrl+Del時),執行這個項目(/sbin/shutdown -t3 -r now)。如果你不希望你的系統因為有人在Console按下Alt+Ctrl+Del而重新開機時,你可以修改這個項目。
5 : 2345 : respawn : /sbin/mingetty tty5
表示在進入RunLevel 2/3/4/5/6時執行 "/sbin/mingetty tty5 ",action "respawn"表示在一個session結束後(User logout Console tty5),再執行一次"/sbin/mingetty tty5 ",如果此處不用repawn的話,當User Logout tty5,這個Virtual Terminal將一去不復返,也就是"Alt+F5"將不再發生作用。
******************************************************************************************
另外一篇相关文章转载:
/etc/inittab文件中每个登记项的结构都是一样的,共分为以冒号“:”分隔的4个字段。具体如下:
identifier : run_level : action : process
其中,各字段以及与其相关的说明如下:
identifier 登记项标识符,最多为4个字符。用于惟一地标识/etc/inittab文件中的每一个登记项
run_level 系统运行级,即执行登记项的init级别。用于指定相应的登记项适用于哪一个运行级,即在哪一个运行级中被处理。如果该字段为空,那么相应的登记项将适用于所有的运行级。在该字段中,可以同时指定一个或多个运行级,其中各运行级分别以数字0.1.2.3.4.5.6或字母a、b、c 表示,且无需对其进行分隔。
action 动作关键字。用于指定init(M)命令或进程对相应进程(在“process”字段定义)所实施的动作。具体动作包括:
1、boot:只有在引导过程中,才执行该进程,但不等待该进程的结束;当该进程死亡时,也不重新启动该进程。
2、bootwait:只有在引导过程中,才执行该进程,并等待进程的结束:当该进程死亡时,也不重新启动该进程。实际上,只有在系统被引导后,并从单用户方式进入多用户方式时,这些登记项才被处理;如果系统的默认运行级设置为2(即多用户方式),那么这些登记项在系统引导后将马上被处理。
3、initdefault:指定系统的默认运行级。系统启动时,init将首先查找该登记项。如果存在init将据此决定系统最初要进入的运行级。具体来说,init将指定登记项“run_level"字段中的最大数字(即最高运行级)为当前系统的默认运行级;如果该字段为空,那么将其解释为 “0123456”,并以“6”作为默认运行级。如果不存在该登记项,那么init将要求用户在系统启动时指定一个最初的运行级。
4、off:如果相应的进程正在运行,那么就发出一个警告信号,等待20秒后,再通过杀死信号强行终止该进程。如果相应的进程并不存在那么就忽略该登记项。
5、once:启动相应的进程,但不等待该进程结束便继续处理/etc/inittab文件中的下一个登记项;当该进程死亡时,init也不重新启动该进程。注意:在从一个运行级进入另一个运行级时,如果相应的进程仍然在运行,那么init就不重新启动该进程。
6、ondemand:与“respawn”的功能完全相同,但只用于运行级为a、b或c的登记项。
7、powerfail:只在init接收到电源失败信号时执行相应的进程,但不等待该进程结束。
8、powerwait:只在init接收到电源失败信号时执行相应的进程,并在继续对/etc/inittab文件进行任何处理前等待该进程结束。
9、respawn:如果相应的进程还不存在,那么init就启动该进程,同时不等待该进程的结束就继续扫描/etc/inittab文件;当该进程死亡时,init将重新启动该进程。如果相应的进程已经存在,那么init将忽略该登记项并继续扫描/etc/inittab文件。
10、sysinit:只有在启动或重新启动系统并首先进入单用户时,init才执行这些登记项。而在系统从运行级1-6进入单用户方式时,init 并不执行这些登记项。"action”字段为“sysinit”的登记项在“run_level”字段不指定任何运行级。
11、wait:启动进程并等待其结束,然后再处理/etc/inittab文件中的下一个登记项。
process 所要执行的shell命令。任何合法的shell语法均适用于该字段。
******************************************************************************
还有另外一篇文章转载,来自于:
导言
在一次IBM于阿姆斯特丹举办的Linux研讨会上,一位老师提出以下说法:“启动是Linux最难的部分。但是,一旦内核已经载入,并由init接管之后,你就畅行无阻了。从那个时刻起,所有发生的事情你都可以在脚本和文档(man page)里面读到。”
他当然是对的。在启动Linux机器的过程中没有什么秘密。你能在ASCII文件中读到所有东西。但是,在跟踪这些脚本的过程中也很容易迷路。Slackware与别的发行版不同之处在于它坚持用BSD风格的启动过程,而不是像它们那样用Sys V的启动过程。
在Sys V的启动系统中,所有起动/停止的脚本都放在 /etc/rc.d目录中。在每一个运行级(runlevel)都有一个目录(即 /etc/rc.1, /etc/rc.2 等等),其中全是该运行级所需运行脚本的链接。当进入一个运行级时,有一个大的脚本来处理这些链接以起动(或停止)该运行级的服务。
Sys V启动过程用在Redhat、Suse中,我将把解释它的事留给用这类系统的人。没有实际使用它的机器,我恐怕很快会在细节上晕头转向。
Slackware的用户(Slackers)多数认为Sys V启动过程既复杂又难于维护。老实说,Redhat和Suse用户的想法正好相反。不过,先跟着我,然后你自己作出判断。
在本文档中,我将试着证明IBM的老师是正确的。我将循着Slackware(8.1)的启动过程,用脚本和man page作为指导。会引用很多,而较少(我自己的)文字。
又及:你可能注意到,英语不是我的母语。我会尽量经常地用拼写检查程序,但它在语法方面的用处不大。无论在内容或语法方面的错误,请不吝赐教。此外,我非常喜欢大家对我写的东西提出看法。
运行级(runlevel)
我们会很多次谈到运行级,所以现在是个好机会来解释一下运行级。运行级是决定某机器的服务等级的*nix方式。在每个运行级中,人们可以定义哪些服务要激活、哪些不用。原则上,可以有很多运行级。实际上,只有5个:
- 单用户运行级,只有最少的服务在运行。这个运行级经常用于系统维护。
- 多用户运行级,所有提供的服务都在运行。这些服务可能是诸如HTTP服务器、电子邮件服务器、SQL服务器之类。正是系统管理员(你)所需要的。
- 多用户运行级,和前面一样,但这次有个图形界面的登陆管理器。
多用户运行级之一就是机器正常的运行状态。你可以决定另外的运行级。例如,用于远程维护的有网络支持的单用户运行级。
上述运行级之外,还有两个特殊的运行级:
- 停止系统(halt)的运行级。
- 重新启动(reboot)的运行级。
Init
假如我想用树状图表示我机器上所有的进程,我可能会得到这样的结果:
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:~$
pstree命令显示我机器上运行的进程的树状图,看起来有点像目录结构。最引人注目(至少在我看来)的是,树状图的“根”是“init”。从init派生出所有其他进程。这并非偶然。
来自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.
有几个值得注意的要点:
- init派生所有进程(Init is the parent of all processes.)
- init从文件 /etc/inittab中启动进程
- init控制所有独立的进程
在上面的树状图中,你能看到那些独立的进程。它们都是init的直系后代,举几个例子:agetty(4个)、sendmail(2个)、lpd和syslogd。
但为什么init是“所有进程之母”,看看manpage:
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.
可见内核(kernel)启动时所做的最后一件事就是启动init。init接着按 /etc/inittab的规定做事。
init的manpage给出了更多的信息,但对我们来说也许该看看/etc/inittab了。它似乎是个非常重要的文件。
来自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
啊哈,令人吃惊!它说:“用于与sysv兼容的init进程”。这是Slackware吗?没错,Slackware确实是用Sys V的init。纯粹为了开心,我们看看Slackware的软件包说明:
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:~$
所以不要听信别人说Slackware不用Sys V的init,不过它是按BSD风格来用。
inittab
玩够了......让我们看看 /etc/inittab 的格式。同样来自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.
组成这个文件的每行都有4个部分,用“:”分隔开
- id - 该行的标识
- runlevels - 该行为应该发生的运行级的列表
- action - 应发生的行为,你能在inittab的manpage里面发现对它们的概述。我将在适当的时候引用。
- process - 应由init启动的进程。
复杂吗?还不是那么坏吧,这是我的 /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,
# Modified by: Patrick J. Volkerding,
#
# 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:~$
只有74行文字(仅约一张A4纸的篇幅),如果你把那些注释去掉,将只剩下16行。但你将学到那些注释很值得读一读。
让我们开始把/etc/inittab拆开:
# Author: Miquel van Smoorenburg,
# Modified by: Patrick J. Volkerding,
这个文件的最后版本是由Miquel van Smoorenburg(听起来像德国人)制作的,然后由Patrick J. Volkerding(Slackware的维护者,对,Slackware是一个人的工作)为了用于Slackware而作了修改。这个注释没有太大作用,但它确实在那里。我们把它当作GPL的实例好了。
# 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
又是一些注释,当然它什么事都不做,但它让接下来的事情清晰了很多。你看到的是对Slackware用到的7个运行级的描述。运行级2和5都没有用到,往后你会看到它们和运行级3用同样的脚本。
# Default runlevel. (Do not set to 0 or 6)
id:3:initdefault:
终于要做些事情了。它是一个正常的inittab行,4个部分用“:”隔开。在这里的行为是“initdefault”,按照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.
在这里定义了缺省的运行级,当然注释就是这么说的。因此,Slackware缺省的运行级是3,用控制台/文本登录的多用户运行级。
假如系统启动时,Slackware没有接到进入其他运行级的信号(例如"telinit 1"这类命令),它就会进入这个运行级。
# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.S
这里的行为是“sysinit”(系统初始化),意思很明显,但我们还是看看manpage:
sysinit
The process will be executed during system boot.
It will be executed before any boot or bootwait
entries. The runlevels field is ignored.
虽然这里指明了运行级S,但实际上被忽略了。将执行的程序是/etc/rc.d/rc.S,是个脚本。你会看到Slackware所有的启动脚本都在/etc/rc.d。在/etc/rc.d/rc.S里,系统将被初始化,我们接下来讨论这个脚本时就会看到。
# Script to run when going single user (runlevel 1).
su:1S:wait:/etc/rc.d/rc.K
这里的行为是wait:
wait The process will be started once when the specified
runlevel is entered and init will wait for its
termination.
其中定义的脚本将在进入运行级1和S(意思是single)时被调用。“wait”行为将使init保留所有其他的动作直至/etc/rc.d/rc.K执行完毕。/etc/rc.d/rc.K启动了单用户运行级所需的服务,迟一点你会看到那不算很多。
# Script to run when going multi user.
rc:2345:wait:/etc/rc.d/rc.M
在这里的行为还是wait。这里定义了运行级2、3、4、5都调用/etc/rc.d/rc.M,基本上是除了运行级1之外的所有“常规”的运行级。一会儿我们会看到那是个怎样的脚本。
目前为止我们所看到的行是用来定义系统启动之后所发生的事。在所有情况下,init都会等到它启动的进程(脚本)终止。下面的几行是init在特殊情况下应做的事,而且不属于任何特定的运行级。
# What to do at the "Three Finger Salute".
ca::ctrlaltdel:/sbin/shutdown -t5 -r now
不单微软知道所谓的“三指礼”(译注:ctrl-alt-del),在Linux中你也能决定它出现时该做什么。下面是init的manpage中关于这个行为的条目:
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.
在Slackware的系统上,将会执行 /sbin/shutdown -t5 -r now 。
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.
参数 -r 的意思是重新启动(reboot),做法是给init进入运行级6的信号。延迟时间是从现在开始5秒。如果你有保持运行时间的癖好(uptime junkie),你可以让“三指礼”做完全不同的事情,并有效地迫使用户明确给出shutdown命令。(假如你有个NT类系统和Linux共存的服务器群,取消ctrl-alt-del的功能并不是一件坏事。)
当然第2部分(译注:指定运行级)就不必要了,init是对外界信号作出反应。
# Runlevel 0 halts the system.
l0:0:wait:/etc/rc.d/rc.0
这里的行为又是wait,因此init又会等待脚本执行完毕。进入运行级0后,init将执行 /etc/rc.d/rc.0 (最后是零)。这个脚本所做的是让所有启动了的进程安全地停止。不是所有的程序都喜欢你直接拔出插头的。作为最后的行动,它将调用poweroff来关闭系统或通知用户可以拔插头了。
# Runlevel 6 reboots the system.
l6:6:wait:/etc/rc.d/rc.6
这一行与上面那行非常像,事实上 /etc/rc.d/rc.0 是指向 /etc/rc.d/rc.6的符号链接,两个脚本其实是同一个。脚本的调用方式决定了最后一步会怎么做。在运行级6中,最后的命令将是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
这两行的命令要合在一起说,因为它们有很多相关性。它们的行为是:
powerwait
The process will be executed when the power goes
down. Init is usually informed about this by a pro-
cess talking to a UPS connected to the computer.
Init will wait for the process to finish before
continuing.
powerfail
As for powerwait, except that init does not wait
for the process's completion.
powerokwait
This process will be executed as soon as init is
informormed that the power has been restored.
这两行都是电力中断(或实际上是UPS电量耗尽)时该做的事情。
/sbin/genpowerfail start由关闭系统开始,/sbin/genpowerfail stop则试图在电力恢复时中断关机的行为。你可能注意到用start参数时并不会等脚本执行完毕,假如等了,就不可能中断关机的过程。 /sbin/genpowerfail是个使用shutdown命令的脚本,假如你有UPS你应该读一读这个脚本。
我们现在已经到了系统将要运行的关头。系统初始化的脚本已经执行了,缺省运行级的脚本也已经执行了- 单用户运行级是/etc/rc.d/rc.K,多用户运行级2、3、4、5执行的是/etc/rc.d/rc.M;所有需要的后台服务也在运行。在多用户运行级中,假如在/etc/rc.d/rc.M中启动了telnet和ssh服务,用户已经可以用这些方式登录系统了。假如你的系统是一个没有显示器和键盘的服务器,你让它这么待着就行了。
目前还不可能做到的是从控制台登录,有时能从控制台登录是会很方便的。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
马上我们有了个新的行为,在inittab的manpage里:
respawn
The process will be restarted whenever it termi-
nates (e.g. getty).
因此,已经启动的进程/sbin/agetty若被终止了,会重新运行。很明显,为运行级1、2、3和5启动了tty1至tty6的虚拟控制台。这些都是没有X的运行级。例外的是tty6上运行的agetty也将在运行级4(有X的运行级)启动。
agetty的manpage让我们了解到agetty的实际行为:
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).
可见,agetty在一个tty的端口等待用户登录,然后将运行/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.
login在系统上启动了一个新的会话。让我们回头看看pstree的输出:
bilbo@bilbo:~$ pstree
init-+-4*[agetty]
|-atd
|-bash
|-bash---startx---xinit-+-X
| `-xinitrc-+-bbmail
| `-blackbox-+-mozilla-bin---mozilla-bin---4+
| `-rxvt---bash---pstree
该死!不是应该有6个agetty吗?呃,对,曾经确实是有6个。但很显然,我从虚拟控制台登录了两次,有一次没有运行其他的程序,另一次运行了startx,变成了X会话。
当我logout的时候agetty会重新运行,还记得respawn吗?有趣的是,假如agetty启动得更早,会不会多个用户通过同一个虚拟控制台登录呢?
*nix总是提供了与系统联系的多种途径,我们已经知道了其中的2种:
- 通过网络,用telnet、ssh之类工具
- 通过直接连接到系统的键盘、显示器和鼠标
但是,*nix还有其他途径与系统联系:
# 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
上面两段为串行线路启动agetty,用于串口连接的终端或者用modem拨号进入。
你可以看到,它们缺省情况是被注释掉的。但一旦你需要使用古老的VT类终端或拨号进入系统,你就要用到这些代码。
在最后,要由X来给我们提供一个图形界面的运行级:
# 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
注释首先解释了为运行级4在tty6留下一个getty的原因。行为是wait,执行/etc/rc.d/rc.4。这个脚本将依次搜索kdm(kde的登录管理器)、gdm(gnome的登录管理器),最后是xdm(缺省的X登录管理器)。它会运行它所找到的第一个。这些登录管理器可以和agetty类比,它们会等着用户登录,当用户退出后自己重新运行。
bilbo@bilbo:~$ man kdm
No manual entry for kdm
bilbo@bilbo:~$
显然,目前为止没有kdm的manpage。
bilbo@bilbo:~$ man gdm
No manual entry for gdm
bilbo@bilbo:~$
目前为止,gnome的用户也不关心gdm的manpage。(译注:Slackware 9.1中已经有了)
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.''
最后我们终于找到了,这是xdm的manpage的片段。由于我总是在运行级3,我没法告诉你很多有关它的事。
我们已经看到,init - 所有进程之母 - 从内核那里接管了系统,然后init将处理/etc/inittab文件,根据inittab的输入,init将依次:
- 设置缺省的运行级
- 运行系统初始化脚本 /etc/rc.d/rc.S 并等待它结束
- 运行指定运行级的脚本并等待它结束
- 运行级1是/etc/rc.d/rc.K
- 运行级2、3、4、5是/etc/rc.d/rc.M
- 运行级0(关机)是/etc/rc.d/rc.0
- 运行级6(重新启动)是/etc/rc.d/rc.6
- 决定在特殊情况,例如ctrl-alt-del或停电时应采取的行动
- 为运行级1、2、3和5启动agetty(还有运行级4时启动6号终端,但有其特殊原因)
- 为串口连接启动终端,尽管这不是缺省的行为
- 为运行级4启动图形界面的登录管理器
结论
事实上这些就是init做的全部事情。剩下的“只不过是脚本”了。但是,仔细读它们也是很有趣的,否则你不会知道在哪里加载模块以及启动网络。