Hotplug

Hotplug2 is a trivial replacement of some of the UDev functionality in a tiny pack, intended for Linux early userspace: Init RAM FS and InitRD. Hotplug executes scripts located in the respective hotplug directory: /etc/hotplug.d/ on certain events, like when an interface goes up or down or when a button gets pressed. It can be very useful with PPPoE-connection or in an unstable network. Hotplug has been available since OpenWrt 'Kamikaze' 7.06.

As of r36987 procd was introduced. See r37336: procd: make old button hotplug rules work until all packages are migrated

It is also used by hardware.button

What is hotplug?

Best answer to this question is found on Chris Lumens's website.

How it works

Every time an interface goes up or down, all scripts in the /etc/hotplug.d/iface/ directory are executed, in alphabetical order. According to an informal convention a numeric prefix is added to each script name to set the correct order of running. That's why the scripts there are named like this: /etc/hotplug.d/iface/<nn>-<scriptname> e.g.: 10-routes, 20-firewall

Kernel module: button-hotplug

Configuration

Modify /etc/hotplug2.rules to enable Hotplug execute your script(s) in /etc/hotplug.d/<type>. <type> is a kind of hotplug device such as usb. In /etc/hotplug2.rules, remove '^' before <type> which can be net, input, button, usb etc.

$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
}

Simply place your script(s) into the respective hotplug subdirectory. Script looks like that:

There are three main environment variables that are passed to each iface hotplug-script:

Variable name Description
ACTION Either "ifup" or "ifdown"
INTERFACE Name of the interface which went up or down (e.g. "wan" or "ppp0")
DEVICE Physical device name which interface went up or down (e.g. "eth0.1" or "br-lan")

Examples

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

Troubleshoot

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*'

Notes

Back to top

doc/techref/hotplug.txt · Last modified: 2014/01/31 20:09 by brna