天天看點

OpenWrt熱插拔HotPlug

熱插拔官方文檔

當某些 events事件發生時,

Procd(init系統和程序管理守護程序)會執行位于/etc/hotplug.d/中的腳本

,例如當接口啟動或關閉時,檢測到新的存儲驅動器時,或者按下按鈕時.

當使用PPPoE連接配接或者在不穩定的網絡中,或使用硬體按鈕時非常有用。

該功能子產品模拟/擴充了已淘汰的Hotplug2軟體包的功能。

工作原理

/etc/hotplug.d

檔案夾包含了 block iface, net 和 ntp 等檔案夾.

觸發事件觸發後,Procd将按字母順序執行該觸發器子檔案夾中的所有腳本。 這就是為什麼大多數腳本都使用數字字首。

  • block 塊裝置事件(塊裝置已連接配接/已斷開連接配接)
  • iface 接口事件(當LAN或WAN等接口連接配接/斷開時)
  • net 與網絡相關的事件
  • ntp 時間同步事件(Time step,時間伺服器層變化)
  • button 按鈕事件 (預設不建立, 由 /etc/rc.button 代替)
  • usb 類似3g-modem和tty*的USB裝置

    對于其他類型的觸發器,可能(應該)是其他的。他們可以是按鈕, 聲音裝置, 序列槽和USB序列槽加密狗。

用法

隻需将您的腳本放入正确的hotplug.d子目錄中(如果沒有),隻需建立正确的子目錄即可。

提供給腳本的資訊/故障排除

當在中執行腳本時/etc/hotplug.d,Procd 通常會以環境變量的形式提供大量資訊。

如果要檢視它提供了什麼環境變量,請編寫一個包含以下行的腳本:

env > /tmp/envs_log.log

并将其放在您要使用的檔案夾中,然後觸發連接配接到該檔案夾​​的事件,然後您可以通過閱讀/tmp/envs_log.log文本檔案 來檢視傳遞了哪些環境

相關的環境變量

block 檔案夾

OpenWrt熱插拔HotPlug

iface 檔案夾

OpenWrt熱插拔HotPlug

ntp 檔案夾

OpenWrt熱插拔HotPlug

即使沒有NTP同步,也會收到一個定期的熱插拔事件,其中stratum=16,開機後大約每11分鐘一次

USB檔案夾

OpenWrt熱插拔HotPlug

U盤的自動挂載解除安裝

Hotplug一個常見的執行個體應用就是U盤或SD卡等外設的自動挂載和解除安裝功能。是以這裡我們主要介紹如何利用hotplug實作U盤,移動硬碟等外設自動挂載的方法和原理。本文中的例子還需要根據實際情況作相應适配。

當然,首先得核心有相應的驅動程式支援才行。當U盤插入後,會産生uevent事件,hotplug收到這個核心廣播事件後,根據uevent 事件json格式的附帶資訊内容,在hotplug.json中進行定位。事件包含的資訊一般為如下所示:

ACTION(add), DEVPATH(devpath), SUBSYSTEM(block), MAJOR(8), MINOR(1), DEVNAME(devname), DEVTYPE(devtype), SEQNUM(865)

根據上面的資訊,就可以在hotplug.json中定位到兩個條目,如上面hotplug.json中藍色顯示字段。第一個條目執行的是makedev,該指令會建立裝置節點。第二個條目會根據附帶資訊中的ACTION, DEVPATH, SUBSYSTEM, DEVNAME, DEVTYPE 等變量,調用指令exec去執行hotplug-call腳本。

于是 hotplug-call 會嘗試執行 /etc/hotplug.d/block/ 目錄下的所有可執行腳本。

是以我們可以在這裡放置我們的自動挂載/解除安裝處理腳本。 例如,編寫/etc/hotplug.d/block/30-usbmount,填入以下内容實作U盤自動挂載,解除安裝:

#!/bin/sh

[ "$SUBSYSTEM" = block ] || exit0
[ "$DEVTYPE" = partition -a "$ACTION" = add ] && {
    echo "$DEVICENAME" | grep 'sd[a-z][1-9]' || exit 0
    test -d /mnt/$DEVICENAME || mkdir /mnt/$DEVICENAME
    mount  -o iocharset=utf8,rw /dev/$DEVICENAME /mnt/$DEVICENAME
}

[ "$DEVTYPE" = disk -a "$ACTION" = remove ] && {
    echo "${DEVICENAME}1" | grep 'sd[a-z][1-9]' || exit 0
    umount/mnt/${DEVICENAME}1 && rmdir /mnt/${DEVICENAME}1
}
           

有隐藏