内核中的uevent

uevent(user space event) 是 内核 提供的一个机制,属于 kobject 中的一个技术实现,代码在lib/kobject_uevent.c
Uevent是Kobject的一部分,用于在Kobject状态发生改变时,通知用户空间进程
改变是什么ADD/REMOVE,Kobject(或上层数据结构)的添加/移除事件。ONLINE/OFFLINE,Kobject(或上层数据结构)的上线/下线事件,其实是是否使能。CHANGE,Kobject(或上层数据结构)的状态或者内容发生改变。MOVE,Kobject(或上层数据结构)更改名称或者更改Parent(意味着在sysfs中更改了目录结构)。CHANGE,如果设备驱动需要上报的事件不再上面事件的范围内,或者是自定义的事件,可以使用该event,并携带相应的参数。1.内核如何向用户空间通信(上报uevent事件)lib/kobject_uevent.ckobject_ueventkobject_uevent_env2.用户空间控制内核给用户空间通信sysfs 下的很多 kobject 下都有 uevent 属性,它主要用于内核与udev/mdev或其他用户空间进程之间的一个通信接口,将sysfs挂载到/sys, uevent属性就变为了可见的文件内核将 uevent 机制暴露给了用户空间(对应/sys下的uevent文件) , 让用户空间控制内核给用户空间通信在每个注册的device文件夹下会生成一个uevent属性文件drivers/base/core.cuevent_storeuevent_showstatic DEVICE_ATTR_RW(uevent);/sys下的uevent文件支持写入的参数有 "add","remove","change","move","online","offline"写入 "add",这样内核就会调用 uevent_store -> kobject_ueventA.通信中的信息内容???

内核uevent的消费者

1.内核如何向用户空间通信 的消费者主要用于设备驱动模型中热插拔设备或设备状态变化时。该机制通常是用来支持热拔插设备的,device_createdevice_create_vargs(class, parent, devt, drvdata, fmt, vargs);device_register(dev);device_add(dev);kobject_uevent(&dev->kobj, KOBJ_ADD);kobject_uevent_env(kobj, action, NULL);   // action = KOBJ_ADD2.用户空间控制内核给用户空间通信 的消费者可用于实现手动触发hotplug(手动触发hotplug就是coldplug)可用于 udevmonitor 通过内核向 udevd (udev 后台程序)发送消息也可用于检查设备本身所支持的 netlink 消息上的环境变量也可用于开发人员调试 udev 规则文件,udevtrigger 这个调试工具本身就是以写各设备的 uevent 属性文件实现的。

内核uevent的性能

无论是usermodehelper还是netlink的方式,uevent对系统性能是有影响的。
特别是netlink的方式,上报的event会通知到所有的用户进程,所以还是少用为妙

内核uevent的底层实现


当消费者调用kobject_uevent上报事件时,kobject_uevent会根据配置不同,主要有两个代码路径一种是通过kmod模块,直接调用用户空间的可执行文件;一种是通过netlink通信机制,将事件从内核空间传递给用户空间
  • kmod
Uevent模块通过Kmod上报Uevent时,会通过call_usermodehelper函数
调用用户空间的可执行文件(或者脚本,简称uevent helper,目前2021年1月18日 一般为mdev)处理该event。kobject_uevent(&dev->kobj, KOBJ_ADD);kobject_uevent_env(kobj, action, NULL);   // action = KOBJ_ADDconst char *action_string = kobject_actions[action];    // action_string = "add"//把相关信息存到环境变量里,环境变量是内核在调用mdev之前设置的// ACTION代表操作类型// DEVPATH为设备在class下存在的路径// SUBSYSTEM为class_create创建的设备类//ACTION=add , DEVPATH=/class/test/test_dev , SUBSYSTEM=testadd_uevent_var(env, "ACTION=%s", action_string);add_uevent_var(env, "DEVPATH=%s", devpath);add_uevent_var(env, "SUBSYSTEM=%s", subsystem);init_uevent_argv/* 调用应用程序:比如mdev *//* 在/etc/init.d/rcS 中的echo /sbin/mdev > /proc/sys/kernel/hotplug指定了应用程序*/call_usermodehelper_setupcall_usermodehelper_exec从上面的调用关系可以看出,最终内核会调用/proc/sys/kernel/hotplug 中指定的
程序(一般会配置为/sbin/mdev),并且使用该程序的环境变量
  • netlink
Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC)也是网络应用程序与内核通信的最常用的接口。是一种特殊的 socket是 Linux 所特有的,类似于 BSD 中的AF_ROUTE 但又远比它的功能强大是一种在内核与用户应用间进行双向数据传输的非常好的方式
Netlink套接字的消费者目前在Linux 内核中使用netlink 进行应用与内核通信的应用很多
Netlink套接字实例路由 daemon(NETLINK_ROUTE),用户态 socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),netfilter 子系统(NETLINK_NETFILTER),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用 netlink(NETLINK_GENERIC)Netlink使用实例用户态    应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用 netlink。Netlink特点1.netlink使用简单,只需要在include/linux/netlink.h中增加一个新类型的 netlink 协议定义即可,(如 #define NETLINK_TEST 20 )然后,内核和用户态应用就可以立即通过 socket API 使用该 netlink 协议类型进行数据交换);2.netlink是一种异步通信机制,在内核与用户态应用之间传递的消息保存在socket缓存队列中发送消息只是把消息保存在接收者的socket的接收队列,而不需要等待接收者收到消息;3.使用 netlink 的内核部分可以采用模块的方式实现使用 netlink 的应用部分和内核部分没有编译时依赖;4.netlink 支持多播,内核模块或应用可以把消息多播给一个netlink组属于该neilink 组的任何内核模块或应用都能接收到该消息内核事件向用户态的通知机制就使用了这一特性5.内核可以使用 netlink 首先发起会话

对应内核uevent的用户空间实现

  • mdev ----对应kmod

1. mdev怎么处理coldplug的只要是用户空间处理创建设备文件,就会有冷插拔的问题在启动脚本rcS中会有这样一句命令/sbin/mdev -s1. 扫描/sys目录里所有的uevent属性文件,向其写入"add”命令,触发uevent事件2. 内核调用 call_usermodehelper (argv[0], argv, envp, 0); fork mdev3. mdev 根据 参数  创建设备文件2. mdev 怎么处理hotplug // mdev 不会自动加载驱动1. 内核创建device,同时触发uevent事件2. 内核调用 call_usermodehelper (argv[0], argv, envp, 0); fork mdev3. mdev 根据 参数  创建设备文件A.mdev的函数调用路径int mdev_main(int argc UNUSED_PARAM, char **argv)xchdir("/dev");  // 先把目录改变到/dev下if (argv[1] && strcmp(argv[1], "-s") == 0) {  // 对应coldplug,这个路径 是 初始化脚本里面 mdev -s  走的路径// 在文件系统启动的时候会调用 mdev -s,创建所有驱动设备节点putenv((char*)"ACTION=add"); // mdev -s 的动作是创建设备节点,所以为addif (access("/sys/class/block", F_OK) != 0) { // 当/sys/class/block目录不存在时,才扫描/sys/block/* Scan obsolete /sys/block only if /sys/class/block* doesn't exist. Otherwise we'll have dupes.* Also, do not complain if it doesn't exist.* Some people configure kernel to have no blockdevs.*/recursive_action("/sys/block",ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET,fileAction, dirAction, temp, 0);}/* * 这个函数是递归函数,它会扫描/sys/class目录下的所有文件,如果发现dev文件,将按照* /etc/mdev.conf文件进行相应的配置。如果没有配置文件,那么直接创建设备节点 * 最终调用的创建函数是 make_device*/recursive_action("/sys/class",    ACTION_RECURSE | ACTION_FOLLOWLINKS,fileAction, dirAction, temp, 0);}else{ // 对应hotplug,这个路径 是 内核 kmod 机制 uevent_helper 走的路径// 获得环境变量,环境变量是内核在调用mdev之前设置的env_devname = getenv("DEVNAME"); /* can be NULL */G.subsystem = getenv("SUBSYSTEM");action = getenv("ACTION");env_devpath = getenv("DEVPATH");snprintf(temp, PATH_MAX, "/sys%s", env_devpath);make_device(env_devname, temp, op);}
  • udev ----对应netlink
是 netlink 对应的用户空间进程实现
具体请查看 https://blog.csdn.net/u011011827/article/details/112741721

linux 设备管理 (五) uevent相关推荐

  1. Linux设备管理(一)_kobject, kset,ktype分析

    Linux设备管理(一)_kobject, kset,ktype分析 转载:https://www.cnblogs.com/xiaojiang1025/p/6193959.html Linux内核大量 ...

  2. linux设备管理之设备号与次设备号

    linux设备管理之主设备号与次设备号 - jinzi - 博客园+ 剽窃 过来的.  记录下,以备查. 主设备号和次设备号 一个字符设备或者块设备都有一个主设备号和次设备号.主设备号和次设备号统称为 ...

  3. Linux设备管理: kobject、kset、ktype分析

    Linux 内核大量使用面向对象的设计思想,通过追踪源码,我们甚至可以使用面向对象语言常用的 UML 类图来分析 Linux 设备管理的"类"之间的关系.这里以 4.14 内核为例 ...

  4. 《sed的流艺术之四》-linux命令五分钟系列之二十四

    [正文开始] 上文接<sed的流艺术之三>-linux命令五分钟系列之二十三 例十 如果设定了很多-e的command,它们的执行顺序是怎样的呢? [rocrocket@rocrocket ...

  5. Linux(五):Ubuntu 16.04 更改系统语言为简体中文(Chinese simplified)

    Linux(五):Ubuntu 16.04 更改系统语言为简体中文(Chinese simplified) 文章目录 1 问题 2 设置中文 2.1 设置: 2.2 点击 Install: 2.3 输 ...

  6. Linux的五个查找命令

    原文地址http://www.ruanyifeng.com/blog/2009/10/5_ways_to_search_for_files_using_the_terminal.html Linux的 ...

  7. 从零开始的linux 第五章

    从零开始的linux 第五章 (咚咚咚...)路人甲:"小编!!快起床!!今天该讲课啦!" (迷迷糊糊且衣冠不整的小编去开门) 路人甲:"小...小编大人...你都让我这 ...

  8. Linux 下五个顶级的开源命令行 Shell

    这个世界上有两种 Linux 用户:敢于冒险的和态度谨慎的. 其中一类用户总是本能的去尝试任何能够戳中其痛点的新选择.他们尝试过不计其数的窗口管理器.系统发行版和几乎所有能找到的桌面插件. 另一类用户 ...

  9. Linux设备管理(三)_总线设备的挂接

    扒完了字符设备,我们来看看平台总线设备,平台总线是Linux中的一种虚拟总线,我们知道,总线+设备+驱动是Linux驱动模型的三大组件,设计这样的模型就是将驱动代码和设备信息相分离,对于稍微复杂一点的 ...

最新文章

  1. Java中IO和NIO的本质和区别
  2. 向Access中插入数据报“INSERT INTO 语句的语法错误” 解决
  3. sql 某列数据全部为0则不显示该列_数据产品经理养成记(五):汇总分析
  4. centos6.8升级python3.5.2
  5. ajax请求成功后返回值如何赋值给js变量
  6. js常用设计模式实现(一)单例模式
  7. Microsoft® .NET Micro Framework简介
  8. linux下activityMQ安装
  9. 计算机专业英语影印版试题,计算机专业英语(2008影印版)复习资料
  10. AppStore 预览图制作
  11. CleanMyMac X下载Mac系统清理优化工具
  12. 盛世昊通谈跨界造车风潮,不同车企到底打什么主意
  13. 【Quant】80+面试,5个offer,Quant大神总结分享各家quant面试题
  14. ESXi 6 升级到ESXi 6.5VIB冲突问题
  15. python 操作 word 文件
  16. Swagger报错:missed comma between flow collection entries
  17. 宝宝大战落幕,互联网金融二战爆发
  18. 从两个角度谈谈:什么是产品视角
  19. 面试题:堆、栈、队列的区别以及使用场景
  20. 案例:淘宝点击关闭二维码

热门文章

  1. 【行研报告】2021中国新能源汽车市场洞察报告——附下载链接
  2. 图像处理---逆滤波和维纳滤波
  3. matlab中randint函数替代randi函数
  4. 大连医疗保险药物目录
  5. 2018第九届蓝桥杯JavaB组省赛真题及详解
  6. 拿到这份“小抄”,Amazon面试妥了
  7. 渗透测试之Webshell
  8. 【Ziv Bar-Joseph教授课件】计算生物学:序列比对与剖面HMMs
  9. gitlab如何创建用户并登录
  10. Javascript之字节跳动 浮点数与十六进制互相转换 有符号整数与十六进制互相转换 速度超快