uevent, user space event. 内核与用户空间的一种通信机制,基于netlink机制,主要用于设备驱动模型,例如热插拔。

1、调用/sbin/mdev的流程分析

在驱动程序中经常出现class_device_create这个函数,它用来在/dev目录下创建各个设备的设备节点,那么,这个是怎么实现的呢?下面就来分析这个过程的实现,直接进到class_device_create函数中层层分析它。

class_device_create
class_device_register
class_device_add
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
kobject_uevent_env(kobj, action, NULL);
// action_string = "add";
action_string = action_to_string(action);
/* 分配、保存环境变量的内存 */
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL); /* 设置环境变量 */
nvp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action_string) + ;
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + ;
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + ; /* 调用应用程序:比如mdev */
/* 在/etc/init.d/rcS 中的echo /sbin/mdev > /proc/sys/kernel/hotplug指定了应用程序*/
argv [] = uevent_helper; // = "/sbin/mdev"
argv [] = (char *)subsystem;
argv [] = NULL;
call_usermodehelper (argv[], argv, envp, );

从上面的调用关系可以看出,最终内核会调用用户空间的/sbin/mdev程序,并且使用该程序的环境变量。

2、mdev源码分析

接下来看到busy_box下的mdev机制的实现,直接看到mdev.c文件,列出调用关系:

mdev_main
temp = "/sys/class/buttons/buttons"
make_device(temp, );
/* 确定设备文件名,类型,主设备号,次设备号 */
path = "/sys/class/buttons/buttons"
device_name = bb_basename(path); = "buttons"
type = path[]=='c' ? S_IFCHR : S_IFBLK; // ='c'是字符设备节点 根据 "/sys/class/buttons/buttons/dev"的内容确定主次设备号
mknod(device_name, mode | type, makedev(major, minor)

从上面的调用关系可以看出mdev最终通过mknod生成了设备节点

3、利用mdev机制实现U盘的挂接

分析mdev源码可以知道,它还可以根据/etc/mdev.conf这个配置文件来执行某个命令,这个文件的格式如下:

mdev.conf的格式:
<device regex> <uid>:<gid> <octal permissions> [<@|$|*> <command>]

每个字段的含义如下:

device regex:正则表达式,表示哪一个设备
uid:owner
gid:组id
octal permissions:以八进制表示的属性
@ :创建设备节点之后执行命令
$: 删除设备节点之前执行命令
* :创建设备节点之后执行命令 和 删除设备节点之前执行命令
command:要执行的命令

正则表达式的介绍如下:

正则表达式:
、在电脑上查文件,*.c(*表示通配符,表示任意字符)
、用正则表达式
.表示任意字符(换行符除外)
*表示重复0次或更多次
+重复1次或更多次
?重复0次或1次
[...]表示中括号里面的字符的某一个

假设需要自动挂载U盘,它的/etc/mdev.conf可以这么写:

sda[-]+ :  * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt;else umount /mnt; fi

其中sda[1-9]+表示sda1-sda9中的一个或多个。后面跟着shell命令,如果是有U盘加载的话,那么挂接到/mnt上,否则的话,就卸载。

当然也可以把shell命令写成脚本的形式,脚本存放在/bin/add_remove_udisk.sh

sda[-]+ :  * /bin/add_remove_udisk.sh

/bin/add_remove_udisk.sh
#!/bin/sh
if [ $ACTION = "add" ];
then
mount /dev/$MDEV /mnt;
else
umount /mnt;
fi

最新文章

  1. linux 系统、命令、软件
  2. python 2.7 学习笔记--day1--基础语句和语法
  3. Oracle Database 12c Release 1下载安装(自身经历)
  4. RHEL6 64位系统安装ORACLE 10g 64bit 数据库
  5. 小清新cygwin,正在诞生中
  6. paip.文件目录操作uAPI php python java对照
  7. FreeSWITCH的TLS加密
  8. Saltstack系列4:Saltstack之Grains组件
  9. HBase shell 常用指令
  10. 大数据技术人年度盛事! BDTC 2016将于12月8-10日在京举行
  11. centos7免密码登录
  12. 图像检索:一维直方图+EMD距离
  13. AM调制的FPGA实现
  14. Xcode intellisense meaning of letters in colored boxes like f,T,C,M,P,C,K,# etc
  15. 存储引擎-Bitcast
  16. [PHP] 算法-顺时针打印矩阵的PHP实现
  17. HTML学习笔记Day11
  18. Ribbon 负载均衡机制
  19. idea+dubbo+zookeeper项目访问html页面的方法
  20. Easyui + asp.net MVC 系列教程 第09-17 节 完成登录 高清录制

热门文章

  1. 怎么解决Chrome浏览器“Failed to load resource: net::ERR_INSECURE_RESPONSE”错误?
  2. 使用resultMap实现高级结果映射
  3. Java连载74-字符串常用方法、正则表达式简介
  4. 聊聊智能指针 auto_ptr、shared_ptr、weak_ptr和unique_ptr
  5. HTML5存储(带一个粗糙的打怪小游戏案例)
  6. nunjucks如何使用?
  7. 剑指offer-面试题25-合并两个排序的链表-链表
  8. javascript 权威指南一
  9. 咸鱼的ACM之路:DFS水题集
  10. ubantu crontab定时任务设置