openwrt hotplug
由内核发出 event 事件.
kobject_uevent() 产生 uevent 事件(lib/kobject_uevent.c 中), 产生的 uevent 先由 netlink_broadcast_filtered() 发出, 最后调用 uevent_helper[] 所指定的程序来处理.
uevent_helper[] 里默认指定 "/sbin/hotplug", 但可以通过 /sys/kernel/uevent_helper (kernel/ksysfs.c) 或 /proc/kernel/uevent_helper (kernel/sysctl.c) 来修改成指定的程序.
在 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的更多相关文章
- openwrt 中procd
https://wiki.openwrt.org/doc/techref/procd Procd:Openwrt的进程管理守护进程(process management daemon),它与初始化脚本 ...
- OpenWrt启动过程分析+添加自启动脚本【转】
一.OpenWrt启动过程分析 转自: http://www.eehello.com/?post=107 总结一下OpenWrt的启动流程:1.CFE->2.linux->3./etc/p ...
- OpenWRT中的按键和灯的GPIO控制实现_转
本文转自:OpenWRT中的按键和灯的GPIO控制实现 基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯 ...
- Openwrt Udev Configure(3)
1 Scope of Document This document describes how to write udev script, when enum usb device mayb ...
- dnspod 动态域名的使用。openwrt使用dnspod动态域名解析。
这里主要说的是linux shell下的使用. 先看接口说明: 接口地址: https://dnsapi.cn/Record.Ddns HTTP请求方式: POST 请求参数: 公共参数 domain ...
- [Openwrt 项目开发笔记]:DDNS设置(五)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我主要讲述了如何在Openwrt上安 ...
- [Openwrt 扩展上篇]USB挂载&U盘启动&Samba共享
最近偷懒,没学习,反想起自己的路由刷了Openwrt,正好闲置了一个硬盘想拿来做个网络硬盘,于是开始了折腾....这里将不谈论如何刷Openwrt,如何ssh,如何添加PPOE,如何添加相对应服务的包 ...
- OpenWRT中的按键和灯的GPIO控制实现
基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯所对应的GPIO定义: #define AP121_GP ...
- openwrt procd启动流程和脚本分析
Linux内核执行start_kernel函数时会调用kernel_init来启动init进程,流程如下图: graph LR A[start_kernel] -->B(rest_init) B ...
随机推荐
- appium+python自动化-adb offline(5037端口被占)
前言 adb连手机的时候经常会出现offline的情况,一般杀掉adb,然后重启adb可以解决. 如果发现不管怎么重启adb都连不上,一直出现offlie的情况,这个时候很大可能就是adb的5037端 ...
- NYOJ 219 An problem about date
An problem about date 时间限制:2000 ms | 内存限制:65535 KB 难度:2 描述 acm的iphxer经常忘记某天是星期几,但是他记那天的具体日期,他希望你 ...
- SQL处理XML
使用SP_XML_PREPAREDOCUMENT 来读取 Xml 文本. 读取作为输入提供的 XML 文本,然后使用 MSXML 分析器 (Msxmlsql.dll) 对其进行分析,并提供分析后的文档 ...
- BZOJ 4823 [Cqoi2017]老C的方块 ——网络流
lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html 我还是太菜了.以后遇到这种题目应该分析分析性质的. 网络流复杂度真是$O(玄学)$ #in ...
- NOI2015 荷马史诗 【k-哈夫曼树】
题目 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛> ...
- 【2018.10.27】CXM笔记
一个数大约有 $O(\sqrt(n)/log^2(n))$ 个约数. 1. 一个棋盘,每个格子最开始都是白的.可以按一个格子,它马跳(日字跳)能到达的 $8$ 个格子反色(当前格不反色).问有多少种方 ...
- OTOCI(bzoj 1180)
Description 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作: 1.bridge A B:询问结点A与结点B是否连通.如果是则输出“no”.否则输出“yes ...
- 【HDOJ6354】Everything Has Changed(计算几何)
题意: 给定一个平面和一个(0,0)为中心的大圆,有n个小圆保证没有两两之间相交与覆盖整个大圆的情况,求小圆覆盖后大圆的周长并 1≤m≤100, -1e3<=x[i],y[i]<=1e3, ...
- 解析XML字符串为json对象
var overtime='<?xml version="1.0" encoding="UTF-8"?><response><co ...
- Redis数据结构之字典
Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对. 一.字典结构定义1. 哈希表节点结构定义: 2. 哈希表结构定义: 3. 字典 ...