1.传统的启动方式
init进程在启动时会调用/etc/rc${RUNLEVEL}.d文件夹下的脚本,这些脚本是/etc/init.d/下脚本的软链接,runlevel包括0-9,S,S是single模式的runlevel(想起上次服务器宕掉,提示init进程segment fault,而据负责维护的同事说内核没有问题,可能是/etc/rcS.d/下的服务有问题?真是这样的话可以disable后启动看看有没有问题),软连接文件名是这样的[S|K][NN]${name},S表示服务enabled,K表示disabled,NN是0-99的数字,数字可以重复,但在系统下次升级时会根据依赖关系重新整理一次。update-rc.d命令正是通过建立软链接来安装删除upstart script的命令。
每个服务启动脚本(upstart script)都符合lsb规范(linux二进制程序与运行程序接口规范),需要加上lsb头,lsb头说明了在哪些runlevel是enabled,哪些disabled的,以及服务的依赖关系。删除一个S开头的软链接并不意味着linux以后开机就不启动这个服务了,升级之后仍然可能又安装了对应S软链接,应该通过update-rc.d命令的disable选项建立K软链接可以达到效果。
该命令有如下选项:remove,defaults,start|stop,disable|enable。default安装的服务是2,3,4,5 enable,0,1,6 disable,后面指定一个整数是K和S带的整数,如果指定两个证书,则分别是S和K带的整数,推荐K带的整数为100-S带的整数。该命令还有两个选项-n,-f,man page的说明和例子很丰富。
2.ubuntu下upstart流程
顺着update-rc.d命令的man page,我们注意到insserv,我们得知update-rc.d这个命令在debian 6之后已经obsolute(这是system-v style的),推荐可以使用insserv命令,该命令查看/etc/insserv.conf,/etc/insserv.conf.d,/etc/insserv/overrides下的LSB系统设施(LSB System Facilities)。
基本命令initctl和chkconfig相似,list列出所有的状态,status可以列出单个服务的状态,我们注意到其中包括的服务比/etc/rc.${RUNLEVEL}多很多,从initctl的man page看其服务配置在/etc/init目录下设置,/etc/init/rc.conf清楚地表明是"System V runlevel compatibility",并执行exec /etc/init.d/rc $RUNLEVEL,现在我们可以看出/etc/init和/etc/init.d的差别了。差别就是/etc/init.d是system v style的upstart scripts目录,并按runlevel存放,/etc/init是ubuntu下的upstart脚本规范,到lucid(10.04 LTS)为止,ubuntu一直在往这个规范迁移,system v style的服务只是该规范下的一个服务(可以看看service rc status)。/etc/init下的配置文件相对比/etc/init.d中的脚本要简洁。
再看service脚本,可以看到它优先查看/etc/init文件夹,然后才查看/etc/init.d的脚本。
if [ -r "/etc/init/${SERVICE}.conf" ]; then
# Upstart configuration exists for this job
case "${ACTION}" in
start|stop|status|reload)
# Action is a valid upstart action
exec ${ACTION} ${SERVICE} ${OPTIONS}
;;
restart)
# Map restart to the usual sysvinit behavior.
stop ${SERVICE} ${OPTIONS} || :
exec start ${SERVICE} ${OPTIONS}
;;
force-reload)
# Upstart just uses reload for force-reload
exec reload ${SERVICE} ${OPTIONS}
;;
esac
fi
可见upstart job不是调用脚本,而是使用start,stop,status,reload这些二进制程序。--full-restart和force-reload这两个选项倒是我之前没有注意到的。
另外Ubuntu上chkconfig命令很强也很方便,可以列出服务的状态,也可能方便enable,disable。
附: Fedora upstart流程
在我的Fedora 17(BeefyMiracle)上,也支持system v style upstart scripts,但也有自己的规范,并且system v style优先。其自己的service文件在/usr/lib/systemd/system/下,如sshd.service,似乎比ubuntu更易读,使用systemctl调用,并且在标准错误上会输出Redirecting to /bin/systemctl ${OPTIONS} ${SERVICE}.service(只要标准错误是字符设备)。
如果upstart script在/etc/init.d下,Fedora下既没有update-rc.d也没有insserv,应该用chkconfig。
如果在/usr/lib/systemd/system/下,由于Fedora下chkconfig也只对system v style的服务有效,做法是还使用systemctl,如systemctl enable/disable iptables.service。
待续:
/lib/lsb/init-functions (Fedora /usr/lib/functions)
参考:
man update-rc.d
man insserv
man initctl
http://askubuntu.com/questions/5039/what-is-the-difference-between-etc-init-and-etc-init-d
man service