linux设备模型的主要功能,Linux设备模型(3)
Linux设备模型(3)_Uevent
作者:蜗蜗 发布于:2014-3-10 20:39
分类:统一设备模型
1. Uevent的功能
Uevent是Kobject的一部分,用于在Kobject状态发生改变时,例如增加、移除等,通知用户空间程序。用户空间程序收到这样的事件后,会做相应的处理。
该机制通常是用来支持热拔插设备的,例如U盘插入后,USB相关的驱动软件会动态创建用于表示该U盘的device结构(相应的也包括其中的kobject),并告知用户空间程序,为该U盘动态的创建/dev/目录下的设备节点,更进一步,可以通知其它的应用程序,将该U盘设备mount到系统中,从而动态的支持该设备。
2. Uevent在kernel中的位置
下面图片描述了Uevent模块在内核中的位置:
由此可知,Uevent的机制是比较简单的,设备模型中任何设备有事件需要上报时,会触发Uevent提供的接口。Uevent模块准备好上报事件的格式后,可以通过两个途径把事件上报到用户空间:一种是通过kmod模块,直接调用用户空间的可执行文件;另一种是通过netlink通信机制,将事件从内核空间传递给用户空间。
注1:有关kmod和netlink,会在其它文章中描述,因此本文就不再详细说明了。
3. Uevent的内部逻辑解析
3.1 Source Code位置
Uevent的代码比较简单,主要涉及kobject.h和kobject_uevent.c两个文件,如下:
include/linux/kobject.h
lib/kobject_uevent.c
3.2 数据结构描述
kobject.h定义了uevent相关的常量和数据结构,如下:
kobject_action
1: /* include/linux/kobject.h, line 50 */
2: enum kobject_action {
3: KOBJ_ADD,
4: KOBJ_REMOVE,
5: KOBJ_CHANGE,
6: KOBJ_MOVE,
7: KOBJ_ONLINE,
8: KOBJ_OFFLINE,
9: KOBJ_MAX
10: };
kobject_action定义了event的类型,包括:
ADD/REMOVE,Kobject(或上层数据结构)的添加/移除事件。
ONLINE/OFFLINE,Kobject(或上层数据结构)的上线/下线事件,其实是是否使能。
CHANGE,Kobject(或上层数据结构)的状态或者内容发生改变。
MOVE,Kobject(或上层数据结构)更改名称或者更改Parent(意味着在sysfs中更改了目录结构)。
CHANGE,如果设备驱动需要上报的事件不再上面事件的范围内,或者是自定义的事件,可以使用该event,并携带相应的参数。
kobj_uevent_env
1: /* include/linux/kobject.h, line 31 */
2: #define UEVENT_NUM_ENVP 32 /* number of env pointers */
3: #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
4:
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: };
前面有提到过,在利用Kmod向用户空间上报event事件时,会直接执行用户空间的可执行文件。而在Linux系统,可执行文件的执行,依赖于环境变量,因此kobj_uevent_env用于组织此次事件上报时的环境变量。
envp,指针数组,用于保存每个环境变量的地址,最多可支持的环境变量数量为UEVENT_NUM_ENVP。
envp_idx,用于访问环境变量指针数组的index。
buf,保存环境变量的buffer,最大为UEVENT_BUFFER_SIZE。
buflen,访问buf的变量。
kset_uevent_ops
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是为kset量身订做的一个数据结构,里面包含filter和uevent两个回调函数,用处如下:
filter,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口过滤,阻止不希望上报的event,从而达到从整体上管理的目的。
name,该接口可以返回kset的名称。如果一个kset没有合法的名称,则其下的所有Kobject将不允许上报uvent
uevent,当任何Kobject需要上报uevent时,它所属的kset可以通过该接口统一为这些event添加环境变量。因为很多时候上报uevent时的环境变量都是相同的,因此可以由kset统一处理,就不需要让每个Kobject独自添加了。
3.3 内部动作
通过kobject.h,uevent模块提供了如下的API(这些API的实现是在"lib/kobject_uevent.c”文件中):
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[]);
5:
6: __printf(2, 3)
7: int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
8:
9: int kobject_action_type(const char *buf, size_t count,
10: enum kobject_action *type);
kobject_uevent_env,以envp为环境变量,上报一个指定action的uevent。环境变量的作用是为执行用户空间程序指定运行环境。具体动作如下:
查找kobj本身或者其parent是否从属于某个kset,如果不是,则报错返回(注2:由此可以说明,如果一个kobject没有加入kset,是不允许上报uevent的)
查看kobj->uevent_suppress是否设置,如果设置,则忽略所有的uevent上报并返回(注3:由此可知,可以通过Kobject的uevent_suppress标志,管控Kobject的uevent的上报)
如果所属的kset有uevent_ops->filter函数,则调用该函数,过滤此次上报(注4:这佐证了3.2小节有关filter接口的说明,kset可以通过filter接口过滤不希望上报的event,从而达到整体的管理效果)
判断所属的kset是否有合法的名称(称作subsystem,和前期的内核版本有区别),否则不允许上报uevent
分配一个用于此次上报的、存储环境变量的buffer(结果保存在env指针中),并获得该Kobject在sysfs中路径信息(用户空间软件需要依据该路径信息在sysfs中访问它)
调用add_uevent_var接口(下面会介绍),将Action、路径信息、subsystem等信息,添加到env指针中
如果传入的envp不空,则解析传入的环境变量中,同样调用add_uevent_var接口,添加到env指针中
如果所属的kset存在uevent_ops->uevent接口,调用该接口,添加kset统一的环境变量到env指针
根据ACTION的类型,设置kobj->state_add_uevent_sent和kobj->state_remove_uevent_sent变量,以记录正确的状态
调用add_uevent_var接口,添加格式为"SEQNUM=%llu”的序列号
如果定义了"CONFIG_NET”,则使用netlink发送该uevent
以uevent_helper、subsystem以及添加了标准环境变量(HOME=/,PATH=/sbin:/bin:/usr/sbin:/usr/bin)的env指针为参数,调用kmod模块提供的call_usermodehelper函数,上报uevent。
其中uevent_helper的内容是由内核配置项CONFIG_UEVENT_HELPER_PATH(位于./drivers/base/Kconfig)决定的(可参考lib/kobject_uevent.c, line 32),该配置项指定了一个用户空间程序(或者脚本),用于解析上报的uevent,例如"/sbin/hotplug”。
call_usermodehelper的作用,就是fork一个进程,以uevent为参数,执行uevent_helper。
kobject_uevent,和kobject_uevent_env功能一样,只是没有指定任何的环境变量。
add_uevent_var,以格式化字符的形式(类似printf、printk等),将环境变量copy到env指针中。
kobject_action_type,将enum kobject_action类型的Action,转换为字符串。
说明:怎么指定处理uevent的用户空间程序(简称uevent helper)?
上面介绍kobject_uevent_env的内部动作时,有提到,Uevent模块通过Kmod上报Uevent时,会通过call_usermodehelper函数,调用用户空间的可执行文件(或者脚本,简称uevent helper )处理该event。而该uevent helper的路径保存在uevent_helper数组中。
可以在编译内核时,通过CONFIG_UEVENT_HELPER_PATH配置项,静态指定uevent helper。但这种方式会为每个event fork一个进程,随着内核支持的设备数量的增多,这种方式在系统启动时将会是致命的(可以导致内存溢出等)。因此只有在早期的内核版本中会使用这种方式,现在内核不再推荐使用该方式。因此内核编译时,需要把该配置项留空。
在系统启动后,大部分的设备已经ready,可以根据需要,重新指定一个uevent helper,以便检测系统运行过程中的热拔插事件。这可以通过把helper的路径写入到"/sys/kernel/uevent_helper”文件中实现。实际上,内核通过sysfs文件系统的形式,将uevent_helper数组开放到用户空间,供用户空间程序修改访问,具体可参考"./kernel/ksysfs.c”中相应的代码,这里不再详细描述。
原创文章,转发请注明出处。蜗窝科技,www.wowotech.net。
评论:
2014-12-02 12:01
之前一直以为uevent_ops->uevent是完成具体的事件上报函数回调,误解为就是wowo开始所说的uevent机制。看了这篇文章和代码才知道这个callback的作用只是添加一个环境变量,名字比较迷惑人。
另外整个kernel中鲜有利用uevent的场景,所以uevent其实用处不大,更有用的是uevent_ops->filter回调。
说起环境变量上报,搞不清楚上报这些个环境变量的用处是什么,如果是上报Kobject在sysfs中路径信息倒是好理解,至于环境变量,用户空间处理程序(hotplug什么的)的执行需要上报的这些环境变量吗?
wowo
2014-12-02 13:27
@puppypyb:其实环境变量是使用usermodehelper的方式处理uevent时才会需要,如果使用的netlink的话,确实不需要。
环境变量存在的本质,是因为exec系列的“文件执行”函数需要(这也是Linux下文件执行的基础),这可以从do_execve(fs/exec.c)接口从看出:
int do_execve(const char *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)
至于kernel中uevent用处,还真不好说。如果你需要一些例子的话,可以去看看Android的switch class(drivers/switch/)。
我的观点是,如果软件设计的足够好,一定用不到uevent,poll机制足够了。如果poll解决不了,则说明设计者根本不知道event要上报给谁,才使用uevent的方式随便一扔,谁想收就收吧。
另外,无论是usermodehelper还是netlink的方式,uevent对系统性能是有影响的。特别是netlink的方式,上报的event会通知到所有的用户进程,所以还是少用为妙。
2014-12-02 14:27
@wowo:understood, thanks~
2014-10-28 23:10
注1:有关kmod和netlink,会在其它文章中描述,因此本文就不再详细说明了。
===>这两个在哪讲啊 啊?????
2014-10-28 23:17
@xxx:不好意思,还没有来得及写…
linux设备模型的主要功能,Linux设备模型(3)相关推荐
- 编程实现linux中的who命令功能,Linux who命令简介及使用方法详解
玩蛇网推荐图文教程:python 列表 本文是关于Linux who命令简介及使用方法详解一文.如果你是一名系统管理员,可能需要需要在一个特定的时间点都有谁活跃在系统上.以便必须严密监视我们的服务器. ...
- linux中umount命令的功能,Linux中的umount命令的详细解释
Linux下的umount命令的主要功能就是用来卸除文件系统,下面由学习啦小编为大家整理了linux下的umount命令的详细解释,希望对大家有帮助! Linux中的umount命令的详细解释 Lin ...
- linux中id命令的功能,Linux id命令参数及用法详解
Linux id命令参数及用法详解--Linux查看当前登陆用户uid,gid. 命 令:id 功能说明:查看显示目前登陆账户的uid和gid及所属分组及用户名 语 法:id [-g ...
- linux禁止系统ip源路由功能,linux 高级路由 ip rule
linux 高级路由即基于策略的路由比传统路由在功能上更强大,使用也更灵活,它不仅能够根据目的地址来转发路径而且也能够根据报文大小.应用或ip源地址来选择路由转发路径从而让系统管理员能轻松做到: 1. ...
- linux 编译配置内核路由功能,Linux下多播路由的实现-网管专栏,防火墙和路由
前言(只是一些废话,不想看的可以略过) ===================================== 多播路由是一个很好的技术,在internet上实现了对数据的"广播&quo ...
- linux查看是否开启审计功能,linux审计功能auditd
安全防护是首先要考虑的问题.为了避免别人盗取我们的数据,我们需要时刻关注它.安全防护包括很多东西, 我们知道auditd 的审计工具.这个工具在大多数Linux操作系统中是默认安装的.那么auditd ...
- linux中rm命令的功能,Linux中的rm命令
Linux系统中的rm命令用来删除文件或目录. 命令语法: rm [OPTION]... FILE... 命令参数: -f, --force 忽略不存在的文件,从不给出提示. -i, --int ...
- linux设备模型的主要功能,第 14 章 Linux 设备模型
第 14 章 Linux 设备模型 在 2.5 开发循环中一个声明的目标是为内核创建一个统一的设备模型. 之前的内核没有单一的数据结构, 使它们可以来获取关于系统如何整合的信息. 尽管缺乏信息, 有时 ...
- linux设备驱动程序架构的研究,Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介)...
Linux设备驱动程序学习(12) -Linux设备模型(底层原理简介) 以<LDD3>的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的.但是我个人认 ...
最新文章
- MySQL查询的进阶操作--分页查询
- File类获取功能的方法
- 17、字符设备控制技术
- 使用CreateFile读写文件
- leetcode - 375. 猜数字大小 II
- 列注释_技术贴 | 宏基因组分箱 (Binning)第四课——COG EC RNA注释统计
- Angular JS
- html菜鸟ruby,ruby的基础语法
- Zend Studio主题的设置
- 【Multisim】关于Multisim仿真“过零比较器”出现的问题以及解决方法
- C语言实现字符串转数字(包括负数)
- java查询时加上进度条插件,简单的jquery进度条插件LineProgressbar.js
- 计算机仿真系统模型有,计算机仿真在光伏发电系统模型中的应用研究原稿(最终定稿)...
- 测试u盘真假的手机软件,U盘真假怎么检测|教你检测U盘真假的方法
- 上海镇保城保四金比例
- 【Java笔记+踩坑】SpringBoot基础3——开发。热部署+配置高级+整合NoSQL/缓存/任务/邮件/监控
- 我的程序员成长之路——回顾自己三年的工作
- 电脑android模拟器下载地址,原神电脑版怎么下载 安卓模拟器电脑版下载地址
- Mysql创建Create Function
- python uiautomation 控件序号_使用python UIAutomation从QQ2016(8.0)群界面获取所有群成员详细资料,...
热门文章
- 阿里开发者们的第13个感悟:工程师需要在循环迭代中成长
- 2017双11交易系统TMF2.0技术揭秘,实现全链路管理
- 万物互联下的碎片化怎么破?UINO优锘推出物联网产业元宇宙“物联森友会”
- 00后确实卷,公司新来的卷王,我们这帮老油条真干不过.....
- 山石网科发布重磅容器安全产品“山石云铠”,云安全版图再下一城
- 使用 SQL 语句实现一个年会抽奖程序
- 在Java虚拟机上班是一种怎样的体验?
- 领航智变时代 2020 NAVIGATE领航者峰会云上起航
- Spring精华问答 | Spring 能帮我们做什么?
- ZStack张鑫:面对混合云浪潮 我们主动出击