upstart : Ubuntu's event-based init daemon


Ubuntu-8.04系统启动过程

upstart包提供/sbin/init
upstart-compat-sysv包提供与sysv兼容的系统启动文件,包括/etc/event.d/{rcS,rc[0-6],rc-default,rc-sulogin},以及halt、reboot、shutdown等命令。

ubuntu-8.04中,系统在执行initrd中/init脚本的最后一步,执行
exec run-init ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console 2>&1其中run-init是由klibc-utils包(klibc-1.5.7/usr/kinit/run-init/run-init.c)提供的。

run-init做完必要的设置后,execv("/sbin/init", …),将控制交给upstart,/sbin/init的PID为1。

upstart的/sbin/init会读取/etc/event.d/目录下的配置文件,并监控该目录的变化,还会emit一个STARTUP_EVENT,之后就进入一个循环。
/etc/event.d/目录下的rcS脚本的开头是"start on startup",STARTUP_EVENT信号的发出使得该脚本响应,其内容如下:
start on startup
stop on runlevel
console output
script
        runlevel –set S >/dev/null || true

        PREVLEVEL=N
        RUNLEVEL=S
        export PREVLEVEL RUNLEVEL

        exec /etc/init.d/rcS
end script

可以看出,随后/etc/init.d/rcS脚本将继续执行,它将依次执行/etc/rcS.d/下的启动脚本。

/etc/init.d/rcS执行完毕后,/etc/event.d/rcS也结束,随后/etc/event.d/rc-default将执行(其配置为start on stopped rcS),其内容如下:
start on stopped rcS
script
        runlevel –reboot || true

        if grep -q -w – "-s|single|S" /proc/cmdline; then
            telinit S
        elif [ -r /etc/inittab ]; then
            RL="$(sed -n -e "/^id:[0-9]:initdefault:/{s/^id://;s/:.//;p}" /etc/inittab || true)"
            if [ -n "$RL" ]; then
                telinit $RL
            else
                telinit 2
            fi
        else
            telinit 2
        fi
end script

它将进入runlevel 2,并执行/etc/rc2.d/下的脚本。

至此,系统启动过程全部完成!



=================================================================================
在event.d/下添加一个新的event响应


ref:http://www.linux.com/feature/125977
$ cat /etc/event.d/myjob
start on hithere
script
echo "Hi there, here I am!" > /tmp/myjob.out
date >> /tmp/myjob.out
end script
$ sudo initctl emit hithere
hithere
myjob (start) waiting
myjob (start) starting
myjob (start) pre-start
myjob (start) spawned, process 6064
myjob (start) post-start, (main) process 6064
myjob (start) running, process 6064
myjob (stop) running
myjob (stop) stopping
myjob (stop) killed
myjob (stop) post-stop
myjob (stop) waiting

$ cat /tmp/myjob.out
Hi there, here I am!
Sat Jul 7 20:19:13 PDT 2007









end