在/sys/devices/ 下面的每一个device都有一个uevent attr,这个是rw的,通过cat uevent 可以知道这个device 已经向上层发送的event时间,向这个写的话,则可以向上层发送uenvent事件
linux-81uf:/sys/devices/pci0004:88 # ls -al
total 0
drwxr-xr-x 5 root root 0 Jun 19 02:33 .
drwxr-xr-x 18 root root 0 Jun 19 02:33 ..
drwxr-xr-x 4 root root 0 Jun 19 02:33 0004:88:00.0
lrwxrwxrwx 1 root root 0 Jun 20 04:47 firmware_node -> ../LNXSYSTM:00/LNXSYBUS:00/PNP0A08:01
drwxr-xr-x 3 root root 0 Jun 19 02:33 pci_bus
drwxr-xr-x 2 root root 0 Jun 20 04:47 power
-rw-r--r-- 1 root root 4096 Jun 19 02:33 uevent
linux-81uf:/sys/class/infiniband/hns_0 # ls
device node_desc node_type power sys_image_guid
fw_ver node_guid ports subsystem uevent
linux-81uf:/sys/class/infiniband/hns_0 # cat uevent
NAME=hns_0
与其对应的代码在drivers/base/core.c 中
对应的read函数
static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct kobject *top_kobj;
struct kset *kset;
struct kobj_uevent_env *env = NULL;
int i;
size_t count = 0;
int retval;
/* search the kset, the device belongs to */
top_kobj = &dev->kobj;
while (!top_kobj->kset && top_kobj->parent)
top_kobj = top_kobj->parent;
if (!top_kobj->kset)
goto out;
kset = top_kobj->kset;
if (!kset->uevent_ops || !kset->uevent_ops->uevent)
goto out;
/* respect filter */
if (kset->uevent_ops && kset->uevent_ops->filter)
if (!kset->uevent_ops->filter(kset, &dev->kobj))
goto out;
env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
if (!env)
return -ENOMEM;
/* let the kset specific function add its keys */
retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
if (retval)
goto out;
/* copy keys to file */
for (i = 0; i < env->envp_idx; i++)
count += sprintf(&buf[count], "%s\n", env->envp[i]);
out:
kfree(env);
return count;
}
对应的写函数
static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
enum kobject_action action;
if (kobject_action_type(buf, count, &action) == 0)
kobject_uevent(&dev->kobj, action);
else
dev_err(dev, "uevent: unknown action-string\n");
return count;
}
static DEVICE_ATTR_RW(uevent);
对应的event事件如下
static const char *kobject_actions[] = {
[KOBJ_ADD] = "add",
[KOBJ_REMOVE] = "remove",
[KOBJ_CHANGE] = "change",
[KOBJ_MOVE] = "move",
[KOBJ_ONLINE] = "online",
[KOBJ_OFFLINE] = "offline",
};