zoukankan      html  css  js  c++  java
  • 一个完整的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
  • 相关阅读:
    Palindrome Partitioning
    triangle
    Populating Next Right Pointers in Each Node(I and II)
    分苹果(网易)
    Flatten Binary Tree to Linked List
    Construct Binary Tree from Inorder and Postorder Traversal(根据中序遍历和后序遍历构建二叉树)
    iOS系统navigationBar背景色,文字颜色处理
    登录,注销
    ios 文字上下滚动效果Demo
    经常崩溃就是数组字典引起的
  • 原文地址:https://www.cnblogs.com/silenceli/p/3546425.html
Copyright © 2011-2022 走看看