查看: 142|回复: 0

[讨论] 跟我学OpenWrt7-- 重建巴别塔的UCI之procd init脚本

[复制链接]

39

主题

3

好友

4031

积分

QQ游客

  • TA的每日心情
    开心
    2014-1-27 10:34
  • 签到天数: 67 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2017-7-14 09:57:05 |显示全部楼层
    init脚步放在路由器的/etc/init.d目录下。
    先看一下有哪些用法。随便找一个脚步,不指定参数运行,就可以看到help信息了:
    1. <font size="3">root@OpenWrt:/etc/init.d# ./led
    2. Syntax: ./led [command]

    3. Available commands:
    4.         start        Start the service
    5.         stop        Stop the service
    6.         restart        Restart the service
    7.         reload        Reload configuration files (or restart if that fails)
    8.         enable        Enable service autostart
    9.         disable        Disable service autostart</font>
    复制代码
    在本文接下来的部分,会将脚步运行的第一个参数称为action。
    当action为enable时,脚步会在rc.d目录下新建一个符号链接,链接到这个init脚步,这样路由器在开机的时候,就会以action为boot来运行这个init脚步了。
    当我们打开一个init脚步时,都会看到第一行的shebang为
    1. <font size="3">#!/bin/sh /etc/rc.common</font>
    复制代码
    所以,当我们运行例如/etc/init.d/led时,实际的运行情况为:
    1. <font size="3">/bin/sh /etc/rc.common /etc/init.d/led</font>
    复制代码
        通过设置shebang,OpenWrt就像是构建了一个框架,当我们写脚步时,只需要知道某个函数在什么时候会被调用,例如当action为start时,start函数就会被调用了。如果你需要增加自己的action的话,只需要给变量EXTRA_COMMANDS赋值,多个action以空格分开。
            接下来来拜读一下rc.common。
    1. <font size="3">initscript=$1   
    2. action=${2:-help}
    3. shift 2</font>
    复制代码
    注意到,$1是脚步路径,当我们运行/etc/init.d/led时,$1就是“/etc/init.d/led"。action的赋值很有意思,用了 shell script的默认值语法,当$2为空时,action就是help。所以当我们不带参数运行脚步时,就会打印help信息。最后把参数往前推了两个,这样$3 => $1, $4 => $1 ....
    现在OpenWrt已经引入了procd机制,写procd脚步的时候会有点不一样。首先需要在init脚步中赋值USE_PROCD为1。
    1. <font size="3">USE_PROCD=1</font>
    复制代码
    当init脚步以action为start运行时,就不再是调用start()函数 ,而是start_service()函数。在start_service()函数中,经典的行为为:读取uci config文件,生成对应 配置文件,使用procd.sh的接口注册daemon进程。因为生成的配置文件没有必要保存到flash,一般都会放在内存文件系统中,并在daemon进程运行时将conf路径指定到该内存文件系统路径下。
    以samba为例:
    1. <font size="3">start_service() {
    2.         init_config

    3.         procd_open_instance
    4.         procd_set_param command /usr/sbin/smbd -F
    5.         procd_set_param respawn
    6.         procd_close_instance

    7.         procd_open_instance
    8.         procd_set_param command /usr/sbin/nmbd -F
    9.         procd_set_param respawn
    10.         procd_close_instance
    11. }</font>
    复制代码
    通过指定respawn参数,就可以让daemon进程被杀掉时会被自动重启起来了。
    procd提供了很多很方便的特性。例如如果你想要监控你的uci config文件的话,只需要实现service_triggers函数:
    1. <font size="3">service_triggers()
    2. {
    3.         procd_add_reload_trigger "uci-file-name"
    4. }</font>
    复制代码
    当你注册监控的uci配置文件的md5发生变化时,就会调用脚步的reload_service函数,你也就可以在reload_service里重新读取配置文件,并根据需要重启daemon进程。
    至于具体的实现方式,其实是调用了封装起来的ubus接口,通过ubus接口,向procd发送一些消息。ubus我们后面再学习。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /5 下一条

    手机版|爱板网 |网站地图  

    GMT+8, 2017-9-20 04:48 , Processed in 0.118950 second(s), 9 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部