The ubus mechanism of openwrt
The most recent project at work uses openwrt, and a task I am responsible for needs to obtain network status, so I need to use ubus. The following are only study notes.
1. Introduction to openwrt
OpenWRT is a highly modular and highly automated embedded Linux system with powerful network components and scalability. It is often used in industrial control equipment, telephones, small robots , smart homes, routers, and VOIP devices. At the same time, it also provides more than 100 compiled software, and the number is still increasing, and the OpenWrt SDK simplifies the process of developing software.
OpenWRT is different from many other distributions for routers. It is a router operating system written from scratch, fully functional and easy to modify. In fact, this means that you can use the functions you want without adding other burdens, and support these functions to work [linux kernel](https://baike.baidu.com/item/linux kernel/765824) It is far newer than most distributions.
2 、 ubus
Introduction
Ubus is a general framework for inter-process communication. It has strong portability and can be easily transplanted to other Linux platforms for use.
The ubus module is designed to provide communication between daemons and applications, including daemon ubusd, libraries, and some examples. Ubusd can be considered as a message management server (Server), and processes that require communication can use ubus through the provided libubus, and ubus relies on ubox. The source code download address is as follows: web
ubus git: //nbd.name/luci2/ubus.git 或者 http://git.openwrt.org/project/ubus.git
ubox git: //nbd.name/luci2/ubox.gitshell
The internal framework of ubus is roughly as follows:
The Ubus Daemon is ubusd, which is a service management server. The component in the lower right corner of the above figure is a Client, which is used to request services from ubusd. And the lower left corner is a service provider (compared to ubusd, it is actually a Client, here is called Server is actually relative to the service requester Client, don't confuse it). In the above figure, the messages communicated between Server and Client are in json format.
Glossary
Object:
In order to facilitate the processing of messages, ubusd abstracts the concepts of "object" and "method". An object contains multiple methods, and they can all be named for easy use in other places. Multithreading
Method
Methods are operations provided by objects that can be invoked. When using ubus to call (Call) a certain method, the Client will send a call message to the service provider and wait for a reply. Architecture
Notification & Subscriber (Observer)
Subscribers only care about the services they are interested in, and the notifier broadcasts messages through the service to notify all subscribers. There is a many-to-one relationship between them.
ubus inter-process communication method
There are three ways of communication between ubus processes: P2P mode; Subscribe-notify mode; Event broadcast mode.
1) P2P method: 1 to 1
For the process of providing service (Service) (service provider)
- Use ubus_connect to link to the service management process ubusd, and obtain ubus_context (including link fd, callback of registered fd, etc.)
- After ubus_add_uloop, the link fd contained in ubus_context is added to the epoll descriptor set for monitoring.
Note: Before using ubus, uloop_init must be called to prepare the epoll special handle. - Add the defined object to ubusd via ubus_add_object
- Call uloop_run to loop the file descriptor set of epoll
- Resource release
If you don't want to use ubus anymore, call ubus_free and uloop_done in turn to release the previously requested resources.
For the request process of obtaining service (client)
-
Call ubus_connect to link to ubusd to obtain ubus_context
-
After ubus_add_uloop, the link fd contained in ubus_context is added to the epoll descriptor set for monitoring.
Note: Before using ubus, uloop_init must be called to prepare the epoll special handle. -
Call ubus_lookup_id to find the id corresponding to the object
-
Fill the call parameters into blob_buf
① initialize blob_buf
through blob_buf_init ② add data to blob_buf through functions such as blobmsg_add_u32 -
Call ubus_invoke and wait for a response.
If you don’t need to wait for a response, call ubus_invoke_async
-
Resource release
If you don't want to use ubus anymore, call ubus_free and uloop_done in turn to release the previously requested resources.
2) Subscribe-notify method: 1 to many
A is the subscriber, and B, C, and D are subscribers.
B, C, D subscribe to A through ubusd, and A broadcasts messages to B, C, D through ubusd
For subscribers (Subscriber)
- Call ubus_connect to link to ubusd to obtain ubus_context
- After ubus_add_uloop, the link fd contained in ubus_context is added to the epoll descriptor set for monitoring
- Define ubus_subscriber instance and call ubus_register_subscriber to register it to ubusd
- Subscribe to the object of interest (Object)
- Use the uloop_run function to wait for the subscriber to broadcast the message.
For the notification sender (Notifier, Notification Sender)
- Call ubus_connect to link to ubusd to obtain ubus_context
- After ubus_add_uloop, the link fd contained in ubus_context is added to the epoll descriptor set for monitoring
- Define a notification object (ubus_object)
- ubus_add_object adds the notification object to ubusd
- When an event occurs, prepare the message type and parameters
- ubus_notify broadcasts the notification to ubusd
- Resource release
If you don't want to use ubus anymore, call ubus_free and uloop_done in turn to release the previously requested resources.
3) Event broadcast method: 1 to many
A is the broadcaster, B, C, D are the listeners
A broadcasts the event. If the event matches the listening messages of B, C, and D, the corresponding processing functions of B, C, and D are called.
Event is a broadcast message, and the sender of the event does not need to know who wants to receive this message. The status notification of the network card is implemented in this way, and anyone who cares about this event will receive and process it.
The implementation steps are similar to the previous two, only the different parts are introduced here.
For event recipients
- Define event listener ubus_event_handler
- Call ubus_register_event_handler to register the event handling mechanism
ubus_register_event_handler(ctx, ubus_event_handler, “eventA”);
For the event sender
- Fill blob_buf to construct event content
- Call ubus_send_event to broadcast the event
ubus_send_event(ctx, “eventA", b.head);
For the event sender
- Fill blob_buf to construct event content
- Call ubus_send_event to broadcast the event
ubus_send_event(ctx, “eventA", b.head);
references
https://www.cnblogs.com/sky-heaven/p/6394267.html