Score:1

udev rule for similar devices

ve flag

I'm struggling in creation of udev rules for some similar devices (serial USB port). Here the output of the detail from one of them:

$ udevadm info --name=/dev/ttyACM0 --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:15.0/usb1/1-3/1-3:1.0/tty/ttyACM0':
    KERNEL=="ttyACM0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:15.0/usb1/1-3/1-3:1.0':
    KERNELS=="1-3:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="cdc_acm"
    ATTRS{iad_bFunctionClass}=="02"
    ATTRS{iad_bInterfaceCount}=="02"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{iad_bFunctionSubClass}=="02"
    ATTRS{iad_bFirstInterface}=="00"
    ATTRS{bInterfaceSubClass}=="02"
    ATTRS{authorized}=="1"
    ATTRS{iad_bFunctionProtocol}=="00"
    ATTRS{bmCapabilities}=="6"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bInterfaceClass}=="02"
    ATTRS{bNumEndpoints}=="01"

  looking at parent device '/devices/pci0000:00/0000:00:15.0/usb1/1-3':
    KERNELS=="1-3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{maxchild}=="0"
    ATTRS{busnum}=="1"
    ATTRS{speed}=="12"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{rx_lanes}=="1"
    ATTRS{bDeviceSubClass}=="02"
    ATTRS{idVendor}=="2341"
    ATTRS{devnum}=="6"
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{quirks}=="0x0"
    ATTRS{devpath}=="3"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bDeviceClass}=="ef"
    ATTRS{tx_lanes}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{manufacturer}=="Arduino"
    ATTRS{ltm_capable}=="no"
    ATTRS{removable}=="unknown"
    ATTRS{product}=="Nano 33 BLE"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{idProduct}=="805a"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{authorized}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{serial}=="F594686789F67DE5"
    ATTRS{bcdDevice}=="0101"
    ATTRS{configuration}==""
    ATTRS{urbnum}=="13"
    ATTRS{bmAttributes}=="c0"

  looking at parent device '/devices/pci0000:00/0000:00:15.0/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceClass}=="09"
    ATTRS{maxchild}=="8"
    ATTRS{ltm_capable}=="no"
    ATTRS{urbnum}=="85"
    ATTRS{manufacturer}=="Linux 5.11.0-38-generic xhci-hcd"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{product}=="xHCI Host Controller"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{devpath}=="0"
    ATTRS{devnum}=="1"
    ATTRS{rx_lanes}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{authorized_default}=="1"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{idProduct}=="0002"
    ATTRS{authorized}=="1"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{serial}=="0000:00:15.0"
    ATTRS{configuration}==""
    ATTRS{removable}=="unknown"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{idVendor}=="1d6b"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bcdDevice}=="0511"
    ATTRS{tx_lanes}=="1"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{interface_authorized_default}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:15.0':
    KERNELS=="0000:00:15.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{revision}=="0x0d"
    ATTRS{irq}=="126"
    ATTRS{driver_override}=="(null)"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{device}=="0x5aa8"
    ATTRS{subsystem_vendor}=="0x8086"
    ATTRS{enable}=="1"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{vendor}=="0x8086"
    ATTRS{subsystem_device}=="0x5aa8"
    ATTRS{power_state}=="D0"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{dbc}=="disabled"
    ATTRS{class}=="0x0c0330"
    ATTRS{ari_enabled}=="0"
    ATTRS{local_cpus}=="f"
    ATTRS{broken_parity_status}=="0"
    ATTRS{numa_node}=="-1"
    ATTRS{msi_bus}=="1"
    ATTRS{d3cold_allowed}=="1"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

At first I want to create a rule for this device, without using the serial attribute (see below).

In /etc/udev/rules.d I created 10-gesture.rules with this content:

SUBSYSTEM=="tty",SUBSYSTEMS=="usb",DRIVERS=="cdc_acm",ATTRS{idVendor}=="2341",ATTRS{idProduct}=="805a",SYMLINK+="gesture"

then:

$ sudo chmod 0644 10-gesture.rules
$ udevadm control --reload-rules && udevadm trigger

but the symlink is not created. I also tried to:

$ sudo udevadm control --log-priority=debug
$ journalctl -f

but I find nothing relevant.

First question: I surely did something wrong in the rule. May you help me to find out what?

I don't want to use the serial attribute because I need to connect several of these devices. I won't known their serial name (the actual devices can change, by the way) so I would rely on the type of device (SUBSYSTEM, SUBSYSTEMS, DRIVERS and idVendor/idProduct attributes).

Second question: how to create symlink with a progressive number (i.e. "gesture1", "gesture2") for all devices that match the rule? The order is not important.

Ubuntu 20.04

Score:1
ng flag
  • 10-gesture.rules 10 is very early for such devices and this rule just to create simlinks.

    Try using high number 90~99 only if you know rules that you want to override (fully or partially) or influence its actions later)

  • udev support variable substitution, so you could use some attributes in symlink name. Otherwise, create a script that verify previous symlinks (or store last number in a file), increment and use it with RUN+="" action.

ve flag
I'll try your hint and then I come back with a feedback. I set it to `10-` because the `/etc/udev/rules.d` directory was empty, so I assumed there were no earlier rules...
user.dz avatar
ng flag
@Mark , you need to be aware there multiple rules locations and they are get scanned by udev all together, see https://unix.stackexchange.com/a/205738/12209 . Recommended to keep your custom rules in `/etc/udev/rules.d` and watch out for similar number and names in other folders, so you know the order and avoid unintended override. Also you may test using `udevadm test ...` to see all rules loaded and which action get triggered.
ve flag
Got it, thanks! But unfortunately even moving the rules to `99-` did not work. I changed the rule to `KERNEL=="ttyACM*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", SYMLINK+="ttyGesture%n", GROUP="dialout", MODE="0666"` and in this way it's triggered. But I'm not sure if it's the correct approach.
user.dz avatar
ng flag
@Mark Good, your approach is good as long as you don't have similar device that could interfere. While it is more strict then previous one, could be that symlink is getting rewritten multiple times in previous setup!
ve flag
Is there a way to show these rewrites? It would be useful for debugging
user.dz avatar
ng flag
@Mark one way is to add logging script with `RUN+=""` another is to use `udevadm trigger ...` and `udevadm monitor -u` . I resumed once such hints in https://unix.stackexchange.com/a/207712/12209 , I used to `echo` a line into a log file each time the rule is triggered and record the node name and or path.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.