====== Persistent symlinks for devices with udev ====== - Locate the device: ''/dev/usb/hiddev0''root@misaka:~# ls /dev/usb/hiddev0 -l crw------- 1 root root 180, 0 Dec 19 13:00 /dev/usb/hiddev0 - Get device characteristics from udev. root@misaka:~# udevadm info --name=/dev/usb/hiddev0 --attribute-walk ...snip... looking at device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0/usbmisc/hiddev0': KERNEL=="hiddev0" SUBSYSTEM=="usbmisc" DRIVER=="" looking at parent device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0': KERNELS=="9-2:1.0" SUBSYSTEMS=="usb" DRIVERS=="usbhid" ...snip... looking at parent device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2': KERNELS=="9-2" SUBSYSTEMS=="usb" DRIVERS=="usb" ...snip... ATTRS{idProduct}=="0002" ATTRS{idVendor}=="051d" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="APC" ATTRS{maxchild}=="0" ATTRS{product}=="Back-UPS 650 FW:822.A3.I USB FW:A3" ...snip... ...snip... - Write ''udev'' rule ACTION=="add", SUBSYSTEM=="usbmisc", ATTRS{idProduct}=="0002", ATTRS{idVendor}=="051d", SYMLINK+="apcups" - Reload ''udev'' root@misaka:~# udevadm control --reload-rules - Try rules root@misaka:~# udevadm test --action=add $(udevadm info -q path -n /dev/usb/hiddev0) ... snip ... LINK 'apcups' /etc/udev/rules.d/99-apcups.rules:1 handling device node '/dev/usb/hiddev0', devnum=c180:0, mode=0600, uid=0, gid=0 preserve permissions /dev/usb/hiddev0, 020600, uid=0, gid=0 preserve already existing symlink '/dev/char/180:0' to '../usb/hiddev0' found 'c180:0' claiming '/run/udev/links/\x2fapcups' creating link '/dev/apcups' to '/dev/usb/hiddev0' creating symlink '/dev/apcups' to 'usb/hiddev0' created db file '/run/udev/data/c180:0' for '/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0/usbmisc/hiddev0' ACTION=add DEVLINKS=/dev/apcups DEVNAME=/dev/usb/hiddev0 DEVPATH=/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0/usbmisc/hiddev0 MAJOR=180 MINOR=0 SUBSYSTEM=usbmisc UPOWER_BATTERY_TYPE=ups UPOWER_VENDOR=APC USEC_INITIALIZED=23088813 Unload module index Unloaded link configuration context. - Apply new rules root@misaka:~# udevadm trigger --sysname-match=hiddev0 --action=add --verbose /sys/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0/usbmisc/hiddev0 root@misaka:~# ls /dev/apcups -l lrwxrwxrwx 1 root root 11 Dec 20 01:00 /dev/apcups -> usb/hiddev0 root@misaka:~# udevadm info --name=/dev/usb/hiddev0 --attribute-walk Udevadm info starts with the device specified by the devpath and then walks up the chain of parent devices. It prints for every device found, all possible attributes in the udev rules key format. A rule to match, can be composed by the attributes of the device and the attributes from one single parent device. looking at device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0/usbmisc/hiddev0': KERNEL=="hiddev0" SUBSYSTEM=="usbmisc" DRIVER=="" looking at parent device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2/9-2:1.0': KERNELS=="9-2:1.0" SUBSYSTEMS=="usb" DRIVERS=="usbhid" ATTRS{authorized}=="1" ATTRS{bAlternateSetting}==" 0" ATTRS{bInterfaceClass}=="03" ATTRS{bInterfaceNumber}=="00" ATTRS{bInterfaceProtocol}=="00" ATTRS{bInterfaceSubClass}=="00" ATTRS{bNumEndpoints}=="01" ATTRS{supports_autosuspend}=="1" looking at parent device '/devices/pci0000:00/0000:00:1d.1/usb9/9-2': KERNELS=="9-2" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="8" ATTRS{bMaxPower}=="0mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="0106" ATTRS{bmAttributes}=="e0" ATTRS{busnum}=="9" ATTRS{configuration}=="" ATTRS{devnum}=="2" ATTRS{devpath}=="2" ATTRS{idProduct}=="0002" ATTRS{idVendor}=="051d" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="APC" ATTRS{maxchild}=="0" ATTRS{product}=="Back-UPS 650 FW:822.A3.I USB FW:A3" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{serial}=="XXXXXXXXXXXX " ATTRS{speed}=="1.5" ATTRS{urbnum}=="48204" ATTRS{version}==" 1.10" looking at parent device '/devices/pci0000:00/0000:00:1d.1/usb9': KERNELS=="usb9" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{authorized_default}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="09" ATTRS{bDeviceProtocol}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="0mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="0409" ATTRS{bmAttributes}=="e0" ATTRS{busnum}=="9" ATTRS{configuration}=="" ATTRS{devnum}=="1" ATTRS{devpath}=="0" ATTRS{idProduct}=="0001" ATTRS{idVendor}=="1d6b" ATTRS{interface_authorized_default}=="1" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="Linux 4.9.0-4-amd64 uhci_hcd" ATTRS{maxchild}=="2" ATTRS{product}=="UHCI Host Controller" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{serial}=="0000:00:1d.1" ATTRS{speed}=="12" ATTRS{urbnum}=="24" ATTRS{version}==" 1.10" looking at parent device '/devices/pci0000:00/0000:00:1d.1': KERNELS=="0000:00:1d.1" SUBSYSTEMS=="pci" DRIVERS=="uhci_hcd" ATTRS{broken_parity_status}=="0" ATTRS{class}=="0x0c0300" ATTRS{consistent_dma_mask_bits}=="32" ATTRS{d3cold_allowed}=="0" ATTRS{device}=="0x3a35" ATTRS{dma_mask_bits}=="32" ATTRS{driver_override}=="(null)" ATTRS{enable}=="1" ATTRS{irq}=="19" ATTRS{local_cpulist}=="0-3,8-11" ATTRS{local_cpus}=="000f0f" ATTRS{msi_bus}=="1" ATTRS{numa_node}=="0" ATTRS{subsystem_device}=="0x0006" ATTRS{subsystem_vendor}=="0x15d9" ATTRS{vendor}=="0x8086" looking at parent device '/devices/pci0000:00': KERNELS=="pci0000:00" SUBSYSTEMS=="" DRIVERS=="" ===== See Alsos ===== * https://unix.stackexchange.com/questions/39370/how-to-reload-udev-rules-without-reboot * https://unix.stackexchange.com/questions/66901/how-to-bind-usb-device-under-a-static-name * https://unix.stackexchange.com/questions/394411/persistent-names-for-physical-usb-ports * https://github.com/signal11/hidapi/blob/master/udev/99-hid.rules {{tag>udev}}