Show pagesourceOld revisionsBacklinksBack to top × Table of Contents Hotplug How it works Usage / Troubleshooting Event classes / Directories block dsl iface ntp usb Examples Get specific IP address Restart WLAN on USB Wi-Fi event Symlink instead of rename a device Script that detects if plugged usb device is bluetooth or not Auto start mjpg-streamer when an usb camera is plugged in Custom automount script for XFS Coldplug Rename interfaces by MAC address log DSL status changes Hotplug Procd (the init system and process management daemon) executes scripts located in /etc/hotplug.d/ when certain events happen, like for example when an interface goes up or down, when a new storage drive is detected, or when a button is pressed. It can be very useful with PPPoE connection or in an unstable network, or to use hardware buttons. This functionality emulates/extends what was done by the long retired Hotplug2 package. How it works In the /etc/hotplug.d directory you will find some directories block, iface, net and ntp. When the trigger event fires, Procd will execute all scripts in that trigger's directory, in alphabetical order. Which is why most scripts in there use a numeric prefix. Directory Description block Block device events: device connected/disconnected button Buttons: not created by default, see /etc/rc.button instead dhcp DHCP-related events dsl DSL modem events firewall Firewall-related events iface Interface events: LAN/WAN/etc. is connected/disconnected neigh Neighbor discovery net Network-related events ntp Time sync events: time step, time server stratum change tftp TFTP-related events usb USB devices like 3g-modem and tty* See also: Buttons, sound devices, serial and USB serial dongles DHCP, NDP, TFTP DHCP client scripts Usage / Troubleshooting Simply place your script(s) into the right hotplug.d directory, if there is none just create the right one. Procd exposes a wealth of info when executes your scripts in /etc/hotplug.d, usually as environmental variables. If you want to see what environmental variables it is providing, make a script like this: cat << "EOF" > /etc/hotplug.d/iface/00-logger logger -t hotplug $(env) EOF Then trigger the event connected to that directory, and then you can see what envs were passed by reading the output: logread -e hotplug Event classes / Directories block For scripts in block directory, these are the (relevant) environmental variables Variable name Description ACTION For normal device (e.g: sda) it is either “add” or “remove”. Can be “change” if the device is dm-crypt (e.g: dm-0) DEVICENAME seems same as DEVNAME below DEVNAME Device or partition name (if I connect a drive I get a hotplug call with “sda” and another hotplug call with “sda1”) DEVPATH full device path (for example “/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/host7/target7:0:0/7:0:0:0/block/sdc/sdc1 ” DEVTYPE what the DEVNAME e DEVICENAME are names of, I've seen “partition” here when a device with a readable partition is inserted and a “disk” when that device is removed. MAJOR major device number MINOR minor device number SEQNUM seqnum (a number) SUBSYSTEM seems this is only “block” dsl For scripts in dsl directory, these are the (relevant) environment variables Variable name Description DSL_NOTIFICATION_TYPE DSL_STATUS, DSL_INTERFACE_STATUS, DSL_DATARATE_STATUS_US, DSL_DATARATE_STATUS_DS DSL_LINE_NUMBER 0, 1 * When DSL_NOTIFICATION_TYPE is DSL_STATUS, the following environment variables are set Variable name Description DSL_XTU_STATUS ADSL, VDSL DSL_TC_LAYER_STATUS ATM, EFM DSL_EFM_TC_CONFIG_US NORMAL, PRE_EMPTION, UNKNOWN DSL_EFM_TC_CONFIG_DS NORMAL, UNKNOWN When DSL_NOTIFICATION_TYPE is DSL_INTERFACE_STATUS, the following environment variables are set Variable name Description DSL_INTERFACE_STATUS DOWN, READY, HANDSHAKE, TRAINING, UP DSL_BONDING_STATUS INACTIVE, ACTIVE * When DSL_NOTIFICATION_TYPE is DSL_DATARATE_STATUS_US, the following environment variables are set Variable name Description DSL_DATARATE_US_BC0 Upstream data rate in bit/s for Channel 0 DSL_DATARATE_US_BC1 Upstream data rate in bit/s for Channel 1 * When DSL_NOTIFICATION_TYPE is DSL_DATARATE_STATUS_DS, the following environment variables are set Variable name Description DSL_DATARATE_DS_BC0 Downstream data rate in bit/s for Channel 0 DSL_DATARATE_DS_BC1 Downstream data rate in bit/s for Channel 1 * NOTE: environment variables marked with an * are only available when channel bonding support is compiled in. iface For scripts in iface directory, these are the (relevant) environmental variables Variable name Description ACTION ifdown, ifup, ifup-failed, ifupdate, free, reload, iflink, create INTERFACE Name of the logical interface which went up or down (e.g. wan or lan) DEVICE Name of the physical device which went up or down (e.g. eth0 or br-lan or pppoe-wan), when applicable The meaning of most actions should be straightforward, the maybe-not-obvious ones are: Value Description ifup-failed ifdown event happened while the interface was being brought up free the interface has been removed (inverse of create) iflink the interface reported the presence of a carrier When ACTION is ifupdate, the following environment variables may be set Variable name Description IFUPDATE_ADDRESSES 1 if address changed since previous ifupdate event IFUPDATE_ROUTES 1 if a route changed since previous ifupdate event IFUPDATE_PREFIXES 1 if prefix changed since previous ifupdate event IFUPDATE_DATA 1 if ubus call network.interface.$INTERFACE set_data ... (or equivalent) happened ntp Variables based on busybox ntpd: Variable name description ACTION step, stratum, unsync or periodic freq_drift_ppm ntp variables offset Time adjustment done stratum Quality (nr of servers to atomic clock) poll_interval ntp variables Even without NTP sync, you will receive a “periodic” hotplug event, with stratum=16, about every 11 minutes out of the box. usb Variable name description ACTION add, remove as above DEVNAME eg, “bus/usb/001/002” DEVPATH eg, “/devices/platform/ehci-platform/usb1/1-1” DEVICENAME eg “1-1” DEVNUM eg 002 DRIVER “usb” TYPE eg 9/0/1 PRODUCT the vendor/productcode/version, eg “424/2640/0” see lsusb SEQNUM ? eg 335 BUSNUM eg 001 MAJOR eg 189 MINOR eg 1 Examples cat << "EOF" > /etc/hotplug.d/iface/99-my-action [ "${ACTION}" = "ifup" ] && { logger -t hotplug "Device: ${DEVICE} / Action: ${ACTION}" } EOF Every time an interface goes up then the if/fi statement will be executed. Get specific IP address If your ISP provides a dynamic IP address, reconnect until you get the one with 10 in the first octet. Delay for 10 seconds between reconnects. Keep in mind that ifup internally invokes ifdown. cat << "EOF" > /etc/hotplug.d/iface/10-fix-wan-ip . /lib/functions/network.sh network_flush_cache network_find_wan NET_IF network_get_ipaddr NET_ADDR "${NET_IF}" if [ "${ACTION}" = "ifup" ] \ && [ "${INTERFACE}" = "${NET_IF}" ] \ && [ "${NET_ADDR%%.*}" = "10" ] then sleep 10 ifup "${NET_IF}" fi EOF You can also use a more specific regexp match if necessary. [[ "${NET_ADDR}" =~ "^[0-9]{2}\.[0-9]{3}\." ]] Restart WLAN on USB Wi-Fi event Niii has posted this quick example for a USB WiFi device hotplug event to trigger an init.d network restart wlan0 script. To determine RTL8188SU_PRODID variable: # lsusb -v idVendor 0x0bda Realtek Semiconductor Corp. idProduct 0x8171 RTL8188SU 802.11n WLAN Adapter bcdDevice 2.00 mkdir -p /etc/hotplug.d/usb cat << "EOF" > /etc/hotplug.d/usb/20-rtl8188su BINARY="/sbin/wifi up" RTL8188SU_PRODID="bda/8171/200" if [ "${PRODUCT}" = "${RTL8188SU_PRODID}" ]; then if [ "${ACTION}" = "add" ]; then ${BINARY} fi fi EOF Symlink instead of rename a device 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. cat << "EOF" > /etc/hotplug.d/usb/20-cp210x 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 0 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 EOF Script that detects if plugged usb device is bluetooth or not cat << "EOF" > /etc/hotplug.d/usb/20-bt_test BT_PRODID="a12/1/" BT_PRODID_HOT="${PRODUCT::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 EOF Auto start mjpg-streamer when an usb camera is plugged in cat << "EOF" > /etc/hotplug.d/usb/20-mjpg_start case "${ACTION}" in add) # start process /etc/init.d/mjpg-streamer start ;; remove) # stop process /etc/init.d/mjpg-streamer stop ;; esac EOF Custom automount script for XFS cat << "EOF" > /etc/hotplug.d/block/xfs_automount # if a new block device is connected if [ "${ACTION}" = "add" ]; then # getting device UUID detected_uuid="$(xfs_admin -u /dev/${DEVICENAME} | awk '{print $3}')" # deciding mountpoint for known UUID mountpoint="" case "${detected_uuid}" in 6a5d7c5c-c9d0-41cc-8f19-78d97f839c05) mountpoint="/path/to/first/mountpoint" ;; 02880b1f-0c67-46b6-9b05-5535680ccc89) mountpoint="/path/to/second/mountpoint" ;; esac # if we have a known UUID we have a mountpoint so we can mount it if [ "${mountpoint}" != "" ]; then mount /dev/${DEVICENAME} ${mountpoint} fi fi # unmounting happens automatically at device disconnection anyway so no logic for that EOF Coldplug If you had notice the udev and eudev were removed in the openwrt 18.0.* release, don't be afraid because you still can make the things works. You can use hotplug scripts as coldplug. Pay attention at the ACTION environment variable, at the boot are executed 'bind' actions. So, just add this option to hotplug run accordinly. In my case I used this: mkdir -p /etc/hotplug.d/usb cat << "EOF" > /etc/hotplug.d/usb/22-symlinks # Description: Action executed on boot (bind) and with the system on the fly if [ "${ACTION}" = "bind" ]; then case "${PRODUCT}" in 1bc7*) # Telit HE910 3g modules product id prefix DEVICE_NAME="$(ls /sys/${DEVPATH} | grep tty)" DEVICE_TTY="$(ls /sys/${DEVPATH}/tty/)" # Module Telit HE910-* connected to minipciexpress slot MAIN if [ "${DEVICENAME}" = "1-1.3:1.0" ]; then ln -s /dev/${DEVICE_TTY} /dev/ttyMODULO1_DIAL logger -t hotplug "Symlink from /dev/${DEVICE_TTY} to /dev/ttyMODULO1_DIAL created" elif [ "${DEVICENAME}" = "1-1.3:1.6" ]; then ln -s /dev/${DEVICE_TTY} /dev/ttyMODULO1_DATA logger -t hotplug "Symlink from /dev/${DEVICE_TTY} to /dev/ttyMODULO1_DATA created" # Module Telit HE910-* connected to minipciexpress slot SECONDARY elif [ "${DEVICENAME}" = "1-1.2:1.0" ]; then ln -s /dev/${DEVICE_TTY} /dev/ttyMODULO2_DIAL logger -t hotplug "Symlink from /dev/${DEVICE_TTY} to /dev/ttyMODULO2_DIAL created" elif [ "${DEVICENAME}" = "1-1.2:1.6" ]; then ln -s /dev/${DEVICE_TTY} /dev/ttyMODULO2_DATA logger -t hotplug "Symlink from /dev/${DEVICE_TTY} to /dev/ttyMODULO2_DATA created" fi ;; esac fi # Action to remove the symlinks if [ "${ACTION}" = "remove" ]; then case "${PRODUCT}" in 1bc7*) # Telit HE910 3g modules product id prefix # Module Telit HE910-* connected to minipciexpress slot MAIN if [ "${DEVICENAME}" = "1-1.3:1.0" ]; then rm /dev/ttyMODULO1_DIAL logger -t hotplug "Symlink /dev/ttyMODULO1_DIAL removed" elif [ "${DEVICENAME}" = "1-1.3:1.6" ]; then rm /dev/ttyMODULO1_DATA logger -t hotplug "Symlink /dev/ttyMODULO1_DATA removed" # Module Telit HE910-* connected to minipciexpress slot SECONDARY elif [ "${DEVICENAME}" = "1-1.2:1.0" ]; then rm /dev/ttyMODULO2_DIAL logger -t hotplug "Symlink /dev/ttyMODULO2_DIAL removed" elif [ "${DEVICENAME}" = "1-1.2:1.6" ]; then rm /dev/ttyMODULO2_DATA logger -t hotplug "Symlink /dev/ttyMODULO2_DATA removed" fi ;; esac fi EOF Rename interfaces by MAC address A simple method to configure persistent interface names by MAC address. cat << "EOF" > /etc/hotplug.d/iface/00-dev-rename dev_rename() { local DEV_CONF="${1}" local DEV_ONAME DEV_NAME DEV_MAC config_get DEV_NAME "${DEV_CONF}" name config_get DEV_MAC "${DEV_CONF}" mac DEV_ONAME="$(grep -l -e "${DEV_MAC}" \ $(find /sys/class/net/*/device/uevent \ | sed -e "s|/device/uevent$|/address|") \ | awk -F '/' '{print $5}')" if [ "${DEV_ONAME}" != "${DEV_NAME}" ] then ip link set "${DEV_ONAME}" name "${DEV_NAME}" fi } . /lib/functions.sh config_load network config_foreach dev_rename device EOF uci set network.wana.device="wana" uci set network.wanb.device="wanb" uci set network.wana6.device="wana" uci set network.wanb6.device="wanb" uci -q delete network.wana_dev uci set network.wana_dev="device" uci set network.wana_dev.name="wana" uci set network.wana_dev.mac="11:22:33:44:55:66" uci -q delete network.wanb_dev uci set network.wanb_dev="device" uci set network.wanb_dev.name="wanb" uci set network.wanb_dev.mac="aa:bb:cc:dd:ee:ff" uci commit network /etc/init.d/network restart log DSL status changes If you have a DSL modem you can add logging of DSL status changes and connection data rates. This can be helpful if your DSL connection is affected by Seamless Rate Adaptation (SRA) or Dynamic Line Management (DLM) events; for SRA events data rate changes will be logged, while for DLM events connection status changes will be logged as the modem is forced to retrain and then the new data rates will be logged. cat << "EOF" > /etc/hotplug.d/dsl/20-dsl_status case "${DSL_NOTIFICATION_TYPE}" in "DSL_INTERFACE_STATUS") logger -p daemon.notice -t "dsl-notify" "${DSL_XTU_STATUS} link status: ${DSL_INTERFACE_STATUS}";; "DSL_DATARATE_STATUS_US") logger -p daemon.notice -t "dsl-notify" "DSL upstream actual data rate: ${DSL_DATARATE_US_BC0}";; "DSL_DATARATE_STATUS_DS") logger -p daemon.notice -t "dsl-notify" "DSL downstream actual data rate: ${DSL_DATARATE_DS_BC0}";; esac EOF Note that this example script assumes that channel bonding is not compiled in to the DSL support. This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.OKMore information about cookies Last modified: 2023/09/20 03:37by vgaetera