Hotplug

A Hotplug2 egy esemény alrendszer Linuxhoz. A hagyományos udev és hotplug szolgáltatások előnyeit egyesíti magában, de sokkal kisebb méretben, ezért ideális beágyazott rendszerekhez, mint az OpenWrt. Lényegében a Hotplug2 arra való, hogy meghatározott rendszeresemények esetén - pl. egy hálózati interfész be- vagy kikapcsolása, egy USB eszköz csatlakoztatása, vagy egy gomb megnyomása, - scripteket hajtson végre.

Rendkívül hasznos lehet pédául egy instabil PPPoE kapcsolat esetén, ahol napjában többször is megváltozhat az eszköz IP címe. A hardware.button is a hotplug-ot használja.

A Hotplug2 az OpenWrt 'Kamikaze' 7.06-os verziójában jelent meg, és az 'Attitude Adjustment' az utolsó verzió amiben támogatott.

A r36987 változtatással bevezetésre került a procd, ami a következő verzióban teljes egészében le fogja váltani a hotplug-ot. Sajnos a procd-ről még annyi dokumentáció sincs mint a hotplug-ról… A r37132 -ben a hotplug2 csomag kikerült a default csomagok közül, így ez a leírás a legújabb verziókra nem érvényes, át kell állni a procd-re. See r37336: procd: make old button hotplug rules work until all packages are migrated

Mi az a hotplug?

Jó open source szokás szerint a hotplug-ról alig fellelhető valami dokumentáció. Chris Lumens weboldalán található egy általános leírás az eredeti hotplug-ról, azonban a hotplug2 működése kicsit eltérő.

Működése

A hotplug alrendszer alapja a /sbin/hotplug2 program, mely egy szolgáltatásként folyamatosan fut. Ha valami rendszeresemény történik, akkor a kernel továbbítja azt a hotplug2-nek. A program az eseményeket az ún. rules fájl szerint dolgozza fel. Ez egy olyan szabálygyűjtemény, amiben a különböző típusú eseményekhez különböző végrehajtandó utasítások vannak rendelve. A rules fájloknak egyedi szintaxisa van.

Normál működéskor a rendszer a /etc/hotplug2.rules fájlban leírt szabályokat alkalmazza. Ezek értelmében a különböző alrendszerek (pl. net, usb, button) eseményei a /sbin/hotplug-call scriptnek lesznek továbbítva, paraméterként az alrendszer neve adódik át. Ez nem csinál mást, minthogy ABC-sorrendben meghívja az /etc/hotplug.d/ könyvtáron belül az adott alrendszer könyvtárában lévő összes scriptet.

Például, egy hálózati interfész be- vagy kikapcsolásakor az /etc/hotplug.d/iface/ könyvtárban lévő összes script név szerinti sorrendben lefut. Megegyezés szerint minden hotplug script neve két számjegyű számmal kezdődik, így egyszerűen biztosítható, hogy mindig a megfelelő sorrendben fussanak le. Ezért a hálózat interfészekhez tartozó eseményscriptek elnevezési sémája: /etc/hotplug.d/iface/<nn>-<scriptneve> pl.: 00-netstate, 20-firewall.

Használata

1. Rules fájlok

Az események feldolgozását a hotplug2 a default rules fájllal kezdi. Az /etc/hotplug2.rules fájl tartalmazza a használható események típusait, ezek jelenleg: net, input, button, usb, ieee13945, block, atm, zaptel és tty.

FIGYELEM! Az angol leírásban található utasítás, miszerint ki kell törölni a ^ jelet, hogy engedélyezzük az eseményeket az adott alrendszerhez, NEM IGAZ, és hibás működéshez vezethet!

$include /etc/hotplug2-common.rules

SUBSYSTEM ~~ (^net$|^input$|^button$|^usb$|^ieee1394$|^block$|^atm$|^zaptel$|^tty$) {
	exec /sbin/hotplug-call %SUBSYSTEM%
}

DEVICENAME == watchdog {
	exec /sbin/watchdog -t 5 /dev/watchdog
	next-event
}

A fájl első sora egy include direktíva, azt jelenti, hogy a hotplug2 a /etc/hotplug2-common.rules fájlban lévő szabályokat is végre fogja hajtani.

2. Hotplug scriptek

Az események használatához egyszerűen helyezzük a hotplug-scriptet a megfelelő alrendszer alkönyvtárába /etc/hotplug.d/ könyvtáron belül, és az automatikusan el fog indulni az adott típusú esemény hatására. A fájlt nn-scriptnév formában nevezzük el, ahol az nn egy kétjegyű számot jelöl.

3. Event változók

Az eseményekről további informácókat a következő shell változók tartalmaznak. Ezek az eseményscripten belül használhatóak, értéküket a keretrendszer automatikusan beállítja. Erről a folyamatról a fórumban található egy részletes gondolatmenet: How does hotplug work for network interfaces?

Változónév Leírás Értékek
ACTION Az esemény azonosítója, értékei az esemény forrásától függnek.
Kernel forrású eseményeknél (pl. usb alrendszer):
add - eszköz csatlakoztatva
remove - eszköz eltávolítva
change - ?
move - ?
online - ?
offline - ?
netifd forrású eseményeknél (iface alrendszer):
ifup - hálózati eszköz feléledt
ifdown - hálózati eszköz lekapcsolt
ifupdate - ?
button alrendszer eseményeinél:
pressed - gomb megnyomva
released - gomb elengedve
DEVPATH Az eseményt kiváltó eszköz belső elérési útja a /sys fájlrenszeren belül
SUBSYSTEM Az alrendszer azonosítója ami az eseményt küldte, pl. usb, button, stb.
SEQNUM Az esemény sorszáma, pl. hibakereséshez
DEVNAME Az eszköz elérési útja a /dev fájlrendszeren belül (ha van)
DEVICENAME Az eszköz "barátságos" neve, ha van
FIRMWARE Ez a változó akkor van beállítva, ha az eszköz firmware betöltését igényli.
Ezt a megfelelő szabály lekezeli a rules fájlban.
INTERFACE A logikai interfész neve amin a változás történt. iface típus esetén pl. "wan" vagy "ppp0"
usb alrendszernél interface 0 class code (decimális)
más alrendszer esetén specifikus azonosító
DEVICE iface alrendszernél a fizikai eszköz neve aminek az állapota változott.
Más alrendszernél az eszköz elérése a /proc fájlrendszerben
iface alrendszernél pl. eth0.1 vagy br-lan
PRODUCT Eszközazonosító usb alrendszernél USB vendor, product, és version code (hexa)
TYPE Az eszköz típusa usb alrendszernél device class code (decimális)
BUTTON Csak button alrendszernél, a gomb azonosítója amit megnyomtak. BTN_0, BTN_1BTN_9, reset, wps
SEEN Csak button alrendszernél, valami idő alapú változó, nem világos, hogy mi.

Példák

Save the example script at /etc/hotplug.d/iface/99-my-action.

#!/bin/sh [ "$ACTION" = ifup ] && { logger -t button-hotplug Device: $DEVICE / Action: $ACTION }

Every time an interface goes up then the if/fi statement will be executed.

hardware.button makes ample use of hotplug.

Niii has posted this quick example for a USB WiFi device hotplug event to trigger an init.d network restart wlan0 script.

For determine RTL8188SU_PRODID variable, use "lsusb -v":

idVendor           0x0bda Realtek Semiconductor Corp.
idProduct          0x8171 RTL8188SU 802.11n WLAN Adapter
bcdDevice            2.00

/etc/hotplug.d/usb/20-rtl8188su

#!/bin/sh BINARY="/sbin/wifi up" RTL8188SU_PRODID="bda/8171/200" if [ "${PRODUCT}" = "${RTL8188SU_PRODID}" ]; then if [ "${ACTION}" = "add" ]; then ${BINARY} fi fi

/etc/hotplug.d/usb/20-cp210x

An other script to create a symlink instead of renaming the device.
I test if DEVICE_NAME is empty because when I plug usb device I retrieve two add event, and the first come before created device, so symlink fails.

#!/bin/sh CP210_PRODID="10c4/ea60/100" SYMLINK="my_link" if [ "${PRODUCT}" = "${CP210_PRODID}" ]; then if [ "${ACTION}" = "add" ]; then DEVICE_NAME=$(ls /sys/$DEVPATH | grep tty) if [ -z ${DEVICE_NAME} ]; then logger -t Hotplug Warning DEVICE_NAME is empty exit fi logger -t Hotplug Device name of cp210 is $DEVICE_NAME ln -s /dev/$DEVICE_NAME /dev/${SYMLINK} logger -t Hotplug Symlink from /dev/$DEVICE_NAME to /dev/${SYMLINK} created fi fi if [ "${PRODUCT}" = "${CP210_PRODID}" ]; then if [ "${ACTION}" = "remove" ]; then rm /dev/${SYMLINK} logger -t Hotplug Symlink /dev/${SYMLINK} removed fi fi

Script that detects if plugged usb device is bluetooth or not.

#!/bin/sh BT_PRODID="a12/1/" BT_PRODID_HOT=`echo $PRODUCT | cut -c 1-6` #logger -t HOTPLUG "PRODUCT ID is" $BT_PRODID_HOT if [ "$BT_PRODID_HOT" = "$BT_PRODID" ]; then if [ "$ACTION" = "add" ]; then logger -t HOTPLUG "bluetooth device has been plugged in!" if [ "$BSBTID_NEW" = "$BSBTID_OLD" ]; then logger -t HOTPLUG "bluetooth device hasn't changed" else logger -t HOTPLUG "bluetooth device has changed" fi fi if [ "$ACTION" = "remove" ]; then logger -t HOTPLUG "bluetooth device has been removed!" fi else logger -t HOTPLUG "USB device is not bluetooth" fi

Auto start mjpg-streamer when an usb camera is plugged in. Firstly, remove '^' before 'input' in /etc/hotplug2.rules to enable Hotplug execute script(s) in /etc/hotplug.d/input. Secondly, add /etc/hotplug.d/input/30-mjpg-streamer

case "$ACTION" in
    add)
            # start process
        /etc/init.d/mjpg-streamer start
            ;;
    remove)
            # stop process
        /etc/init.d/mjpg-streamer stop
            ;;
esac

Hibakeresés

If you wish to troubleshoot hotplug of some type of device this can be done via simple debug script. For example to troubleshoot adding and removing of any type of usb devices simple create this /etc/hotplug.d/usb/10-usb_debug script with all variables:

#!/bin/sh
logger -t DEBUG "hotplug usb: action='$ACTION' devicename='$DEVICENAME' devname='$DEVNAME' devpath='$DEVPATH' product='$PRODUCT' type='$TYPE' interface='$INTERFACE'"

or this one with only essential ones used:

#!/bin/sh
logger -t DEBUG "hotplug usb: action='$ACTION' product='$PRODUCT' type='$TYPE' interface='$INTERFACE'"

So with debuging enabled here is how it looks like when you plug two different usb bluetooth dongles:

action='add' product='a12/1/1915' type='224/1/1' interface=''
action='add' product='a12/1/1915' type='224/1/1' interface='224/1/1'
action='add' product='a12/1/1915' type='224/1/1' interface='224/1/1'
action='add' product='a12/1/1915' type='224/1/1' interface='254/1/0'
action='remove' product='a12/1/1915' type='224/1/1' interface='224/1/1'
action='remove' product='a12/1/1915' type='224/1/1' interface='224/1/1'
action='remove' product='a12/1/1915' type='224/1/1' interface='254/1/0'
action='remove' product='a12/1/1915' type='224/1/1' interface=''
action='add' product='a12/1/134' type='224/1/1' interface=''
action='add' product='a12/1/134' type='224/1/1' interface='224/1/1'
action='add' product='a12/1/134' type='224/1/1' interface='224/1/1'

So my using some (maybe flawed) logic we can deduce that match bluetooth is possible if we use product='a12/1*'

Back to top

hu/doc/techref/hotplug.txt · Last modified: 2014/01/05 15:41 (external edit)