OpenWRT(16):基于ubus的远程调用守护进程rpcd(Remote Procedure Call Daemon)
OpenWrt的rpcd(RemoteProcedureCallDaemon)是一个守护进程,它提供了一个基于UBUS(OpenWrt'sUnifiedBinaryService)的RPC框架,允许通过插件来扩展其功能。rpcd的主要作用包括:
- 提供远程过程调用接口:允许远程客户端(如LuCIWebUI、命令行工具或其他网络服务)通过RPC调用在OpenWrt系统上运行的特定函数或命令。
- 插件化架构:通过插件系统,rpcd可以灵活地添加新的功能和服务,而无需对核心守护进程进行修改。这些插件可以是共享库(.so文件)或可执行脚本。
- 简化服务管理:rpcd可以管理各种后台服务,如网络配置、设备管理和系统设置,提供了一种统一的方式来处理这些服务的创建、配置和监控。
- 安全性:通过访问控制列表(ACLs)和会话管理,rpcd可以限制对特定RPC调用的访问,确保只有授权的用户或服务能够执行特定的操作。
- 与WebUI的集成:rpcd与OpenWrt的Web用户界面(LuCI)紧密集成,允许通过Web界面进行配置更改和系统管理。
- 支持异步操作:rpcd支持异步RPC调用,这意味着它可以处理长时间运行的操作而不会阻塞客户端。
- 消息总线:rpcd使用UBUS作为消息总线,允许不同的应用程序和组件之间进行通信和数据交换。
为什么需要rpcd:
- 模块化:rpcd的插件化架构使得OpenWrt系统更加模块化,易于扩展和维护。
- 安全性:通过细粒度的访问控制,rpcd增强了系统的安全性,确保只有授权的操作被执行。
- 易用性:rpcd提供的RPC接口简化了远程管理和自动化任务,使得用户和开发者可以更容易地与OpenWrt系统交互。
- 性能:rpcd可以异步处理请求,提高了系统的性能和响应能力。
- 兼容性:rpcd支持多种数据交换格式(如JSON),使得它能够与现代的客户端和工具兼容。
总的来说,rpcd是OpenWrt系统中一个关键的组件,它提供了一个灵活、安全且高效的机制来管理和扩展路由器的功能。
[OpenWrt Wiki] rpcd: OpenWrt ubus RPC daemon for backend server
1 rpcd配置
rpcd提供了UBUS RPC后端服务,通过JSON-RPC向前端程序开放各种功能。
rpcd是 OpenWrt 中的一个重要组件,主要用于处理通过ubus进行的远程过程调用。它提供了一种机制,使得不同的应用程序和服务能够通过统一的接口进行通信。
Base system
rpcd
rpcd-mod-file--提供文件和目录操作服务。
rpcd-mod-iwinfo--访问iwinfo数据。
rpcd-mod-rpcsys--sysupgrade和密码修改等服务。
rpcd-mod-ucode--执行ucode脚本服务。
2 rpcd启动
由/etc/rc.d/S12rpcd启动rpcd进程:
/sbin/rpcd -s /var/run/ubus/ubus.sock -t 30
通过/var/run/ubus/ubus.sock表示的socket和ubus通信,rpc执行的超时为30秒。
rpcd 1056 root cwd DIR 0,12 380 1 / rpcd 1056 root rtd DIR 0,12 380 1 / rpcd 1056 root txt REG 0,12 66139 443 /sbin/rpcd rpcd 1056 root mem REG 0,12 12466 573 /usr/lib/rpcd/rrdns.so rpcd 1056 root mem REG 0,12 33026 574 /usr/lib/rpcd/luci.so rpcd 1056 root mem REG 0,12 41546 1052 /usr/lib/libnl-tiny.so rpcd 1056 root mem REG 0,12 62965 1074 /usr/lib/libiwinfo.so.20210430 rpcd 1056 root mem REG 0,12 20682 575 /usr/lib/rpcd/iwinfo.so rpcd 1056 root mem REG 0,12 20658 576 /usr/lib/rpcd/file.so rpcd 1056 root mem REG 0,12 73744 395 /lib/libgcc_s.so.1 rpcd 1056 root mem REG 0,12 65574 1069 /usr/lib/libjson-c.so.5.1.0 rpcd 1056 root mem REG 0,12 12291 398 /lib/libblobmsg_json.so.20220515 rpcd 1056 root mem REG 0,12 41043 388 /lib/libuci.so rpcd 1056 root mem REG 0,12 24738 389 /lib/libubus.so.20220601 rpcd 1056 root mem REG 0,12 53329 390 /lib/libubox.so.20220515 rpcd 1056 root mem REG 0,12 545785 397 /lib/libc.so rpcd 1056 root 0r CHR 1,3 0t0 10 /dev/null rpcd 1056 root 1w CHR 1,3 0t0 10 /dev/null rpcd 1056 root 2w CHR 1,3 0t0 10 /dev/null rpcd 1056 root 3u a_inode 0,9 0 18 [eventpoll:4,6] rpcd 1056 root 4r FIFO 0,8 0t0 352 pipe rpcd 1056 root 5w FIFO 0,8 0t0 352 pipe rpcd 1056 root 6u unix 0x00000000e169c5a9 0t0 353 type=STREAM
3 rpcd流程
main
uloop_init
ubus_connect--连接到 ubus 服务。
ubus_add_uloop
rpc_session_api_init--初始化session相关的RPC插件,更多参考《[OpenWrt Wiki] ubus session》。
rpc_uci_api_init--初始化UCI配置管理相关的RPC插件,更多参考《[OpenWrt Wiki] ubus uci》。
rpc_rc_api_init--初始化运行级别和初始化脚本管理相关的RPC插件。
rpc_plugin_api_init
rpc_plugin_register_exec--执行/usr/libexec/rpcd中的脚本。
rpc_plugin_parse_exec--解析一个外部命令(通常是一个脚本或可执行程序)并将其注册为rpcd的插件。这个函数通常在rpcd启动时调用,用于动态加载和注册插件。
read--从文件描述符fd读取数据。这些数据是插件在接收到list命令时输出的 JSON 格式的字符串,描述了插件提供的方法和它们的签名。
json_tokener_parse_ex--使用json_tokener库解析 JSON 输出,将其转换为json_object结构。
--基于解析出的方法和签名,创建一个ubus_object结构,这个结构将被注册到ubus系统中,使得通过ubus可以调用插件提供的方法。
ubus_add_object
rpc_plugin_register_library--加载/usr/lib/rpcd中的库文件,执行里面结构体rpc_plugin->init()函数。包括rrdns.so、luci.so、iwinfo.so、file.so。
rpc_file_api_init--更多参考《[OpenWrt Wiki] ubus file》。
rpc_iwinfo_api_init--更多参考《[OpenWrt Wiki] ubus iwinfo》。
rpc_luci_api_init
rpc_rrdns_api_init
uloop_run--启动事件循环,等待和处理事件。
exec_self--respawn时自重启。
4 通过rpcd注册的ubus服务
rpcd创建的ubus服务如下:
- rpcd本身创建的服务:session、uci、rc。
- rpcd调用脚本创建的服务:luci-rpc。
- rpcd调用插件创建的服务:file、iwinfo、luci、network.rrdns。
...'file' @f8930524 "read":{"path":"String","base64":"Boolean","ubus_rpc_session":"String"} "write":{"path":"String","data":"String","append":"Boolean","mode":"Integer","base64":"Boolean","ubus_rpc_session":"String"} "list":{"path":"String","ubus_rpc_session":"String"} "stat":{"path":"String","ubus_rpc_session":"String"} "md5":{"path":"String","ubus_rpc_session":"String"} "remove":{"path":"String","ubus_rpc_session":"String"} "exec":{"command":"String","params":"Array","env":"Table","ubus_rpc_session":"String"} ...'iwinfo' @0f47b60c "devices":{} "info":{"device":"String"} "scan":{"device":"String"} "assoclist":{"device":"String","mac":"String"} "freqlist":{"device":"String"} "txpowerlist":{"device":"String"} "countrylist":{"device":"String"} "survey":{"device":"String"} "phyname":{"section":"String"} ...'luci' @6043b6a1 "getMountPoints":{} "getFeatures":{} "setBlockDetect":{} "getSwconfigFeatures":{"switch":"String"} "setPassword":{"username":"String","password":"String"} "getConntrackHelpers":{} "getUSBDevices":{} "getInitList":{"name":"String"} "getProcessList":{} "getBlockDevices":{} "getRealtimeStats":{"device":"String","mode":"String"} "getSwconfigPortState":{"switch":"String"} "getLEDs":{} "getConntrackList":{} "setLocaltime":{"localtime":"Integer"} "getTimezones":{} "setInitAction":{"name":"String","action":"String"} "getLocaltime":{} 'luci-rpc' @c1308a34 "getNetworkDevices":{} "getWirelessDevices":{} "getHostHints":{} "getDUIDHints":{} "getBoardJSON":{} "getDHCPLeases":{"family":"Integer"} ..'network.rrdns' @98fc9349 "lookup":{"addrs":"Array","timeout":"Integer","server":"String","port":"(unknown)","limit":"Integer"} ...'rc' @d9558cc0 "list":{} "init":{"name":"String","action":"String"} ...'session' @c07213dd "create":{"timeout":"Integer"} "list":{"ubus_rpc_session":"String"} "grant":{"ubus_rpc_session":"String","scope":"String","objects":"Array"} "revoke":{"ubus_rpc_session":"String","scope":"String","objects":"Array"} "access":{"ubus_rpc_session":"String","scope":"String","object":"String","function":"String"} "set":{"ubus_rpc_session":"String","values":"Table"} "get":{"ubus_rpc_session":"String","keys":"Array"} "unset":{"ubus_rpc_session":"String","keys":"Array"} "destroy":{"ubus_rpc_session":"String"} "login":{"username":"String","password":"String","timeout":"Integer"} ...'uci' @4c8d1c9c "configs":{} "get":{"config":"String","section":"String","option":"String","type":"String","match":"Table","ubus_rpc_session":"String"} "state":{"config":"String","section":"String","option":"String","type":"String","match":"Table","ubus_rpc_session":"String"} "add":{"config":"String","type":"String","name":"String","values":"Table","ubus_rpc_session":"String"} "set":{"config":"String","section":"String","type":"String","match":"Table","values":"Table","ubus_rpc_session":"String"} "delete":{"config":"String","section":"String","type":"String","match":"Table","option":"String","options":"Array","ubus_rpc_session":"String"} "rename":{"config":"String","section":"String","option":"String","name":"String","ubus_rpc_session":"String"} "order":{"config":"String","sections":"Array","ubus_rpc_session":"String"} "changes":{"config":"String","ubus_rpc_session":"String"} "revert":{"config":"String","ubus_rpc_session":"String"} "commit":{"config":"String","ubus_rpc_session":"String"} "apply":{"rollback":"Boolean","timeout":"Integer","ubus_rpc_session":"String"} "confirm":{"ubus_rpc_session":"String"} "rollback":{"ubus_rpc_session":"String"} "reload_config":{}
联系方式:arnoldlu@qq.com