upstart an event-based replacement for the /sbin/init

来源:互联网 发布:windows最长文件名 编辑:程序博客网 时间:2024/05/18 20:11

本文主要摘自“Upstart Intro,Cookbook, best practice” 。


http://upstart.ubuntu.com/cookbook/

upstart的配置文件在 /etc/init目录下,以.conf结尾。

1. 最简单的conf 文件


# this is an abstract job containing only a comment
author "foo"
description "this is an abstract job"


2. 创建一个事件

# initctl emit <event>

signal, 不阻塞事件

# initctl emit --no-wait mysignal

method, 阻塞事件

# initctl emit mymethod

hook, 阻塞事件,区别不详


Run Level

  • 0 : System halt.
  • 1 : Single-User mode.
  • 2 : Graphical multi-user plus networking (DEFAULT)
  • 3 : Same as "2", but not used.
  • 4 : Same as "2", but not used.
  • 5 : Same as "2", but not used.
  • 6 : System reboot.
use "runlevel" to show the run level.

$runlevel
N 2

change the default runlevel

change the variable DEFAULT_RUNLEVEL in /etc/init/rc-sysinit.conf.


change the runlevel immediately

reboot

shutdown

telinit


Startup Process


Note that in this section we assume the default runlevel is "2". See Changing the Default Runlevel for further details.

  1. Upstart performs its internal initialization.

  2. Upstart itself emits a single event called startup(7).

    This event triggers the rest of the system to initialize [29].

  3. init(8) runs a small number of jobs which specify the startup(7) event in their start on condition.

    The most notable of these is the mountall job which mounts your disks and filesystems.

  4. The mountall(8) job in turn emits a number of events.

    These include local-filesystems(7), virtual-filesystems(7) and all-swaps(7). See upstart-events(7) for further details.

  5. The virtual-filesystems(7) event causes the udev job to start.

  6. The udev job causes the upstart-udev-bridge job to start.

  7. The upstart-udev-bridge job will at some point emit the "net-device-up IFACE=lo" event signifying the local network (for example, 127.0.0.0for IPv4) is available.

  8. After the last filesystem is mounted, mountall(8) will emit the filesytem event.

  9. Since the start on condition for the rc-sysinit job is:

    start on filesystem and net-device-up IFACE=lo

    Upstart will then start the rc-sysinit job.

  10. The rc-sysinit job calls the telinit command, passing it the runlevel to move to:

    telinit 2
  11. The telinit command emits the runlevel(7) event as:

    runlevel RUNLEVEL=2 PREVLEVEL=N

    Note that this is all the telinit command does – it runs no commands itself to change runlevel!

    See Runlevels for further information on runlevels.

  12. The runlevel(7) event causes many other Upstart jobs to start, including /etc/init/rc.conf which starts the legacy SystemV init system.

最后通过/etc/init/rc.conf 来启动SysV/类似的启动程序,比如,如果runlevel是2, 则执行/etc/rc2.d中的脚本。


shutdown process

The following steps will now be taken:

  1. Assuming the current runlevel is "2", either of the actions above will cause Upstart to emit the runlevel(7) event like this:

    runlevel RUNLEVEL=0 PREVLEVEL=2
  2. The job /etc/init/rc.conf will be run.

    This job calls /etc/init.d/rc passing it the new runlevel ("0").

  3. The SystemV system will then invoke the necessary scripts in /etc/rc0.d/ to stop SystemV services.

  4. One of the scripts run is /etc/init.d/sendsigs.

    This script will kill any remaining processes not already stopped (including Upstart processes).


Reboot Process

The following will steps will now be taken:

  1. Assuming the current runlevel is "2", whichever command is run above will cause Upstart to emit the runlevel(7) event like this:

    runlevel RUNLEVEL=6 PREVLEVEL=2
  2. The job /etc/init/rc.conf will be run.

    This job calls /etc/init.d/rc passing it the new runlevel ("6").

  3. The SystemV system will then invoke the necessary scripts in /etc/rc6.d/ to stop SystemV services.

  4. One of the scripts run is /etc/init.d/sendsigs.

    This script will kill any remaining processes not already stopped (including Upstart processes).



SysV init compatible

为了和之前的sysv init兼容,upstart特意保留了sysv init的配置和运行的方式。
在前面的startup process中也可以看到,最后还是运行了sysv init的脚本。


/etc/init.d/  这个目录下保存这启动服务的脚本文件
/etc/rcX.d  目录下保存了相应的runlevel X 的启动文件。 其实都是一些链接文件,链接到/etc/init.d/下的某个脚本。


在ubuntu中可以安装sysv-rc-conf工具来管理启动顺序。

或者用update-rc.d来配置,下面是一个简单的例子,添加一个自己定义的服务。

先有个脚本文件
# cat /etc/init.d/foo
#!/bin/bash

# start the service foo
start() {
    #initlog -c "echo -n Starting foo server: "
    echo "foo start"
    touch /var/foo
    #success $"foo server startup"
    echo
}

# stop the service foo
stop() {
    #initlog -c "echo -n Stopping foo server: "
        echo "foo stop"
        rm -f /var/foo
    echo
}

# main logic
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status foo
        ;;
    restart|reload|condrestart)
        stop
        start
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart}"
        exit 1
esac
exit 0


这个脚本写好后,就可以用service来启动,停止服务了。
# service foo start
foo start

# service foo restart
foo stop

foo start

好了,现在要用update-rc.d 来设置 runlevel,自动启动
# update-rc.d foo defaults
update-rc.d: warning: /etc/init.d/foo missing LSB information
update-rc.d: see <http://wiki.debian.org/LSBInitScripts>
 Adding system startup for /etc/init.d/foo ...
   /etc/rc0.d/K20foo -> ../init.d/foo
   /etc/rc1.d/K20foo -> ../init.d/foo
   /etc/rc6.d/K20foo -> ../init.d/foo
   /etc/rc2.d/S20foo -> ../init.d/foo
   /etc/rc3.d/S20foo -> ../init.d/foo
   /etc/rc4.d/S20foo -> ../init.d/foo
   /etc/rc5.d/S20foo -> ../init.d/foo

update-rc.d 更详细的使用方法
1、设置指定启动顺序、指定运行级别的启动项:
update-rc.d <service> start <order> <runlevels>
2、设置在指定运行级中,按指定顺序停止:
update-rc.d <service> stop <order> <runlevels>
3、从所有的运行级别中删除指定的启动项:
update-rc.d -f <script-name> remove


删除foo的所有启动选项
update-rc.d -f foo  remove

指定运行的顺序
update-rc.d foo start 21 2 3 4 5 . stop 21 0 1 6 .

指定了在 runlevel  2,3,4,5 以优先级21启动
在runlevel 0,1,6以优先级21 关闭。


恩 基本差不多了。

在RHEL上用的是chkconfig命令。
http://www.cyberciti.biz/faq/rhel5-update-rcd-command/