Uevent是一种在内核空间和用户空间之间通信的机制,主要用于热插拔事件(hotplug)。
uevent事件
根据include/linux/kobject.h中的定义,kobject对应的动作可分为以下几种:
enum kobject_action {
KOBJ_ADD,
KOBJ_REMOVE,
KOBJ_CHANGE,
KOBJ_MOVE,
KOBJ_ONLINE,
KOBJ_OFFLINE,
KOBJ_MAX
};
这些动作对应的事件相应有以下几种:
static const char *kobject_actions[] = {
[KOBJ_ADD] = "add",
[KOBJ_REMOVE] = "remove",
[KOBJ_CHANGE] = "change",
[KOBJ_MOVE] = "move",
[KOBJ_ONLINE] = "online",
[KOBJ_OFFLINE] = "offline",
};
说明:本文所有的源代码均取自内核2.6.32。
uevent环境变量
Uevent事件具体以环境变量(即字符串)的形式发送到用户空间。
struct kobj_uevent_env {
char *envp[UEVENT_NUM_ENVP]; /*环境变量指针数组*/
int envp_idx; /*数组下标*/
char buf[UEVENT_BUFFER_SIZE];
int buflen;
};
发送事件方法
在内核中通过kobject_uevent_env函数将事件发送到用户空间,但是实际上发送事件的动作由调用函数kobject_uevent_env实现。
/**
* kobject_uevent - notify userspace by ending an uevent
*
* @action: action that is happening
* @kobj: struct kobject that the action is happening to
*
* Returns 0 if kobject_uevent() is completed with success or the
* corresponding error when it fails.
*/
int kobject_uevent(struct kobject *kobj, enum kobject_action action)
{
return kobject_uevent_env(kobj, action, NULL);
}
EXPORT_SYMBOL_GPL(kobject_uevent);
kobject_uevent_env函数主要做了两方面的工作:
- 获取整理了与即将发送的事件相关的环境变量,如ACTION、DEVPATH和SUBSYSTE等。
- 发送事件到用户空间。
/**
* kobject_uevent_env - send an uevent with environmental data
*
* @action: action that is happening
* @kobj: struct kobject that the action is happening to
* @envp_ext: pointer to environmental data
*
* Returns 0 if kobject_uevent() is completed with success or the
* corresponding error when it fails.
*/
int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
char *envp_ext[])
{
struct kobj_uevent_env *env;
const char *action_string = kobject_actions[action];
const char *devpath = NULL;
const char *subsystem;
struct kobject *top_kobj;
struct kset *kset;
struct kset_uevent_ops *uevent_ops;
u64 seq;
int i = 0;
int retval = 0;
pr_debug("kobject: '%s' (%p): %s\n",
kobject_name(kobj), kobj, __func__);
/* search the kset we belong to */
top_kobj = kobj;
while (!top_kobj->kset && top_kobj->