1 简介
procd
是一个守护进程。它通过init
脚本将进程信息加入到procd
的数据库中进行管理procd
进程管理功能主要包含3个部分
-
reload_config
,检查配置文件是否发生变化,如果有变化则通知procd
进程 -
procd
,守护进程。接收使用者的请求,增加或删除所管理的进程。并监控进程的状态,如果发现进程退出,则再次启动进程 -
procd.sh
函数封装procd
提供的方法
2 reload_config
当执行reload_config
时,会对系统中的所有配置文件生成MD5
值、并且和应用程序使用的配置文件MD5
值进行比较。如果不同就通过ubus
总线通知procd
配置文件发生改变。
如果应用程序在启动时,向procd
注册了触发服务,那么将配置reload
函数重新读取配置文件(一般为进程退出之后在启动)。需要注意的是配置文件需要内容发生改变之后才会调用、增加空行和注释不会引起内容实质性改变(但会改变MD5
,因为备份配置时会将空行和注释过滤掉)。系统启动时reload_config
会将初始配置文件值保存到/var/run/config.md5
中
示例:
1、手动执行reload_config
,首先会将/etc/config
下的文件通过uci show
输出到/var/run/config.check
会过滤到空行和注释
2、从/var/run/config.md5
读取md5
和现有的配置文件进行比较。如果MD5
不一样就通过ubus
来通知proc
进程配置文件发生改变
3、proc
监控到配置文件发生改变之后会调用/etc/init.d/
下面的相关进程去重启相关进程。
4、最后将运行中的配置文件保存到/var/run/config.md5
3 proc
proc
向ubus
注册了service
和system
对象service
主要有3个功能:进程的管理,文件触发器(trigger
),配置验证服务(validate
)
server
对象常用方法
set : 进程如果存在,则修改注册进程的信息;进程如果不存在,则增加相关进程,最后启动注册的进程
add : 增加注册进程
list : 如果不带参数,则列出所有的进程和其他信息
delete : 删除指定进程
ubus delete service delete '{"name":"firewall"}'
event : 发出事件。reload_config就通过此发送通知信息
validate : 查看所有的验证服务
ubus list service -v
~# ubus list service -v
'service' @c70c3588
"set":{"name":"String","script":"String","instances":"Table","triggers":"Array","validate":"Array"}
"add":{"name":"String","script":"String","instances":"Table","triggers":"Array","validate":"Array"}
"list":{"name":"String","verbose":"Boolean"}
"delete":{"name":"String","instance":"String"}
"update_start":{"name":"String"}
"update_complete":{"name":"String"}
"event":{"type":"String","data":"Table"}
"validate":{"package":"String","type":"String","service":"String"}
"get_data":{"name":"String","instance":"String","type":"String"}
set
入参
- 被管理的服务进程名称
- 启动脚本的绝对路径
- 进程的实例信息(可执行的程序路径和入参)
- 触发器(可选)
- 配置验证项(可选)
add
入参
这里以添加一个hello
进程由proc
进行管理
ubus service add '{"name":"hello", "script":"/etc/init.d/hello",\
"instances":{"instances":{"command":["/bin/hello","-f","-c"], "respawn":[ ]}},\
"tiggers":"[["config.change", ["if", ["eq","package","hello"], ["run_script",\
"/etc/init.d/hello", "reload"]"}'
- 被管理的服务进程名称
- 启动脚本的绝对路径
- 进程的实例信息(可执行的程序路径和入参)
实例启动的命令为/bin/hello
入参为-f -c
- 触发器(可选)
收到hello
的config.change
消息后执行/etc/init.d/hello
,入参为reload
list
入参
- 服务名称
- 布尔值
verbose
(可选)。是否输出详细信息,默认为不输出详细信息
ubus call service list '{"name":"hello","verbose":"ture"}'
delete
入参
- 服务名称
- 进程实例名称(可选)
ubus call service delete '{"name":"hello"}'
event
入参
- 时间类型
- 文件
ubus call service event '{"tpye":"config.change","data":{"package":"hello"}}'
发送事件为config.change
,hello
是指在/etc/config
下的文件
system
对象方法
board : 系统软硬件版本信息。从/etc/opwrt_release中读出
info : 当前系统信息。系统启动时间,系统当前时间,系统负载情况,内存和交换分区占用情况等
upgrade : 设置serveice_update为1
watchdog : 设置watchdog
signal : 向指定的pid进程发信号
nandupgrade : 升级
~# ubus list system -v
'system' @3dd33800
"board":{}
"info":{}
"upgrade":{}
"watchdog":{"frequency":"Integer","timeout":"Integer","stop":"Boolean"}
"signal":{"pid":"Integer","signum":"Integer"}
"nandupgrade":{"path":"String"}
4 procd.sh
一些常用的命令
-
procd_open_instance
增加一个服务实例 -
procd_set_param
设置实例的参数值command
服务的启动命令行respawn
进程意外退出的重启机制和策略。它需要三个值:
1、异常失败边界值(threshold
),默认为3600。如果小于这个值则累加重新启动次数。如果大于则计数归零
2、重启延时值。将在多少秒后重启进程。默认为5s。
3、总的失败重启数。程序永久退出之前的重启数,默认为5env
环境变量file
配置文件名,用于比较其内容是否改变netdev
绑定的网络设备limits
进程资源限制 -
procd_close_instance
完成进程实例的增加 -
procd_add_reload_trigger
增加配置文件触发器,每次配置文件的修改,如果调用了reload_config
时,当前实例都被重启。实际在内部调用的是procd_open_trigger、procd_add_config_trigger、procd_close_trigger
-
procd_open_validate
打开一个验证数组 -
procd_close_validate
关闭一个验证数组 -
procd_open_service(name,[script])
该函数仅在rc.command
中被调用。用于创建一个procd
进程服务消息 -
procd_close_service
该函数仅在rc.command
中被调用。完成procd
进程服务增加 -
procd_kill
杀掉服务实例。
1、参数一为服务名称。通常为进程名。
2、进程实例名称(可选) -
uci_validate_section
调用validate_data
在配置发生改变时对配置进行合法性校验
5 rm.command
procd
预定义的函数
start_service : 向procd注册启动服务。是将在service所管理对象里增加一项
stop_service : 让procd解除注册,并关闭服务。是将在service所管理对象里删除
service_trigger : 配置文件或网络接口改变之后触发服务重新读取配置
service_running : 查询服务状态
reload_service : 重启服务,如果定义了次函数,reload时将会调用,否则调用start
service_started : 判断进程是否启动成功
示例
start_service() {
procd_open_instance
procd_set_param command "$PROG" -r
procd_set_param command respawn
procd_close_instance
...
}
validate_qos_section()
{
uci_validate_section qos interface "${1}" \
'enabled:bool' \
'upload:uinteger' \
'download:uinteger'
}
service_triggers()
{
procd_add_reload_trigger "qos"
procd_add_validation validate_qos_section
qos-start
}
start_service() {
}
stop_service() {
}
reload_service() {
}