用init启动服务
一旦你的启动载入程序完成了最开始的一步获得了内核并运行,init守护进程 �C 所有进程的父进程 --- 就被启动了,init启动正常操作系统必需的基于/etc/inittab配置文件中的条目的守护进程。
/etc/inittab文件
/etc/inittab配置文件的核心是下面的七行,它们定义了七个系统运行级别:
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
注意:同一时间系统只能处于一个运行级别。
这些行指定rc程序(/etc/rc.d/rc脚本)应该在系统运行级别改变时运行一次,init应该向rc程序传递一个单一的字符参数(组成运行级别的数字,0-6),然后rc程序就启动/etc/rc.d目录下对应运行级别子目录中的所有以S(意思是start)字母打头的脚本。
默认运行级别定义在/etc/inittab文件的initdefault行:
id:3:initdefault:
注意:使用runlevel命令查看当前的运行级别。
没有运行图形用户接口的Red Hat Linux服务器的默认运行级别是运行级别3,这就意味着当系统启动时init守护进程运行rc程序并向其传递一个参数3,然后rc程序运行/etc/rc.d/rc3.d目录下每一个以字母S打头的脚本,并传递参数start给这些脚本。
当系统管理员发出shutdown命令时,init守护进程再次运行rc程序,但是这一次rc程序运行/etc/rc.d/rc3.d目录下以字母K(意思是kill)打头的脚本,并传递参数stop给这些脚本。
在Red Hat上,你可以使用下面的命令列出当前运行级别子目录中的内容:
#ls -l /etc/rc.d/rc?.d | less
注意:这个命令中的问号标记指出可以用任何字符匹配,因此这个命令将匹配每个运行级别对应的子目录:rc0.d、rc1.d、rc2.d等。
start和kill脚本存储在这些子目录中,但是,不是真正的文件,它们仅仅是指向存储在/etc/rc.d/init.d目录中真实脚本文件的符号连接,因此,所有start和kill 开关脚本都存储在一个目录(/etc/rc.d/init.d)中,通过在运行级别子目录中创建或移除服务对应的符号连接来控制服务。
幸运的是,有软件工具可以帮助管理这些符号连接,稍后我们将解释如何使用这些工具,但是先让我们检验一下当守护进程死掉时,通过在/etc/inittab文件中使用respawn选项自动重启它的一个方法。
用init重新唤醒服务
你可以在/etc/inittab文件中添加一个可执行程序的名字,并使用respawn选项,这样当这个程序死掉时操作系统会自动重新启动它,当系统进入运行级别时init将启动守护进程,并监视守护进程确保它一直运行(如果它死掉的话就重启它),只要系统还停留在同一级别。
下面是一个/etc/initab条目使用respawn选项的例子:
sn:2345:respawn:/usr/local/scripts/start_snmpd > /dev/null
这个条目告诉init在2、3、4、5运行级别运行脚本/usr/local/scripts/start_snmpd,并将所有产生的输出发送到/dev/null设备(实际上输出内容就被丢掉了)。
注意,尽管我们已经在这里添加了一个脚本文件(/usr/local/scripts/start_snmpd),但它并不真实的snmpd可执行文件,如果这个脚本只是简单地运行snmpd然后就结束的话,init怎么知道监视哪个运行中的进程,在脚本/usr/local/scripts/start_snmpd运行完成后,init会认为程序已经死掉,它将尽职地再次运行这个脚本。
注意:当发生这种情况时,你会看到一个init报告的错误消息,它告诉你sn标识符(参考/etc/inittab文件的第一个字段)重新唤醒太快,init决定几分钟后放弃尝试。
因此确保respawn选项正确地工作,我们需要确保用于启动snmpd守护进程的脚本用snmpd守护进程替换它自身,这通过bash编程语句exec很容易实现,因此一个简单的/usr/local/scripts/start_snmpd bash脚本看起来就象这样:
#!/bin/bash
exec /usr/sbin/snmpd -s -P /var/run/snmpd -l /dev/null
脚本的第一行启动bash shell,第二行引起无论什么进程识别号或PID与这个bash shell结合在一起被snmpd守护进程替换掉(当这种情况发生时bash shell就消失了),这对于init运行脚本成为可能,找出分配给它的PID,然后监视这个PID,如果init看到这个PID消失了(意味着snmpd守护进程死掉了),它将再次运行这个脚本并监视新的PID,这都要感谢/etc/inittab文件中的respawn条目。
用chkconfig管理开关脚本符号连接
chkconfig程序通过使用init的仆人/etc/rc.d/rc脚本创建和移除符号连接,这些符号连接真实地启用或阻止服务在一个特定的运行级别自动运行,如前面提到的,所有系统运行级别下的所有符号连接实际上都指向存储在/etc/rc.d/init.d目录下的脚本(实际上,依据Linux标准基础[3],这个目录应该是/etc/init.d,但是在Red Hat上,这两个目录指向同样的文件[4])。
如果你想一个服务(叫做myservice)运行在运行级别2、3、4,这就意味着你想chkconfig在下面的运行级别子目录中创建三个符号连接:
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
这些符号连接应该以字母S打头,表明你想在这些运行级别中启动你的脚本,然后,chkconfig应该在剩下的/etc/rc.d/rc<运行级别>.d(如运行级别0、1、5、6)目录下创建以K(意思是kill)打头的符号连接。
为了告诉chkconfig你想让它对你的脚本做这些事,你可以在/etc/rc.d/init.d目录下的脚本文件中添加下面的行:
# chkconfig: 234 99 90
# description: myscript runs my daemon at runlevel 2, 3, or 4
然后你可以简单地运行chkconfig程序,它翻译这一行的意思为“用start选项创建符号连接在运行级别2、3、4上运行这个脚本,然后在其他运行级别用kill选项创建需这个脚本的符号连接。”
这个例子中的数字99和90是这个脚本启动和停止的优先级,当一个符号连接创建在运行级别子目录中后,同时也获取一个优先级数字,rc脚本用它来判断运行级别子目录下的脚本启动顺序(杀死顺序),在符号连接S后跟一个低优先级的数字意味着这个脚本应该比在同一目录下的其他脚本先运行,例如,启动网络的脚本/etc/rc.d/rc3.d/S10network在启动Heartbeat程序的/etc/rc.d/rc3.d/S34heartbeat脚本之前运行。
这个例子中第二行注释包括了一个(要求的)对这个脚本的描述,chkconfig命令首先移除所有旧的符号连接(代表旧的chkconfig条目),然后添加这个脚本(它保存在文件/etc/rc.d/init.d/myscript中):
chkconfig --del myscript
chkconfig --add myscript
注意:当使用chkconfig移除旧连接时,在使用--add选项前总先使用--del选项。
然后,chkconfig程序会给你的文件创建下面的符号连接:
/etc/rc.d/rc0.d/K90myscript
/etc/rc.d/rc1.d/K90myscript
/etc/rc.d/rc2.d/S99myscript
/etc/rc.d/rc3.d/S99myscript
/etc/rc.d/rc4.d/S99myscript
/etc/rc.d/rc5.d/K90myscript
/etc/rc.d/rc6.d/K90myscript
再说一次,这些符号连接仅仅指向存储在/etc/init.d目录下的真实文件(从现在开始,我将使用LSB目录名/etc/init.d替换Red Hat系统上原始的/etc/rc.d/init.d目录),如果你需要修改脚本启动或停止你的服务,你只需要修改一个位置下的文件:/etc/init.d目录。
你可以使用下面的命令查看所有的符号连接(在你运行chkconfig命令添加了它们后):
#find /etc -name ‘*myscript’ -print
你也可以用下面的命令查看所有脚本的一个报告:
#chkconfig --list
用ntsysv管理开关脚本符号连接
ntsysv命令依赖这些相同的chkconfig注释行,管理在/etc/rc.d/init.d目录下每个运行级别的脚本符号连接启动和停止脚本。
正常情况下,ntsysv仅管理系统当前运行级别(不是非常有用的),因此你可能会想要它管理所有运行级别,输入下面的命令就可实现你的想法:
#ntsysv --level 0123456
将显示一个/etc/rc.d/init.d目录下所有脚本的列表,通过在列表中的脚本名后添加一个星号(*)并选择“OK”,这是告诉ntsysv程序创建所有的符号连接,与你运行chkconfig --add <脚本名>命令非常类似,如果你在脚本名后移除了星号(*),符号连接就被移除了,与你运行chkconfig --del <脚本名>命令一样。
注意:ckconfig和ntsysv命令不启动或停止守护进程(两个命令实际上都不运行脚本),它们仅仅创建或移除符号连接,系统下次进入或离开一个运行级别时才产生影响(或重启时),要启动或停止脚本,你可以输入命令service <脚本名> start 或service <脚本名> stop,这里的<脚本名>是/etc/init.d目录下文件的名字。
移除你不需要的服务
对于每一个你不需要的脚本(查看下一小节的描述),你可以通过下面的步骤禁用或移除服务:
杀死当前正在运行的守护进程(当你完成时你可以跳过这以步直接重启系统):
#/etc/init.d/<脚本名> stop
或在Red Hat系统上,下面的命令也可以:
#service <脚本名> stop
用下面的命令移除前面chkconfig定义的各运行级别下脚本的符号连接:
#chkconfig --del <脚本名>
或
#ntsysv --level 0123456
然后,使用ntsysv工具,移除每个脚本名后的*(星号),让它们在系统启动时不运行。
注意:snmpd守护进程也支持-f参数,它与exec语句完成相同的事情,请查看snmpd的man手册页获取更多的信息。
查看http://www.linuxbase.org/spec获取LSB最新版本。
因为在Red Hat系统发行版上/etc/init.d是一个到/etc/rc.d/init.d的符号连接