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模块在内核中的位置:

51795963_1.gif

由此可知,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:不好意思,还没有来得及写…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lua_path环境变量设置linux,ubuntu16.04安装lua环境

1.官网下载源码 https://www.lua.org/download.htmlcurl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gztar zxf lua-5.3.5.tar.gzcd lua-5.3.5make linux test2.安装中报错lua.c:82:31: fatal error: readline/readline.h: 没有那个文件或目录compilation terminated.: recip…

皮尔洛和c罗讲什么语言,皮尔洛:如果我跟C罗是队友 我可能能成历史助攻王

皮尔洛:欧冠夺冠热门不包含皇马腾讯体育11月2日讯 近日皮尔洛在接受媒体采访时表示,本赛季欧冠的争夺将会十分激烈,除了尤文外,有四支球队也是欧冠桂冠有利的争夺者,但并不包括卫冕冠军皇马。另外皮尔洛还表示&#xf…

android 调用系统短信接口开发,聚合数据Android SDK 短信api接口验证演示示例

1.到libs聚合SDK是聚合数据平台,为移动开发者提供的免费数据接口.使用前请先到聚合平台(http://www.juhe.cn/)注册,申请相关数据.2.下载聚合数据SDK,将开发包里的smscaptcha_sdk_v_1_1.jar拷贝到libs根目录下,将libJuheSDK_v_1_0.so拷贝到libs\armeabi目录下,如图:3…

代码混淆android.mk,利用ollvm进行代码混淆

OLLVM简介OLLVM(Obfuscator-LLVM)是瑞士西北应用科技大学于2010年6月份发起的一个项目,该项目旨在提供一套开源的针对LLVM的代码混淆工具,以增加对逆向工程的难度。OLLVM是基于LLVM实现的,LLVM是一个编译器框架,它也采用经典的三段…

鸿蒙系统的适配国产手机,真正的好消息!其它国产机,也在适配华为鸿蒙系统...

众所周知,据华为消费者业务软件部总裁王成录的说法,今年6月初,华为手机就能全面升级鸿蒙2.0,迟到近两年的、真正的“一夜之间就可以替换掉安卓”。而近日,又传出了真正的好消息,那就是其它国产手机厂商&…

三星s4 android 6.0吗,快了 三星手机适配Android 6.0时间公布

快了 三星手机适配Android 6.0时间公布2016年01月26日 00:04作者:董岩编辑:董岩文章出处:泡泡网原创分享作为全球范围内无可争议的安卓手机巨头之一,三星在为其旗下手机适配安卓新系统方面历来算是相当上心的一个厂家。日前就已经…

xrdpdf卡片在哪可下载_暑假学习英语字母,就是这样简单(附可打印字母卡下载)...

英语字母是所有英语学习的基础,所以,要想学好英语,第一步,必须是学好字母,为后面的更深层次的学习打下坚实的根基。今天,我们给大家分享最全面的英文字母学习法,建议收藏,文章最后附…

32 位的有符号整数_leetcode 7 整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。示例 1:输入: 123 输出: 321示例 2:输入: -123 输出: -321示例 3:输入: 120 输出: 21注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根…

安卓帧数监测软件_扬尘在线监测系统实现工地智能监控

近年来,随着越来越多的建设项目在建设中,建筑工地越来越广泛。传统人力检查的检查结果主要依靠估计,难以量化和分析,导致相应处罚的科学依据不足。扬尘在线监测系统实现了对施工现场的智能检测,可以对施工现场扬尘进行…

html 切换主题,html切换主题实现方案

方案一使用css的var属性,当然此时不考虑低版本浏览器。1,在default.css主题根元素定义颜色变量:root {--main_color: #03a9f4; // 主题色--main_light: #33baf7; // 二级主题色 常用背景为主题色下的hover--main_lighter: #65caf5; // 三级主题色 常用bo…

json取数据怎么取_干货速递丨书名应该怎么取?

很多作者开书前都会遇到这个困扰:“什么样的书名是好的?”在跟一线编辑广泛交流后,大家普遍认为:一个好书名,既应该是能突出作品内容特点、故事主题,又具有一定的趣味性的,能吸引读者&#xff0…

android加一减一控件,Android的步进器(增加/减少值)控件?

用于Android的步进器(增/减值)控件?没有像Android中的Stepper这样的内置控件但是您可以尝试这种方式android:layout_width"wrap_content"android:background"#ffffff"android:layout_height"wrap_content"android:orientation"h…

安装教程rtx2080ti_点云深度学习环境配置指南(一)Ubuntu16.04+RTX2080ti

【今日导读】想做点云深度学习?先把环境配置好吧。本期为初学者带来环境配置指南,有需求的同学赶快上手吧。配置为:Ubuntu16.04RTX2080tiNVIDIA驱动cuda10.1cudnn7.5。一、安装NVIDIA驱动法一(优先推荐):先添加NVIDIA 的ppa 源&am…

计算机管理员相关知识,计算机管理员述职报告范文

计算机管理员述职报告范文计算机管理员述职报告范文尊敬的医院领导:我叫xxx,20xx年7月毕业于西南计算机科学与技术专业。20xx年8月到医院工作,从事网络管理工作已有4年时间,能够胜任本职工作,现将任职以来的主要工作报…

计算机网络5g,计算机网络参考模型与5G协议

一、分层思想将复杂的流程分解为几个功能相对单一的子过程(1)整个流程更加清晰,复杂问题简单化(2)更容易发现问题并针对性的解决问题二、OSI七层参考模型1984年颁布了开发系统互连(OSI)参考模型;一个开放式体系结构,将网络分为七层分层功能物…

双百双新产业项目是什么_投资380亿,广西38个“双百双新”产业项目开竣工

广西2020年四季度“双百双新”产业项目集中开竣工活动现场。图片由自治区工信厅提供柳州分会场视频连线。图片由自治区工信厅提供与会嘉宾。图片由自治区工信厅提供广西新闻网南宁12月8日讯(记者 谢琳琳)12月8日,广西举行2020年四季度“双百双新”产业项目集中开竣工…

else 策略模式去掉if_业务复杂=if else?刚来的大神竟然用策略+工厂彻底干掉了他们!...

​对于业务开发来说,业务逻辑的复杂是必然的,随着业务发展,需求只会越来越复杂,为了考虑到各种各样的情况,代码中不可避免的会出现很多if-else。一旦代码中if-else过多,就会大大的影响其可读性和可维护性。…

istio springcloud_手牵手一起学Springcloud(1)微服务这么流行,你理解了嘛?

在前一段时间,我们实验室的项目开始变得越来越麻烦,代码也越来越臃肿,一个人兼顾前后端的全栈开发,实在是力不从心,没有一点点幸福感,于是迫切的想要解放生产力,放飞自我,因此开始决…

力改变物体形状举例_人教版八年级物理下册第七章《力》知识点大全

力是物体对物体的作用,比如推土机推动了土。知识点1:力1.概念:是物体对物体的作用叫做力。2.特点:物体间力的作用是相互的。3.力的单位和表示符号:(1)力的单位:牛顿,简称牛(N)。托起一个鸡蛋大约…

bool类型数组转换成一个整数_Go 学习笔记 02 | 基本数据类型以及 byte 和 rune 类型...

一、基本数据类型unsafe.Sizeof() 查看不同长度的整型在内存中的存储空间。 类型转换,高位向低位转换要注意溢出。数字字面量语法。64 位系统中 Go 语言中浮点数默认是 float64。二、Golang 中 float 精度丢失问题利用第三方包:http://github.com/shopsp…