最近在一个小系统上,启动脚本跑完以后runlevel总是得到unknown的结果,后来把启动脚本在inittab当中的位置从runlevel 3调整到sysinit以后问题就解决了,于是就下定决心查一下到底怎么回事。
其实当kernel启动完成以后,系统就转入了init的控制。它通过读取inittab当中的标号顺序的执行一些脚本以便完成系统启动的剩余工作,其顺序如下:
1、读取inittab的配置,将内部运行级别设置为'#',认为是SYSINIT
2、检查并运行级别是#的脚本,一般情况下是sysinit这一级的脚本,若有,执行以后在utmp当中写入sysinit的记录(通过utmpdump /var/run/utmp可以看到)
3、开始执行从SYSINIT->BOOT的转移,向utmp当中写入reboot的记录,设置运行级别为'*'
4、执行inittab配置当中的运行级别为'*'的脚本,这一般是boot一级的脚本,很多系统里面是没有的
5、开始执行从BOOT->default initlevel的转移,向utmp当中写入runlevel的记录,设置运行级别为inittab内设置的运行级
6、执行default initlevel当中所有带有wait标志的脚本,并在执行完毕后向utmp当中写入记录
7、执行default initlevel剩余的脚本、命令,并在执行后向utmp中记录
8、等待信号的到来或者运行级别的改变,执行改变运行级的动作并进行记录
从这个过程可以知道所有的脚本在执行前init都会在utmp当中进行记录,除了sysinit这一级的脚本,它们是执行完毕以后才写入utmp的。原因在于系统在启动后文件系统通常处于read only的状态,此时执行utmp的写操作是不会成功的,所以通常sysinit会要包含将文件系统转为rw模式的命令。
因此,我在小系统当中把所有的设置集中到一个脚本当中后,放置于runleve 3执行,就造成了没有reboot和runlevel的记录,也就导致了执行runlevel时得到unknown的结果。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=1039385