Debian的init进程初始化工作原理

来源:互联网 发布:做java程序员 编辑:程序博客网 时间:2024/06/07 03:29

init和inittab 
============= 
Linux下为什么会要有个init?用过windows 9.x的人应该知道有个批处理文件autoexec.bat,用过windows NT/2000系统的人应该在控制面板中见过system service工具,他们的目的是相同的。只是比较起来windows下的这些东西功能太弱(当然用法也更简单)。 
init是Linux启动的最后一步,他帮助用户完成每次启动系统都必须完成的一些重复性任务,如加载文件系统、各类网络服务等等程式;他更有一个重要用途,让用户自定义系统运行环境,只启动需要的进程,关闭不用的进程,释放内存和处理器资源,让系统运行得更快更稳。 
init 会按任务表执行我们下的命令,这个任务表就是/etc/inittab文件。我们能为系统制定多个运行环境以满足不同任务的需要,在inittab中称之为运行等级(runlevel)。例如,计算机要用来完成一种连网编译任务(和其他系统共享CPU周期,合作编译软件),这样情况需占用大量CPU能力和内存,所以当计算机用作这种用途时,其他程式的运行要尽可能少。可设置一个运行等级(如:runlevel 4),把其他程式包括X Window全关闭,只启动连网编译进程;其他时段,你的计算机要和视窗系统系统共享文件,需要启动Samba,能再定义一个运行等级(如: runlevel 2)。 
目前当你要进行连网编译时可运行init 4,而不用手工去关闭每个暂不必的进程;要和视窗系统系统共享文件可运行init 2。 
Debian系统对某些运行等级进行了预先设置(而且是无法修改的) 
runlevel 0:他的任务就是关闭所有程式,关机。如果计算机及内核支持APM,系统电源可自动切断。 
runlevel 1:为单用户模式保留的。在这个运行等级下,除了一个root shell外,没有其他程式运行。除了root文件系统以只读方式安装外,不安装其他文件系统。该运行等级通常在恢复系统时用。 
runlevel 6:和runlevel 0非常相似,只是他是重启系统而不是关闭系统。 
runlevel 2、3、4、5:Debian系统对他们没有具体规定,通常可自由进行制定,他们都属于多用户模式。其中runlevel 3是Debian使用的默认运行等级。启动Debian系统时,用的就是这个运行等级。 
下面是inittab文件的例子 
# /etc/inittab: init(8) configuration. 
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ 
# The default runlevel. 
id:2:initdefault: 
# Boot-time system configuration/initialization script. 
# This is run first except when booting in emergency (-b) mode. 
si::sysinit:/etc/init.d/rcS 
# What to do in single-user mode. 
~~:S:wait:/sbin/sulogin 
# /etc/init.d executes the S and K scripts upon change 
# of runlevel. 

# Runlevel 0 is halt. 
# Runlevel 1 is single-user. 
# Runlevels 2-5 are multi-user. 
# Runlevel 6 is reboot. 
l0:0:wait:/etc/init.d/rc 0 
l1:1:wait:/etc/init.d/rc 1 
l2:2:wait:/etc/init.d/rc 2 
l3:3:wait:/etc/init.d/rc 3 
l4:4:wait:/etc/init.d/rc 4 
l5:5:wait:/etc/init.d/rc 5 
l6:6:wait:/etc/init.d/rc 6 
# Normally not reached, but fallthrough in case of emergency. 
z6:6:respawn:/sbin/sulogin 
# What to do when CTRL-ALT-DEL is pressed. 
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now 
# Action on special keypress (ALT-UpArrow). 
#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work." 
# What to do when the power fails/returns. 
pf::powerwait:/etc/init.d/powerfail start 
pn::powerfailnow:/etc/init.d/powerfail now 
po::powerokwait:/etc/init.d/powerfail stop 
# /sbin/getty invocations for the runlevels. 

# The "id" field MUST be the same as the last 
# characters of the device (after "tty"). 

# Format: 
# ::: 

# Note that on most Debian systems tty7 is used by the X Window System, 
# so if you want to add more getty’s go ahead but skip tty7 if you run X. 

1:2345:respawn:/sbin/getty 38400 tty1 
2:23:respawn:/sbin/getty 38400 tty2 
3:23:respawn:/sbin/getty 38400 tty3 
4:23:respawn:/sbin/getty 38400 tty4 
5:23:respawn:/sbin/getty 38400 tty5 
6:23:respawn:/sbin/getty 38400 tty6 
# Example how to put a getty on a serial line (for a terminal) 

#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100 
# Example how to put a getty on a modem line. 

#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3 
该文件有一个基本类型的指令,他们指定命令行,命令行所采取的动作,在何种运行等级下激活命令。这引起命令行的格式大体如下: 
id:runlevels:action:command 
id是任意一个名称(具体是什么并不重要),runlevels是个数字串(代表运行等级),action描述何时执行命令,command指定执行的实际命令。拿启动getty的命令行举例: 
1:2345:respawn:/sbin/getty 38400 tty1 
该命令告诉init,他应该在引导后以运行等级2-5运行命令/sbin/getty 38400 tty1。动作标记respawn表示命令在退出时重新运行(当用户在shell输入exit的时候)。 
从方面的文件中能看到,运行等级2和3有六个活动的gettys,而等级4和5只有一个。假设运行等级4下有三个shell运行在虚拟控制台。你在ID为2和3的命令行的运行等级字段添加了数字4,也就是说你将 
2:23:respawn:/sbin/getty 38400 tty2 
3:23:respawn:/sbin/getty 38400 tty3 
替换成 
2:234:respawn:/sbin/getty 38400 tty2 
3:234:respawn:/sbin/getty 38400 tty3 
然后重启或执行以下命令: 
telinit q 
对inittab进行修改。telinit q命令指示init重新加载他的设置。参阅telinit(8)。 
/etc/inittab的其他行看起来比较复杂,我们先看看更有哪些动作标记: 
?respawn:启动命令并监视命令的执行,当进程退出时,再次执行该命令(通常用于虚拟终端设备上的登录提示)。 ?wait:进入指定运行等级时,启动进程。init会停下来,直到执行完成。这个标记用于设置特定等级下软件的启动。 
?once:进入指定的任一运行等级时,启动一次进程。 
?boot:该命令在系统引导时运行。这种类型的指令忽略运行等级。 
?bootwait:该命令在系统引导时运行,init等到他退出后才能继续做别的事。 
?off:禁用所有运行等级下的某个命令。 
?initdefault:这种类型的项指定在系统引导时进入哪个运行等级。 
?powerwait:这类指令给出在电源不足时需要执行的命令。init直到进程完成后才继续工作。 
?powerfail:和powerwait类似,但init不等待进程完成。 
?powerworkwait:电源正常后执行。init暂停,直到进程结束。 
?powerfailnow:当便携机电池或外部UPS电池电量不足时执行。 
?ctrlaltdel:指定init在捕捉ctrl+alt+del组合键时执行的命令。 
?kbdrequest:把特别动作映射到特定的按键。Debian中的是alt+UpArrow。 
目前再看上面的文件是不是清晰了许多? 
更强大的sysvinit 
================ 
inittab 的主要功能是描述引导及正常操作时,应该在何种运行等级下启动什么程式,每个运行等级的具体项目完万能通常/etc/inittab来定义,但 Debian有一个更健壮的方案sysvinit,他被认为是init最强大的应用程式之一。Debian组织inittab的方式是把运行等级的大部分定义从inittab中移出来,移到一个脚本层次中去。惟一直接从inittab启动的程式只有getty,他用于虚拟设备上启动登录提示符,保留他因为他们需求特别处理,在inittab之外处理要困难得多。 
inittab来启动所有软件当然是可能的,但将所有设置写在同一个文件既不方便查看也不方便维护,所以文件里会加上这许多行: 
l0:0:wait:/etc/init.d/rc 0 
l1:1:wait:/etc/init.d/rc 1 
l2:2:wait:/etc/init.d/rc 2 
l3:3:wait:/etc/init.d/rc 3 
l4:4:wait:/etc/init.d/rc 4 
l5:5:wait:/etc/init.d/rc 5 
l6:6:wait:/etc/init.d/rc 6 
这些行实际决定了系统在各个运行等级下的行为。他们怎么做到的也许并不明显,但至少我们知道主要意思:首先每行都有个符号ID lx,lx表示runlevel x;其次,每行只在一个运行等级下激活,该运行等级对应着符号ID中的数字x。命令执行时,init停下来,直到进程结束。最后,每个命令行调用一个脚本 /etc/init.d/rc x,这里x代表当前运行等级的数字。显然各运行等级的具体任务在/etc/init.d/rc脚本中安排。 
Debian init设置的核心在/etc/init.d目录。该目录包含了启动或停止重要软件的脚本,为了简化操作,规定每个脚本都使用相同的一套参数??start或stop。个别软件包维护者为用户着想,往这些脚本中加了其他功能,但init不会去调用他们。 
举个例子,可调用:#/etc/init.d/apache start来启动Apache,调用:#/etc/init.d/apache stop来关闭他。 
作为一个用户工具,这是非常有用的,他让用户轻松启动和关闭Debian所带的复杂程式,不过在考虑怎么启动程式前,先检查/etc/init.d,看看是不是已有脚本能做这件事了。借助于这种机制,能按自己的需求来调整运行等级,/etc/init.d/rc能把系统引入所需的运行等级。 /etc/rcx.d是一组指向/etc/init.d的符号链接。进行运行等级时,rc在运行等级目录中按逻辑顺序处理每个脚本。首先前缀为K的每个文件都以参数stop(按字母和数字顺序)执行;其次,以S为前缀的每个脚本都以参数start(按字母和数字顺序)执行。 
了解了工作原理,下面试着自己来构造一个运行等级。我们使用运行等级5和和之相关的rc目录/etc/rc5.d。首先,看看该目录下的内容:找出每个符号链接所做的工作;查看文件,判断他来自哪个文件。经过仔细查看,找出启动无用程式的S打头的脚本,把他们删掉,在/etc/init.d中找出需要运行但未包括在内的脚本,例如假设你想在运行等级5下启动Samba,执行命令: 
ln -s /etc/init.d/samba /etc/rc5.d/S20samba 
看到这里是不是对init有了新的了解,那么来测试一下学习成果:关闭Debian默认安装时加载的gdm/xdm/kdm进程,让Debian启动到命令行终端而不是X。 
http://www.real-blog.com/linux-bsd-notes/49

以文字模式?? Ubuntu 
January 31, 2006 @ 11:00 pm ? Filed under Linux / BSD ?? 
如果想 Ubuntu 在每次??到 command prompt ,能?入以下指令: 
$echo “false” | sudo tee /etc/X11/default-display-manager 
?下次???,就?以指令模式??,如果想?回?? x window,能?入: 
$echo “/usr/bin/gdm” | sudo tee /etc/X11/default-display-manager 
P.S. 如果不是用 gdm 作?,以上指令需要根?你的?境作出更改,例如 kdm 或 xdm。

原创粉丝点击