Turn from: HTTP://WWW.WOWOTECH.NET/DEVICE_MODEL/UEVENT.HTML1. Features of the Uevent
Uevent is a part of Kobject that notifies the user of a space program when the Kobject state changes, such as adding, removing, and so on. After the user space program receives such an event, it will do the appropriate processing.
This mechanism is usually used to support hot-swappable devices, such as USB flash drive after the insertion of the driver software will be dynamically created to represent the device structure (including the corresponding kobject), and inform the user space program, for the USB flash drive to create the/dev/directory of the device node, Further, the device can be dynamically supported by notifying other applications to mount the USB drive device to the system.
2. Location of the uevent in kernel
The following picture depicts the location of the Uevent module in the kernel:
It can be concluded that the uevent mechanism is relatively simple, and any device in the device model that has an event to escalate will trigger the interface provided by the uevent. After the Uevent module is ready for the format of the escalation event, the event can be escalated to user space in two ways: one is to invoke the executable file of the user space directly through the Kmod module, and the other is to pass the event from the kernel space to the user space through the NetLink communication mechanism.
Note 1: For Kmod and NetLink, they are described in other articles, so this article is not explained in detail.
3. Uevent internal Logic parsing 3.1 Source code location
Uevent code is relatively simple, mainly related to Kobject.h and kobject_uevent.c two files, as follows:
- Include/linux/kobject.h
- Lib/kobject_uevent.c
3.2 Data Structure description
Kobject.h defines uevent-related constants and data structures, as follows:
1:/* include/linux/kobject.h, line 50 */
2:enum Kobject_action {
3:kobj_add,
4:kobj_remove,
6:kobj_move,
8:kobj_offline,
10:};
Kobject_action defines the type of event, including:
Add/Remove events for Add/remove,kobject (or upper-level data structures).
Online/offline,kobject (or upper-level data structure) of the on/off event, in fact, is whether to enable.
The state or content of the change,kobject (or upper-layer data structure) has changed.
Move,kobject (or upper-level data structure) changes the name or changes the parent (meaning that the directory structure is changed in SYSFS).
Change, if the device driver needs to escalate an event that is no longer within the scope of the above event, or is a custom event, you can use that event and carry the corresponding parameter.
1:/* include/linux/kobject.h, line 31 */
2: #define UEVENT_NUM_ENVP/* Number of env pointers */
3: #define UEVENT_BUFFER_SIZE 2048/* BUFFER for the variables */
5:/* include/linux/kobject.h, line 116 */
6:struct kobj_uevent_env {
7:char *ENVP[UEVENT_NUM_ENVP];
8:int Envp_idx;
9:char Buf[uevent_buffer_size];
10:int Buflen;
11:};
As mentioned earlier, when using Kmod to escalate event events to user space, the executable file for user space is executed directly. In Linux systems, executable execution relies on environment variables, so kobj_uevent_env is used to organize the environment variables when this event is escalated.
ENVP, an array of pointers that holds the address of each environment variable, and the maximum number of environment variables that can be supported is UEVENT_NUM_ENVP.
Envp_idx, which is used to access the index of an array of environment variable pointers.
BUF, save the BUFFER of the environment variable, the maximum is uevent_buffer_size.
Buflen, accesses the BUF variable.
1:/* include/linux/kobject.h, line 123 */
2:struct Kset_uevent_ops {
3:int (* const filter) (struct Kset *kset, struct kobject *kobj);
4:const char * (* const name) (struct kset *kset, struct kobject *kobj);
5:int (* const uevent) (struct kset *kset, struct kobject *kobj,
6:struct kobj_uevent_env *env);
7:};
Kset_uevent_ops is a data structure tailored for kset that contains the filter and uevent two callback functions, which are useful as follows:
Filter, when any kobject need to escalate uevent, it belongs to the Kset can be filtered through the interface, to block the event that does not want to escalate, so as to achieve overall management purposes.
Name, which can return the name of the Kset. If a kset does not have a valid name, then all Kobject under it will not be allowed to escalate uvent
Uevent, when any kobject need to escalate uevent, the kset to which it belongs can add environment variables for these event unification through this interface. Because the environment variables are the same in many cases when the uevent is reported, it can be handled uniformly by kset, so you don't have to add each kobject alone.
3.3 Internal action
The following APIs are provided through the Kobject.h,uevent module (the implementation of these APIs is in the "lib/kobject_uevent.c" file):
1:/* include/linux/kobject.h, line 206 */
2:int kobject_uevent (struct kobject *kobj, enum kobject_action action);
3:int kobject_uevent_env (struct kobject *kobj, enum kobject_action action,
4:char *envp[]);
6: __printf (2, 3)
7:int Add_uevent_var (struct kobj_uevent_env *env, const char *format, ...);
9:int kobject_action_type (const char *BUF, size_t count,
10:enum kobject_action *type);
Kobject_uevent_env, with ENVP as the environment variable, escalate a uevent of the specified action. The role of environment variables is to specify the operating environment for executing user-space programs. The specific actions are as follows:
- Find kobj itself or whether its parent belongs to a kset, if not, the error is returned (Note 2: This can be explained, if a kobject does not join the Kset, is not allowed to escalate uevent)
- Check if Kobj->uevent_suppress is set, and if set, ignore all uevent escalation and return (Note 3: It can be seen through the uevent_suppress flag of Kobject, Control Kobject of the uevent of the report)
- If the owning Kset has a uevent_ops->filter function, the function is called. Filter this escalation (Note 4: This confirms the 3.2 section about the filter interface, Kset can filter the event that does not want to escalate, so as to achieve the overall management effect)
- Determine if the owning Kset has a valid name (called subsystem, which differs from the previous kernel version), otherwise it is not allowed to escalate uevent
- Assign a buffer to store the environment variables for this escalation (the result is stored in the env pointer) and get the kobject in the SYSFS path information (the user space software needs to access it in SYSFS based on the path information)
- Call the Add_uevent_var interface (described below) to add the action, path information, subsystem, and so on to the env pointer
- If the incoming envp is not empty, the incoming environment variable is parsed, and the Add_uevent_var interface is also called, which is added to the env pointer
- If the owning Kset exists Uevent_ops->uevent interface, call the interface, add kset uniform environment variable to the ENV pointer
- Depending on the type of action, set the kobj->state_add_uevent_sent and kobj->state_remove_uevent_sent variables to record the correct state
- Call the Add_uevent_var interface and add a serial number formatted as "Seqnum=%llu"
- If "config_net" is defined, the uevent is sent using NetLink
- The Uevent_helper, subsystem, and the env pointer with the standard environment variable (home=/,path=/sbin:/bin:/usr/sbin:/usr/bin) as parameters, invoke the Call_ provided by the Kmod module. Usermodehelper function, escalation uevent.
The content of Uevent_helper is determined by the kernel configuration item Config_uevent_helper_path (located at./drivers/base/kconfig) (refer to lib/kobject_uevent.c, line 32 ), the configuration item specifies a user-space program (or script) that resolves the escalated uevent, such as "/sbin/hotplug".
The function of Call_usermodehelper is to fork a process, take uevent as parameter, execute uevent_helper.
Kobject_uevent, like the kobject_uevent_env function, simply does not specify any environment variables.
Add_uevent_var, copy the environment variables into the env pointer in the form of formatted characters (like printf, PRINTK, etc.).
Kobject_action_type, converts an action of enum kobject_action type to a string.
Description: How to specify the user space program to handle uevent (Uevent helper)?
The above describes the internal action of kobject_uevent_env, it is mentioned that the Uevent module through Kmod escalation uevent, through the Call_usermodehelper function, call the user space executable file (or script, short Uevent helper ) to handle the event. The path to the Uevent helper is saved in the uevent_helper array.
You can statically specify Uevent HELPER when compiling the kernel through Config_uevent_helper_path configuration items. But this approach will fork a process for each event, and this will be fatal when the system boots (which can cause memory overflow, etc.) as the number of devices supported by the kernel increases. So only in earlier versions of the kernel would this be used, and now the kernel is no longer recommended for this approach. Therefore, when the kernel compiles, the configuration item needs to be left blank.
After the system starts, most of the devices are ready, and you can reassign a uevent helper as needed to detect hot-plug events during system operation. This can be done by writing the helper's path to the "/sys/kernel/uevent_helper" file. In fact, the kernel through the form of the Sysfs file system, the uevent_helper array open to user space for user space program modification access, the specific reference "./kernel/ksysfs.c" in the corresponding code, which is no longer described in detail. |
Original articles, forwarded please indicate the source. Snail Nest technology, www.wowotech.net.
Linux device Model (3) _uevent "Go"