基本概念可以了解
http://www.mike.org.cn/articles/understand-upstart/
http://blog.fens.me/linux-upstart/
http://zh.wikipedia.org/wiki/Upstart
Upstart是一个基于事件的初始化守护进程,用于替代传统的init。 — 几个类Unix计算机操作系统启动时用于执行任务的方法。它是由Canonical公司前雇员Scott James Remnant所写。
Upstart是异步工作的 — 它在系统运行时监督服务,并且在开关机时启动和关闭任务和服务。
重要的概念
http://blog.csdn.net/vecri/article/details/4735601
/etc/event.d目录下是所有init进程读取的job(作业)定义。该目录下的每个文件都定义了一个job(作业),和对应该作业的事件。这和windows下的消息机制有些类似。在这里新建一个文件myjob: $cat /etc/event.d/myjob start on hithere script echo "Hi there, here I am!" > /tmp/myjob.out date >> /tmp/myjob.out end script 这个文件定义了一个作业,在作业在收到hithere事件后触发。该作业运行时将"Hi there, here I am!"和系统时间打印到/tmp/myjob.out
一个例子,但这个例子对于ubuntu12.04稍有不同,在12.04版本中,没有/etc/event.d/目录,相应的目录变为/etc/init,而且目录下的文件名必须以.conf结尾,否则不能执行。
upstart本身使用initctl (start stop restart reload list status等都是initctl 软链接而成),比如启动或者关闭程序,使用
initctl start squid3 or start squid3
initctl stop squid3 or stop squid3
后面的job名称是/etc/init目录下xxxx.conf文件去除.conf结尾后的名称。
/etc/init.d/xxxx是按照sysvinit遗留下来的旧有模式
我理解的upstart的核心是事件驱动,由事件(event)触发。
手动触发:
initctl emit hithere直接触发
而系统对于某些动作会触发相应的事件
比如:
boot loader会触发startup事件,系统进入runlevel 2的时候会触发runlevel 2事件
具体的例子及配置文件的语法格式
description "HTTP proxy-cache" //job描述 author "Chuck Short <zulcss@ubuntu.com>" //job作者 # The second "or" condition is to start squid in case it failed to start # because no real interface was there. start on runlevel [2345] //在2345运行级别启动 stop on runlevel [!2345] //非2345运行级别关闭 respawn //意外关闭重启服务 normal exit 0 //列出normal exit的代码或者信号,正常退出不重启 env CONFIG="/etc/squid3/squid.conf" //变量 env SQUID_ARGS="-YC" //变量 pre-start script //指定进程运行之前执行的命令,此处为脚本 if [ -f /etc/default/squid3 ]; then . /etc/default/squid3 fi find_cache_dir () { w=" " # space tab res=`sed -ne ‘ s/^‘$1‘[‘"$w"‘]\+[^‘"$w"‘]\+[‘"$w"‘]\+\([^‘"$w"‘]\+\).*$/\1/p; t end; d; :end q‘ < $CONFIG` [ -n "$res" ] || res=$2 echo "$res" } find_cache_type () { w=" " # space tab res=`sed -ne ‘ s/^‘$1‘[‘"$w"‘]\+\([^‘"$w"‘]\+\).*$/\1/p; t end; d; :end q‘ < $CONFIG` [ -n "$res" ] || res=$2 echo "$res" } cache_dir=`find_cache_dir cache_dir` cache_type=`find_cache_type cache_dir` if [ "$cache_type" = "coss" -a -d "$cache_dir" -a ! -f "$cache_dir/stripe" ] || [ "$cache_type" != "coss" -a -d "$cache_dir" -a ! -d "$cache_dir/00" ] then /usr/sbin/squid3 $SQUID_ARGS -z -f $CONFIG fi end script //脚本结束 script if [ -f /etc/default/squid3 ]; then . /etc/default/squid3 fi umask 027 //设定umask值 ulimit -n 65535 // exec /usr/sbin/squid3 -N $SQUID_ARGS -f $CONFIG end script
注:
exec:
在bash下输入man exec,找到exec命令解释处,可以看到有”No new process is created.”这样的解释,这就是说exec命令不产生新的子进程。那么exec与source的区别是什么呢?
exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。
1. 系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。
一个进程主要包括以下几个方面的内容:
(1)一个可以执行的程序
(2) 与进程相关联的全部数据(包括变量,内存,缓冲区)
(3)程序上下文(程序计数器PC,保存程序执行的位置)
如何自己编写一个upstart程序
如手动编译nginx,编写nginx启动脚本
description "nginx_daemon" author "binhoul" start on runlevel [2345] stop on runlevel [!2345] respawn normal exit 0 umask 022 env DAEMON="/app/web/nginx/sbin/nginx" exec $DAEMON
上面的脚本启动没有问题,但停止时无法出现错误:
stop: Unknown instance:
经过查找需要添加一行,或者看nginx网站上给出的启动脚本例子
# nginx description "nginx http daemon" author "George Shammas <georgyo@gmail.com>" start on (filesystem and net-device-up IFACE=lo) stop on runlevel [!2345] env DAEMON=/usr/sbin/nginx env PID=/var/run/nginx.pid expect fork respawn respawn limit 10 5 #oom never pre-start script $DAEMON -t if [ $? -ne 0 ] then exit $? fi end script exec $DAEMON
# nginx description "nginx http daemon" author "George Shammas <georgyo@gmail.com>" start on (filesystem and net-device-up IFACE=lo) stop on runlevel [!2345] env DAEMON=/usr/sbin/nginx env PID=/var/run/nginx.pid expect fork respawn respawn limit 10 5 #oom never pre-start script $DAEMON -t if [ $? -ne 0 ] then exit $? fi end script exec $DAEMON
链接: http://wiki.nginx.org/Upstart
具体原因分析:
http://upstart.ubuntu.com/cookbook/#expect-fork
原文:http://www.cnblogs.com/silenceli/p/3546425.html