一、procd简介

  • 通常的嵌入式系统均有一个守护进程,该守护进程监控系统进程的状态,如果某些系统进程异常退出,将再次启动这些进程。procd 就是这样一个进程,它是使用C语言编写 的,一个新的OpenWrt进程管理服务。
  • 它通过init脚本来将进程信息加入到procd的数据库中来管理进程启动,这是通过ubus总线调用来实现,可以防止进程的重复启动调用。

procd的进程管理功能主要包含3个部分

  • ①reload_config:检查配置文件是否发生变化,如果有变化则通知procd进程。
  • ②procd守护进程:接收使用者的请求,增加或删除所管理的进程,并监控进程的状态,如果发现进程退出,则再次启动进程。
  • ③procd.sh:提供函数封装procd提供系统总线方法,调用者可以非常便利的使用procd提供的方法。

二、reload_config

  • 工作原理:当在命令行执行reload_config时,会对系统中的所有配置文件生成MD5值,并且和应用程序使用的配置文件MD5值进行比较(对/var/run/config.md5文件进行比较),如果不同就通过ubus总线通知procd配置文件发生改变,如果应用程序在启动时,向procd注册了配置触发服务,那就将调用 reload函数重新读取配置文件,通常是进程退出再启动。如果配置文件没有改变将不会调用,这将节省系统CPU资源。
  • 两点注意事项
    • 注意:是配置文件的真实配置内容发生改变之后才会调用,如果增加空行和注释并不会引起配置文件的实质内容改变。
    • 系统启动时,会执行reload_config将初始配置文件摘要值保存为/var/run/config.md5文件中,下次再执行reload_config就是与这文件里面的MD5值进行比较的。

工作原理详解:

  • 我们以防火墙的配置文件发生改变为例来说明。
  • ①当手动执行reload_config时,首先将目录/etc/config目录下的所有文件通过“uci show”命令输出其配置到“/var/run/config.check” 目录下,这个命令将过滤配置文件增加空行和注释的情况。
  • ②初始系统启动时的配置文件摘要值保存在文件/var/run/config.md5 中,我们通过 “md5sum –c”命令来从文件中读取MD5值并验证是否和现有的配置文件MD5是否一致, 如果不一致则就调用ubus方法通知procd进程配置文件发生改变。
  • ③当procd知道配置文件发生改变后,procd就会调用/etc/init.d/firewall reload来处理配置文件改变,其他配置文件没有改变的进程,系统将不会花费资源进行处理。
  • ④最后将现在运行中的配置文件MD5值保存到/var/run/config.md5中。

三、procd进程

  • procd进程向ubus总线注册了service和system对象。

service对象

  • 下表是serveis对象提供的方法,主要有3部分功能:进程的管理、文件触发器(trigger)、配置验证服务(validate)。
方 法 含 义
set 进程如果存在,则修改已经注册的进程信息,如果不存在则增加,最后启动注册的进程
add 增加注册的进程
list 如果不带参数,则列出所有注册的进程和其信息
delete 删除指定服务进程,在结束进程时调用,例如停止防火墙会进行以下调用: ubus call service delete ‘{“name”:”firewall”}’
event 发出事件,例如 reload_config 就使用该方法来通知配置发生改变
validate 查看所有的验证服务
  • set方法:

    • 上面的3个功能都是通过set方法增加到procd保存的内存数据库中。数据库以服务名称作为其主键。
    • 共有5个参数:第一个参数为被管理的服务进程名称;第二个参数为启动脚本绝对路径;第三个参数为进程实例信息,例如可执行程序路径和进程的启动参数等;第四个参数为触发器;第五个参数为配置验证项(前3个参数是必须要传递的,后面两个参数可选)。
  • delete方法:
    • 在删除时使用 delete 方法。
    • 共有两个参数:第一个参数为服务名称,第二个参数为进程实例名称,可以不指定实例名称。
  • list方法:
    • 查询时使用 list 方法。
    • 共有两个参数:第一个参数为服务名称,第二个参数是布尔值,表示是否输出其详细信息,默认为不输出详细信息(该方法可以不带任何参数,表示查询所有注册的服务信息)。

  • 演示案例如下:
  • ①增加进程:如果hello进程需要procd来管理,那么我们使用ubus命令将hello进程加入的procd的内存数据库中。下面命令传递了4个参数,第一个参数设置被管理的服务进程名称为“hello”。第二个参数设置启动脚本绝对路径“/etc/init.d/hello”。第三个参数设置了进程实例信息,实例的启动命令为“/bin/hello”,启动参数为“-f -c bjbook.net”,并设置进程意外退出的重生参数(respawn)为默认值。第四个参数为触发器,收到文件“hello” 的“config.change”消息后执行脚本“/ect/init.d/hello”并传递“reload”参数。
ubus call service add '{"name":"hello",
"script":"/etc/init.d/hello",
"instances":{"instance1":{ "command":["/bin/hello","-f","-c","bjbook.net"],"respawn":[ ] }},
"triggers": [ ["config.change",["if", ["eq","package", "hello" ], ["run_script","/ect/init.d/hello", "reload" ] ] ] ]
}'
  • ②删除进程:参数传递进程的名字即可。
ubus call service delete '{"name":"hello"}'
  • ③查看注册的进程信息:也可以不指定名称,将输出所有的管理列表。“verbose”为真,表示输出其详细信息。
ubus call service list '{"name":"hello","verbose":true}'
  • ④发送事件:第一个参数含义为事件类型,现在只支持“config.change”事件消息; 第二个参数表示文件“hello”,是指在目录“/etc/config”下的文件。在配置文件发生改变 时调用。通知 procd 进程配置文件 hello 发生了改变。
ubus call service event '{"type":"config.change","data":{"package":"hello"}}'

system对象

  • procd 注册在系统总线上的另外一个对象为system。
  • 下表为system 对象的所有方法。 该对象可以供luci来调用,其他模块很少调用,因此不再详述。
方 法 含 义
board 系统软硬件版本信息,包含 4 个部分,分别为内核版本、主机名称、系统 CPU 类 型信息和版本信息,版本信息从/etc/openwrt_release 文件读出
info 当前系统信息,包含 5 部分,分别为系统启动时间、系统当前时间、系统负载情况、 内存和交换分区占用情况等
upgrade 设置 service_update 为 1
watchdog 设置 watchdog 信息,还存在问题,例如如果本身为 0 的情况
signal 向指定 pid 的进程发信号,是通过 kill 函数来实现的
nandupgrade 执行升级

四、procd.sh

  • 使用ubus方法来进行管理时其传递参数复杂并且容易出错,procd.sh将这些参数拼接组织功能封装为函数,每一个需要被procd管理的进程都使用它提供的函数进行注册。

procd.sh的函数

  • 这些函数组织为JSON格式的消息然后通过ubus总线向procd进程发送消息。这些函数将不同功能封装为不同的函数,构建特定的JSON消息来表达特定的功能用法。
  • 函数命名规范:procd.sh提供的API命名非常规范,除了有一个uci_validate_section函数用于验证UCI 配置文件以外,其他所有的函数均是以“procd_”开头。

procd_open_ trigger、procd_close_trigger、procd_add_reload_trigger函数

  • procd_open_ trigger函数创建一个触发器数组,在增加了所有的触发器之后,调用procd_close_trigger函数来结束触发器数组的增加。
  • procd_add_reload_trigger:增加配置文件触发器,每次配置文件的修改,如果调用了reload_config时,当前实例都被重启。有一个可选的参数为配置文件名称。其实它在内部是调用 procd_open_trigger、procd_add_config_trigger 和 procd_close_trigger 这3个函数来增加触发器。

procd_open_instance、procd_set_param、procd_close_instance函数

  • 通常这3个函数在一起使用
  • procd_open_instance:开始增加一个服务实例。
  • procd_set_param:设置服务实例的参数值。通常会有以下几种类型的参数:(每次只能使用一种类型参数,其后是这个类型参数的值)。
    • command:服务的启动命令行。
    • respawn:进程意外退出的重启机制及策略,它需要有 3 个设置值。第一个设置为 判断异常失败边界值(threshold),默认为 3600 秒,如果小于这个时间退出,则 会累加重新启动次数,如果大于这个临界值,则将重启次数置 0。第二个设置为 重启延迟时间(timeout),将在多少秒后启动进程,默认为 5 秒。第三个设置是总 的失败重启次数(retry),是进程永久退出之前的重新启动次数,超过这个次数进 程退出之后将不会再启动。默认为 5 次。也可以不带任何设置,那这些设置都是 默认值。
    • env:进程的环境变量。
    • file:配置文件名,比较其文件内容是否改变。
    • netdev:绑定的网络设备(探测 ifindex 更改)。
    • limits:进程资源限制。
  • procd_close_instance:完成进程实例的增加。
  • 演示案例:下面为rpcd对procd函数的使用,这个示例可以用于大多数应用程序。PROG变量在前面已设置为/bin/rpcd。该示例将最终调用以下命令完成进程的增加。
ubus call service set '{"name":"rpcd", "script":"/etc/init.d/rpcd",
"instances": {"instance1":{ "command": ["/bin/rpcd"] } } }'
procd_open_instance
procd_set_param command "$PROG"
procd_close_instance

procd_open_validate、procd_close_validate函数

  • procd_open_validate:打开一个验证数组,是和 procd_close_validate 函数一起使用。
  • procd_close_validate:关闭一个验证数组。
  • 演示案例:下面是软件包firewall使用 procd 来对防火墙配置的触发器和验证。
procd_add_reload_trigger firewallprocd_open_validate
validate_firewall_redirect
validate_firewall_rule
procd_close_validate

procd_open_service(name, [script])、procd_close_service函数

  • procd_open_service(name, [script]):至少需要一个参数,第一个参数是实例名称, 第二个参数是可选参数为启动脚本。该函数仅在在 rc.common 中调用,用于创建一个新的 procd 进程服务消息。
  • procd_close_service:该函数不需要参数,仅在 rc.common 中调用,完成进程管理服务的增加。

procd_kill函数

  • 杀掉服务实例(或所有的服务实例)。至少需要一个参数,第一个参 数是服务名称,通常为进程名,第二个是可选参数,是进程实例名称,因为可能有多个进 程示例,如果不指定所有的实例将被关闭。该函数在 rc.common 中调用,用户从命令行调 用 stop 函数时会使用该函数杀掉进程。

uci_validate_section

  • 调用 validate_data 命令注册为验证服务。在配置发生改变 后对配置文件的配置项合法性进行校验。验证服务是在进程启动时通过 ubus 总线注册到 procd 进程中。
  • 输入以下命令,可以看到系统所有注册的验证服务。
ubus call service validate

  • 这些验证服务是在启动脚本中增加验证服务来实现,如下代码所示,service_triggers 函数是预定义好的回调函数,在每一个增加服务结束后会自动调用,使用者不必关注如何 调用。validate_cron_section 函数是真正的将验证服务加入 procd 的验证服务中。它调用 uci_validate_section 函数,而 uci_validate_section 函数进一步调用 validate_data 程序。
validate_cron_section() {uci_validate_section system system "${1}" \'cronloglevel:uinteger'
}service_triggers()
{procd_add_validation validate_cron_sectionprocd_add_reload_trigger "hello"
}

五、rc.common

  • rc.common在1209及之前的版本中并不支持procd启动,在1407版本中增加了专门针对procd的启动,该脚本向前兼容。
  • USE_PROCD变量:
    • 在软件模块的启动脚本中如果没有定义USE_PROCD变量:则启动流程和之前完全相同。
    • 如果定义了 USE_PROCD变量:对start、stop 和 reload函数进行重新定义,在调用这些函数时,将调用start_service、stop_service和 reload_service函数等。
  • procd预定义的函数如下:如果在自己的启动脚本中定义了USE_PROCD那就调用这些函数。在rc.common中重新定义了start函数,相当于重载了这些函数。
函 数 含 义
start_service 向 procd 注册并启动服务,是将在 services 所管理对象里面增加了一项。
stop_service 让 procd 解除注册,并关闭服务, 是将在 services 中的管理对象删除。
service_triggers 配置文件或网络接口改变之后触发服务重新读取配置。
service_running 查询服务的状态。
reload_service 重启服务,如果定义了该函数,在 reload 时将调用该函数,否则再次调用 start 函数。
service_started 用于判断进程是否启动成功。

六、编写一个procd启动脚本

#!/bin/sh /etc/rc.commonUSE_PROCD=1
START=15
STOP=85
PROG=/bin/hellovalidate_hello_section()
{uci_validate_section hello system globe \'delay:uinteger(1:200)'
}start_service() {echo "start HelloRoute!"validate_hello_section || {echo "hello validattion failed!"return 1}procd_open_instanceprocd_set_param command "$PROG" –f -w bjbook.netprocd_set_param respawnprocd_close_instance
}service_triggers()
{procd_add_reload_trigger "hello"
}reload_service()
{stopstart
}
  • 备注: 在执行该启动脚本时,如果需要对procd脚本进行调试,可以设置PROCD_DEBUG变量为 1,这样可以输出向ubus总线调用的参数信息。例如:
PROCD_DEBUG=1 /etc/init.d/hello start

脚本分析

  • 通常前面两行内容是固定的,第一行表示使用“/etc/rc.common”来解释脚本。第二行内容设置USE_PROCD变量为1,表示使用procd来管理进程。

  • PROG变量用来给程序的启动脚本赋值,用于启动应用程序。

  • validate_hello_section函数:验证了配置文件hello中的delay变量否为整型值,并且在合理的(1~200)范围内。

  • start_service函数:负责程序的启动。

    • 函数开始处调用了validate_hello_section函数对程序配置文件进行验证,如果验证失败,则进程不启动。
    • 在参数验证完成后,调用procd_open_instance 数发起实例增加,接着调用了procd_set_param函数来设置了启动命令和启动参数,再接着设置其进程意外退出的重启机制及策略为默认值,最后调用procd_close_instance函数完成实例的增加。注意procd管理的进程需要运行在前台,即不能调用daemon或类似函数。

  • service_triggers函数:增加触发器,我们增加了对配置文件hello的触发服务。当hello文件发生改变后,如果调用了 reload_config命令,将触发调用reload_service函数。

  • reload_service函数:在传递reload参数时进行调用,如果没有该函数,将会调用默认start函数。

  • 关于开机启动脚本的介绍,详情见文章:https://blog.csdn.net/qq_41453285/article/details/102545624。

  • 我是小董,V公众点击"笔记白嫖"解锁更多OpenWrt资料内容。

OpenWrt开发必备软件模块——进程管理服务procd相关推荐

  1. OpenWrt开发必备软件模块——系统总线ubus

    一.ubus模块介绍 OpenWrt 提供了一个系统总线ubus,它类似于Linux桌面操作系统的d-Bus,目标是提供系统级的进程间通信(IPC)功能.ubus在设计理念上与d-Bus基本保持一致, ...

  2. OpenWrt开发必备软件模块——无线技术与PPPoE

    一.什么是无线 无线是使用射频技术,利用无线电波发送与接收数据,无须中断网络即可实现移动办公. IEEE 802.11是无线网络的协议标准,计算机之间的无线通信需要共同遵守 IEEE 802.11规则 ...

  3. NI LabVIEW 2014SP1视觉开发必备软件和工具包

    * s! R7 D7 p NI LabVIEW 2014SP1视觉开发必备软件和工具包 4 U# Z, M; ?7 z2 r0 q) j  L. f NI视觉开发可以使用64位版本,因为其视觉包直接支 ...

  4. Mac 高效程序猿开发必备软件

    一个聪明的开发者会用合理使用工具软件来提高工作效率,MacBook Pro开发必备软件. 工具软件选择策略 聪明的程序员不仅应该知道借助各种软件来提高工作效率,还应该知道如何选择适合自己的软件. 当前 ...

  5. LabVIEW视觉开发必备软件VAS、VDM、VBAI以及基于VDM的圆形

    1.关于labview视觉开发必备软件 VAS--vision acquisition software(视觉获取软件)用于捕获图像的一系列驱动程序.如果你使用的是大恒的工业相机,调用的是DLL,不需 ...

  6. NI LabVIEW 2015视觉开发必备软件和工具包

    http://shixinhua.com/bbs/thread-8487-1-1.html NI LabVIEW&VISION 2015视觉开发必备软件和工具包 1 M) Y2 }) E9 r ...

  7. LabVIEW 2013SP1视觉开发必备软件LV、VDM、VBAI、VAS

    NI LabVIEW 2013SP1视觉开发必备软件LV.VDM.VBAI.VAS ---------------------------------------------------------- ...

  8. Java后端开发必备软件下载地址汇总

    Java后端开发必备软件下载地址汇总 文章目录 Java后端开发必备软件下载地址汇总 先记录,用到再加,持续更新,欢迎补充. 华为云 jdk8 OpenJdk小版本 IDEA各版本 Tomcat各版本 ...

  9. python中的os abort_Python::OS 模块 -- 进程管理

    这里我们介绍os模块中的进程管理相关的操作. os模块提供给了我们访问操作系统功能的接口,我们可以通过os模块提供给我们的进程管理接口,编写多进程程序,这对编写高效.并发的程序提供了方便. 下面是一个 ...

  10. PHP开发必备软件(个人意见)

    一.环境 Visual NMP (http://www.ampnmp.com/visual-nmp/) 当前环境php版本7.0 下面是环境效果集成了 各种php开发必备的软件 相比phpstudy ...

最新文章

  1. 实战:vue项目中导入swiper插件
  2. 近期活动盘点: Call for Code编程马拉松邀请赛
  3. python3+scapy扫描获取局域网主机ip和mac
  4. Opencv_黑白素描
  5. HTTP 错误 403.1 - 禁止访问:执行访问被拒绝
  6. thinkphp 5.0 模块设计
  7. STM32 USB主机通信连接中断过程
  8. 标准模型与随机预言模型的比较
  9. Outlook_Hotkey
  10. 安卓进阶之android系统架构
  11. HDU 6148 Valley Numer (数位DP)题解
  12. meta-learning link for some Danniel
  13. Git生成公钥及查看公钥
  14. 得到 K 个黑块的最少涂色次数
  15. 浙大版《C语言程序设计实验与习题指导(第3版)》题目集
  16. office快速制作贺报方法
  17. docker部署excalidraw画图工具
  18. python绘制风向玫瑰图
  19. 分支定价求解GAP问题
  20. python 经典练习题一

热门文章

  1. hdu5773The All-purpose Zero
  2. Android内存优化工具
  3. 最新 iOS13 苹果登录
  4. 【高通】【QPST】QCN导入
  5. 定时任务:数据表设计与实现方案
  6. hdu 4816,Bathysphere,三分
  7. linux下的chm阅读器?
  8. F - 悼念512汶川大地震遇难同胞
  9. 2022-2028年中国再生塑料行业市场全景评估及发展策略分析报告
  10. AlipayHK拿下香港港铁,背后是蚂蚁金服出海造船的阳谋