由内核发出 event 事件.

  1. kobject_uevent() 产生 uevent 事件(lib/kobject_uevent.c 中), 产生的 uevent 先由 netlink_broadcast_filtered() 发出, 最后调用 uevent_helper[] 所指定的程序来处理.

  2. uevent_helper[] 里默认指定 "/sbin/hotplug", 但可以通过 /sys/kernel/uevent_helper (kernel/ksysfs.c) 或 /proc/kernel/uevent_helper (kernel/sysctl.c) 来修改成指定的程序.

  3. 在 OpenWrt 并不使用 user_helper[] 指定程序来处理 uevent (/sbin/hotplug 不存在), 而是使用 PF_NETLINK 来获取来自内核的 uevent.

用户空间监听 uevent

openwrt 中, procd 作为 init 进程会处理许多事情, 其中就包括 hotplug.

procd/plug/hotplug.c 中, 创建一个 PF_NETLINK 套接字来监听内核 netlink_broadcast_filtered() 发出的 uevent.

收到 uevent 之后, 再根据 /etc/hotplug.json 里的描述来处理.

通常情况下, /etc/hotplug.json 会调用 /sbin/hotplug-call 来处理, 它根据 uevent 的 $SUBSYSTEM 变量来分别调用 /etc/hotplug.d/ 下不同目录中的脚本.

比如, 插入U盘或SD卡时, 会产生的事件消息如下:

procd: rule_handle_command(355): Command: makedev
procd: rule_handle_command(357): /dev/sda1
procd: rule_handle_command(357): 0644
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): ACTION=add
procd: rule_handle_command(362): DEVPATH=/devices/101c0000.ehci/usb1/1-1/1-1.3/1-1.3:1.0/host16/target16:0:0/16:0:0:0/block/sda/sda1
procd: rule_handle_command(362): SUBSYSTEM=block
procd: rule_handle_command(362): MAJOR=8
procd: rule_handle_command(362): MINOR=1
procd: rule_handle_command(362): DEVNAME=sda1
procd: rule_handle_command(362): DEVTYPE=partition
procd: rule_handle_command(362): SEQNUM=865
procd: rule_handle_command(363):
procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357): /sbin/hotplug-call
procd: rule_handle_command(357): block
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): ACTION=add
procd: rule_handle_command(362): DEVPATH=/devices/101c0000.ehci/usb1/1-1/1-1.3/1-1.3:1.0/host16/target16:0:0/16:0:0:0/block/sda/sda1
procd: rule_handle_command(362): SUBSYSTEM=block
procd: rule_handle_command(362): MAJOR=8
procd: rule_handle_command(362): MINOR=1
procd: rule_handle_command(362): DEVNAME=sda1
procd: rule_handle_command(362): DEVTYPE=partition
procd: rule_handle_command(362): SEQNUM=865
procd: rule_handle_command(363):

第一个 makedev 会创建 /dev/sda1 节点. 第二个 exec 命令, 其附带的消息中指定了 ACTION, DEVPATH, SUBSYSTEM, DEVNAME, DEVTYPE 等变量.

于是 hotplug-call 会尝试执行 /etc/hotplug.d/block/ 目录下的所有可执行脚本.

所以我们可以在这里放置我们的自动挂载/卸载处理脚本.

按键 button 的检测

openwrt 中, 按键的检测也是通过 hotplug 来实现的.

它首先写了一个内核模块: gpio_button_hotplug, 用于监听按键, 有中断和 poll 两种方式. 然后在发出事件的同时, 将记录并计算得出的两次按键时间差也作为 uevent 变量发出来.

这样在用户空间收到这个 uevent 事件时就知道该次按键按下了多长时间.

hotplug.json 中有描述, 如果 uevent 中含有 BUTTON 字符串, 而且 SUBSYSTEM 为 "button", 则执行 /etc/rc.button/ 下的 %BUTTON% 脚本来处理.

        [ "if",
[ "and",
[ "has", "BUTTON" ],
[ "eq", "SUBSYSTEM", "button" ],
],
[ "exec", "/etc/rc.button/%BUTTON%" ]
],

使用 export DBGLVL=10; procd -h /etc/hotplug.json 截获一些打印信息看看:

{{"HOME":"\/","PATH":"\/sbin:\/bin:\/usr\/sbin:\/usr\/bin","SUBSYSTEM":"button","ACTION":"pressed","BUTTON":"reset","SEEN":"862","SEQNUM":"593"}}
procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357): /etc/rc.button/reset
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): HOME=/
procd: rule_handle_command(362): PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362): SUBSYSTEM=button
procd: rule_handle_command(362): ACTION=pressed
procd: rule_handle_command(362): BUTTON=reset
procd: rule_handle_command(362): SEEN=862
procd: rule_handle_command(362): SEQNUM=593
procd: rule_handle_command(363): procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357): /sbin/hotplug-call
procd: rule_handle_command(357): button
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): HOME=/
procd: rule_handle_command(362): PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362): SUBSYSTEM=button
procd: rule_handle_command(362): ACTION=pressed
procd: rule_handle_command(362): BUTTON=reset
procd: rule_handle_command(362): SEEN=862
procd: rule_handle_command(362): SEQNUM=593
procd: rule_handle_command(363): {{"HOME":"\/","PATH":"\/sbin:\/bin:\/usr\/sbin:\/usr\/bin","SUBSYSTEM":"button","ACTION":"released","BUTTON":"reset","SEEN":"3","SEQNUM":"594"}}
procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357): /etc/rc.button/reset
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): HOME=/
procd: rule_handle_command(362): PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362): SUBSYSTEM=button
procd: rule_handle_command(362): ACTION=released
procd: rule_handle_command(362): BUTTON=reset
procd: rule_handle_command(362): SEEN=3
procd: rule_handle_command(362): SEQNUM=594
procd: rule_handle_command(363): procd: rule_handle_command(355): Command: exec
procd: rule_handle_command(357): /sbin/hotplug-call
procd: rule_handle_command(357): button
procd: rule_handle_command(358):
procd: rule_handle_command(360): Message:
procd: rule_handle_command(362): HOME=/
procd: rule_handle_command(362): PATH=/sbin:/bin:/usr/sbin:/usr/bin
procd: rule_handle_command(362): SUBSYSTEM=button
procd: rule_handle_command(362): ACTION=released
procd: rule_handle_command(362): BUTTON=reset
procd: rule_handle_command(362): SEEN=3
procd: rule_handle_command(362): SEQNUM=594
procd: rule_handle_command(363):

openwrt hotplug的更多相关文章

  1. openwrt 中procd

    https://wiki.openwrt.org/doc/techref/procd Procd:Openwrt的进程管理守护进程(process management daemon),它与初始化脚本 ...

  2. OpenWrt启动过程分析+添加自启动脚本【转】

    一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...

  3. OpenWRT中的按键和灯的GPIO控制实现_转

    本文转自:OpenWRT中的按键和灯的GPIO控制实现 基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯 ...

  4. Openwrt Udev Configure(3)

    1      Scope of Document This document describes how to write udev script, when enum usb device mayb ...

  5. dnspod 动态域名的使用。openwrt使用dnspod动态域名解析。

    这里主要说的是linux shell下的使用. 先看接口说明: 接口地址: https://dnsapi.cn/Record.Ddns HTTP请求方式: POST 请求参数: 公共参数 domain ...

  6. [Openwrt 项目开发笔记]:DDNS设置(五)

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我主要讲述了如何在Openwrt上安 ...

  7. [Openwrt 扩展上篇]USB挂载&U盘启动&Samba共享

    最近偷懒,没学习,反想起自己的路由刷了Openwrt,正好闲置了一个硬盘想拿来做个网络硬盘,于是开始了折腾....这里将不谈论如何刷Openwrt,如何ssh,如何添加PPOE,如何添加相对应服务的包 ...

  8. OpenWRT中的按键和灯的GPIO控制实现

    基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯所对应的GPIO定义: #define AP121_GP ...

  9. openwrt procd启动流程和脚本分析

    Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...

随机推荐

  1. WordPress 编辑器没有可视化

    第一次安装wordpress后出现文章编辑器只有一行按钮的问题,即使我安装了其他的编辑插件也是一样只有一行, 解决方法: 原来是再Users->All Users 中勾选了Disable the ...

  2. C++类指针初始化

    上面的代码会打印“A”. C++ 类指针定义的时候没有初始化的时候,居然可以安全的调用类内部的成员函数而不出错. 在网上查了一下:   初始化为NULL的类指针可以安全的调用不涉及类成员变量的类成员函 ...

  3. 如何解决 错误code signing is required for product type 'xxxxx' in SDK 'iOS 8.2'

    如何解决 错误code signing is required for product type 'xxxxx' in SDK 'iOS 8.2' 大家在做真机调试的时候,或许会遇到这样的问题,那如何 ...

  4. 【Luogu】P2912牧场散步(TarjanLCA)

    题目链接 老天……终于碰上一个除了模板之外的LCA题了 这道题用Tarjan来LCA.树上两个点的路径是唯一的,所以钦定一个根,两点间的路径就是两点到根的路径减去双倍的公共祖先到根的路径.大概很好理解 ...

  5. 中国余数定理 2(codevs 3990)

    题目描述 Description Skytree神犇最近在研究中国博大精深的数学. 这时,Sci蒟蒻前来拜访,于是Skytree给Sci蒟蒻出了一道数学题: 给定n个质数,以及k模这些质数的余数.问: ...

  6. 洛谷 [P2575] 高手过招

    SG函数+状压记忆化搜索 观察题目发现,每一行都是独立的,只要处理出来每一行的SG值,异或起来就好 每一行的SG值可以用状压+记忆化搜索的方法来求,对位运算技术是个很大的考验 注意SG值要预处理出来, ...

  7. Spring Batch 文档(中文)

    http://blog.csdn.net/shorn/article/category/1186181

  8. Servlet 2.4 规范之第二篇:Servlet接口

    Servlet接口是Servlet API的最核心抽象类.所有的servlets都直接实现了这个接口,或者以更通用的方式继承了这个接口的实现类.Servlet API自带了两个实现了Servlet接口 ...

  9. HDu1241 DFS搜索

    #include<iostream> #include<cstring> using namespace std; int a[105][105]; int d[8][2]={ ...

  10. 迁移桌面程序到MS Store(8)——通过APPX下载Win32Component

    在上一篇<迁移桌面程序到MS Store(7)——APPX + Service>中,我们提到将desktop application拆分成UI Client+Service两部分.其中UI ...