Linux内核提供了一种机制,使得有热插拔事件(比如插入或拔出U盘)发生时可以执行一个程序,在本文中我称之为hotplug程序。内核在调用
hotplug程序时会传递一个命令行参数,这个参数是发生热插拔事件的子系统名称,常见的有usb, module, drivers,
net等。此外内核在调用hotplug程序是还会设置一些环境变量,如SUBSYSTEM, ACTION, PRODUCT, TYPE,
INTERFACE, DEVPATH等。
下面是一系列实际的热插拔事件的例子,每一行表示hotplug程序被调用一次:
- 1 SUBSYSTEM=net, ACTION=linkup, PRODUCT=, TYPE=, INTERFACE=eth0, DEVPATH=/class/net/eth0
- 2 SUBSYSTEM=module, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/module/ehci_hcd
- 3 SUBSYSTEM=platform, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ehci_hcd
- 4 SUBSYSTEM=drivers, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/bus/platform/drivers/ehci_hcd
- 5 SUBSYSTEM=usb_host, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/class/usb_host/usb1
- 6 SUBSYSTEM=usb, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ehci_hcd/usb1
- 7 SUBSYSTEM=module, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/module/ohci_hcd
- 8 SUBSYSTEM=platform, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ohci_hcd
- 9 SUBSYSTEM=drivers, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/bus/platform/drivers/ohci_hcd
- 10 SUBSYSTEM=usb_host, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/class/usb_host/usb2
- 11 SUBSYSTEM=usb, ACTION=add, PRODUCT=0/0/206, TYPE=9/0/1, INTERFACE=9/0/0, DEVPATH=/devices/platform/ehci_hcd/usb1/1-0:1.0
- 12 SUBSYSTEM=usb, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ohci_hcd/usb2
- 13 SUBSYSTEM=scsi_host, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/class/scsi_host/host0
- 14 SUBSYSTEM=usb, ACTION=add, PRODUCT=18a5/216/112, TYPE=0/0/0, INTERFACE=8/6/80, DEVPATH=/devices/platform/ehci_hcd/usb1/1-1/1-1:1.0
- 15 SUBSYSTEM=usb, ACTION=add, PRODUCT=0/0/206, TYPE=9/0/0, INTERFACE=9/0/0, DEVPATH=/devices/platform/ohci_hcd/usb2/2-0:1.0
- 16 SUBSYSTEM=usb, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ehci_hcd/usb1/1-1
- 17 SUBSYSTEM=scsi_generic, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/class/scsi_generic/sg0
- 18 SUBSYSTEM=scsi_device, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/class/scsi_device/0:0:0:0
- 19 SUBSYSTEM=scsi, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/devices/platform/ehci_hcd/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0
- 20 SUBSYSTEM=block, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/block/sda
- 21 SUBSYSTEM=module, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/module/ufsd
- 22 SUBSYSTEM=block, ACTION=add, PRODUCT=, TYPE=, INTERFACE=, DEVPATH=/block/sda/sda1
系统默认的热插拔处理程序是/sbin/hotplug。在MP800H上/sbin/hotplug用的是diethotplug-0.4,在华
硕公开的源码中有它的源代码。这是一个瘦身版的hotplug程序,它的主要工作是在usb存储设备插入时进行自动挂载,挂载目录在/tmp
/usbmounts下面,如/tmp/usbmounts/sda1。
我们可以通过修改/proc/sys/kernel/hotplug来重新指定hotplug程序,通过定制hotplug程序,我们可以按我们希望的方式来处理热插拔事件,比如插入无线网卡时自动连接无线网。下面我将给出一个实现此功能的程序实例。
程序由两个shell脚本和一个配置文件组成:hotplug脚本是我们定制的hotplug程序,wifi_monitor脚本是无线网络监控程
序,它们都放在/usr/local/sbin下。wifi.conf是无线网络配置文件,放在/usr/local/etc下。
首先用我们的hotplug程序替换系统默认的/sbin/hotplug
$ echo /usr/local/sbin/hotplug > /proc/sys/kernel/hotplug
程序是这样工作的:热插拔事件发生时,内核执行我们的hotplug程序,即/usr/local/sbin/hotplug。hotplug程序先调用
/sbin/hotplug,让它完成它该做的工作。然后判断该事件是否为usb无线网卡插入事件,如果是则执行wifi_monitor,如果是无线网
络连接事件则通过DHCP获取IP地址。wifi_monitor根据wifi.conf配置文件尝试连接无线网络。它先扫描可用无线网络,如果找到指定
的网络则进行连接,否则等5秒钟再重新扫描。如果扫描3次都没有找到,则等待10秒钟后重新读入配置文件再次开始扫描循环。wifi_monitor还可
以处理无线网络断线的情况,即发现无线网络断开时重新开始扫描循环。
/usr/local/sbin/hotplug
阅读(3220) | 评论(0) | 转发(0) |