参考连接:html
[openwrt] 使用ubus实现进程通讯segmentfault
openwrt ubus简介以及libubus开发说明
session
ubus [1] - ubusd数据结构
ubus是为了OpenWrt中守护进程和应用程序之间通信开发的,相似桌面的DBus,设计理念上与DBus基本保持一致,区别是简化的API和简练的模型,以适应embeddedrouter的特殊环境。与DBus同样也是使用socket实现。
核心部分是ubusd守护进程,它提供了其余守护进程将本身注册以及发送消息的接口。由于这个,接口经过使用Unixsocket来实现,并使用TLV(type-length-value)消息,ubus内部使用Blob_buf,Blob_attr等结构来表示。
ubus有两种调用,一个是method调用,一个是notification,其中method包括等待函数返回和不用等待返回,notification是广播和DBus的signal相似。ubus使用是先创建链接,而后把链接加入epollset中。
下面是它的一些调用API。
uloop_init(); 建立epoll句柄,最多监听32个fd
ubus_connect(); 建立ubus链接
ubus_add_uloop(); 把建立的ubus链接注册到epoll中。
ubus_add_object(); 注册对象到的ubus链接。
uloop_run(); 等待I/O事件发生,调用相对应的对象的功能函数。
ubus_free(); 关闭ubus链接
uloop_done(); 关闭epoll句柄
属于procd启动的一项:
/etc/preinit --> /sbin/init --> /sbin/procd --> /sbin/ubusd
path | Description | Package |
---|---|---|
dhcp | dhcp server | odhcpd |
file | file | rpcd |
hostapd | acesspoints | wpad/hostapd |
iwinfo | wireless informations | rpcd iwinfo |
log | logging | procd |
mdns | mdns avahi replacement | mdnsd |
network | network | netifd |
service | init/service | procd |
session | Session management | rpcd |
system | system misc | procd |
uci | Unified Configuration Interface | rpcd |
ubus调试有一个命令行工具叫ubus,ubus能够和ubusd服务器交互(和当前全部已经注册的服务).它对研究和调试注册的命名空间以及编写脚本很是有用。
能够调用带参数和返回信息的方法,它使用友好的JSON格式。
ubus命令使用说明
ubus命令用于控制调试相关ubus接口,主要命令说明以下:
- list [<path>] List objects
- call <path> <method> [<message>] Call an object method
- listen [<path>...] Listen for events
- send <type> [<message>] Send an event
- wait_for <object> [<object>...] Wait for multiple objects to appear on ubus
ubus list [-v] 该命令用于显示当前ubus中注册的接口,其中-v参数用以显示各个接口的详细信息。示例以下:
root@uplink:~# ubus list network network.device network.interface.lan network.interface.loopback network.interface.wan
ubus call 该命令用于调用ubus中当前注册的接口。示例以下:
ubus listen 用于监听ubus相关事件,若是不指定事件名则监听全部事件。(支持通配符*)
root@uplink:~# ubus listen & root@uplink:~# ubus call network.interface.wan down { "network.interface": { "action": "ifdown", "interface": "wan" } } root@uplink:~# ubus call network.interface.wan up { "network.interface": { "action": "ifup", "interface": "wan" } } { "network.interface": { "action": "ifdown", "interface": "he" } } { "network.interface": { "action": "ifdown", "interface": "v6" } } { "network.interface": { "action": "ifup", "interface": "he" } } { "network.interface": { "action": "ifup", "interface": "v6" } }
ubus send 用于发送事件
root@uplink:~# ubus listen & root@uplink:~# ubus send foo '{ "bar": "baz" }' { "foo": { "bar": "baz" } }
ubus wait_for 用于等待指定项的注册到ubus中。
使用ubus时须要引用一些动态库,主要包括:
libubus.so:ubus向外部提供的编程接口,例如建立socket,进行监听和链接,发送消息等接口函数。
libubox.so:ubus向外部提供的编程接口,例如等待和读取消息。
libblobmsg_json.so,libjson.so:提供了封装和解析json数据的接口,编程时使用libblobmsg_json.so提供的更灵活的接口函数。
ubus可用于两个进程之间的通讯,并以相似json格式进行数据交互。ubus的常见场景为:
1)“客户端--服务器”形式的交互,即进程A注册一系列的服务,进程B去调用这些服务。
2)ubus支持以“订阅 -- 通知”的方式进行进程通讯,即进程A提供订阅服务,其余进程能够选择订阅或退订该服务,进程A能够向全部订阅者发送消息。
因为ubus实现方式的限制,在一些场景中不适宜使用ubus:
1)ubus用于少许数据的传输,若是数据量很大或是数据交互很频繁,则不宜用ubus。通过测试,当ubus一次传输数据量超过60KB,就不能正常工做了。2)ubus对多线程支持的很差,例如在多个线程中去请求同一个服务,就有可能出现不可预知的结果。3)不建议递归调用ubus,例如进程A去调用进程B的服务,而B的该服务须要调用进程C的服务,以后C将结果返回给B,而后B将结果返回给A。若是不得不这样作,须要在调用过程当中避免全局变量的重用问题。