这是在自己学习linux from scratch 时就mingetty 的疑问在网上查到的一篇文章,受益不少,转载过来。原文链接:http://www.linuxsir.org/bbs/showthread.php?s=&threadid=83503
作者:Peter Kaagman
来自:www.slackfiles.org
原文:http://www.slackfiles.org/documentat...cles/init.html
翻译:windrose
导言
在一次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 作为指导。会引用很多,而较少( 我自己的) 文字。
又及:你可能注意到,英语不是我的母语。我会尽量经常地用拼写检查程序,但它在语法方面的用处不大。无论在内容或语法方面的错误,请不吝赐教。此外,我非常喜欢大家对我写的东西提出看法。
运行级(Runlevels)
我们会很多次谈到运行级,所以现在是个好机会来解释一下运行级。运行级是决定某机器的服务等级的*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, <[email protected]>
# Modified by: Patrick J. Volkerding, <[email protected]>
#
# 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 拆开:
代码:
这个文件的最后版本是由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 做的全部事情。剩下的“ 只不过是脚本” 了。但是,仔细读它们也是很有趣的,否则你不会知道在哪里加载模块以及启动网络。