• 一个完整的upstart脚本分析


    基本概念可以了解

    http://www.mike.org.cn/articles/understand-upstart/

    http://blog.fens.me/linux-upstart/

    http://zh.wikipedia.org/wiki/Upstart

    • 传统的linux采用sysvinit daemon,缺点是无法很好地处理现代硬件,如热插拔设备、USB硬盘或山村、网络文件系统等。
    • Upstart是一个基于事件的初始化守护进程,用于替代传统的init。 — 几个类Unix计算机操作系统启动时用于执行任务的方法。它是由Canonical公司前雇员Scott James Remnant所写。

      Upstart是异步工作的 — 它在系统运行时监督服务,并且在开关机时启动和关闭任务和服务。

    • Sysvinit daemon 是一个基于运行级别的初始化程序,它使用了运行级别(如单用户、多用户等)并通过从 /etc/rc?.d 目录到 /etc/init.d 目录的初始化脚本的链接来启动与终止系统服务

    重要的概念

    • event: 事件, 是指系统状态的一种改变,这种改变会被通知给init进程。举例来说,boot loader会触发startup事件,系统进入runlevel 2的时候会触发runlevel 2事件,某个文件系统被挂载时会触发path-mounted事件, USB设备的插拔也都会产生相应的事件。这些时间会被通知给init进程,然后init进程来决定系统如何处理这些事件。
    • job: 作业,一项作业是init进程读入的一系列指令。你可以使用initctl start或initctl stop命令来开始或停止某项作业,这是调用作业的一种方式。另一种方式是当系统被告知发生什么事件event后,运行该事件所对应的作业。可用sudo initctl list命令列出所有系统作业的运行状态。
    • task: 任务, a job that performs its work and returns to a waiting state when it is done. 中文是一种完成指定工作后进去等待状态的作业。
    • service: 服务,a job that does not normally terminate by itself. 举个例子来说, gettys 是以服务来实现的。 init进程监视所有服务,并在服务失败的时候重启服务。

    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

    注:

    • script和exec是主启动程序需要执行的命令行,二者不能同时出现,但script内可以嵌套exec命令。
    • 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
  • 相关阅读:
    3.27 课堂 笔记
    第四周 4-2
    3-26
    Java EE期末项目
    条件查询、SQL、JPQL、HQL比较
    J2EE 第八周(04.23-04.29)
    J2EE 第七周(04.16-04.22)
    J2EE 第六周(04.09-04.15)
    J2EE 第五周(04.02-04.08)
    J2EE 第四周(03.26-04.01)
  • 原文地址:https://www.cnblogs.com/silenceli/p/3546425.html
Copyright © 2020-2023  润新知