I'm trying to set up consistent device names for some USB devices on my home automation server on an Ubuntu 17.04 VM running under ESXi 6. So far, I have the following rules in /etc/udev/rules.d/99-usb-serial.rules:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idproduct}=="6001", ATTRS{serial}=="A19DVOA", SYMLINK+="USBrfxcom", MODE="0660", GROUP="dialout"
KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="USBzwave2", MODE="0660", GROUP="dialout"
KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="USBzwave5", MODE="0660", GROUP="dialout"
KERNEL=="ttyACM[0-9]*", SUBSYSTEM=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", SYMLINK+="USBcul",    MODE="0660", GROUP="dialout"

The first rule with vendorid 0403 and productid 6001 isn't such a big deal at the moment since it's the only device that appears in the /dev/ttyUSB* range, i.e. it's always /dev/ttyUSB0, though that might change in the future when I add more devices. Rules 2-4 are the problematic ones, they all trigger for three devices I have in the /dev/ttyACM* range. After a reboot each USB device can appear as any of /dev/ttyACM0 /dev/ttyACM1 or /dev/ttyACM2, I'd like them to appear as /dev/USBzwave2, /dev/USBzwave5 and /dev/USBcul.

The output of sudo udevadm test -a -p $(udevadm info -q path -n /dev/ttyACM1) gives me:

Reading rules file: /etc/udev/rules.d/99-usb-serial.rules
Reading rules file: /lib/udev/rules.d/99-vmware-scsi-udev.rules
rules contain 49152 bytes tokens (4096 * 12 bytes), 14768 bytes strings
2093 strings (26721 bytes), 1358 de-duplicated (12689 bytes), 736 trie nodes used
value '[dmi/id]sys_vendor' is 'VMware, Inc.'
value '[dmi/id]sys_vendor' is 'VMware, Inc.'
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-serial.rules:7
IMPORT builtin 'usb_id' /lib/udev/rules.d/60-serial.rules:8
/sys/devices/pci0000:00/0000:00:17.0/0000:13:00.0/usb1/1-3/1-3.2/1-3.2:1.0: if_class 2 protocol 0
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-serial.rules:8
IMPORT builtin 'path_id' /lib/udev/rules.d/60-serial.rules:15
LINK 'serial/by-path/pci-0000:13:00.0-usb-0:3.2:1.0' /lib/udev/rules.d/60-serial.rules:16
IMPORT builtin skip 'usb_id' /lib/udev/rules.d/60-serial.rules:19
LINK 'serial/by-id/usb-busware.de_CUL868-if00' /lib/udev/rules.d/60-serial.rules:23
GROUP 20 /etc/udev/rules.d/99-usb-serial.rules:4
MODE 0660 /etc/udev/rules.d/99-usb-serial.rules:4
LINK 'USBcul' /etc/udev/rules.d/99-usb-serial.rules:4
handling device node '/dev/ttyACM1', devnum=c166:1, mode=0660, uid=0, gid=20
preserve permissions /dev/ttyACM1, 020660, uid=0, gid=20
preserve already existing symlink '/dev/char/166:1' to '../ttyACM1'
found 'c166:1' claiming '/run/udev/links/\x2fUSBcul'
creating link '/dev/USBcul' to '/dev/ttyACM1'
preserve already existing symlink '/dev/USBcul' to 'ttyACM1'
found 'c166:1' claiming '/run/udev/links/\x2fserial\x2fby-id\x2fusb-busware.de_CUL868-if00'
creating link '/dev/serial/by-id/usb-busware.de_CUL868-if00' to '/dev/ttyACM1'
preserve already existing symlink '/dev/serial/by-id/usb-busware.de_CUL868-if00' to '../../ttyACM1'
found 'c166:1' claiming '/run/udev/links/\x2fserial\x2fby-path\x2fpci-0000:13:00.0-usb-0:3.2:1.0'
creating link '/dev/serial/by-path/pci-0000:13:00.0-usb-0:3.2:1.0' to '/dev/ttyACM1'
preserve already existing symlink '/dev/serial/by-path/pci-0000:13:00.0-usb-0:3.2:1.0' to '../../ttyACM1'
created db file '/run/udev/data/c166:1' for '/devices/pci0000:00/0000:00:17.0/0000:13:00.0/usb1/1-3/1-3.2/1-3.2:1.0/tty/ttyACM1'
DEVLINKS=/dev/serial/by-id/usb-busware.de_CUL868-if00 /dev/USBcul /dev/serial/by-path/pci-0000:13:00.0-usb-0:3.2:1.0
ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
Unload module index
Unloaded link configuration context.

This seems 99% of the way to a solution but, if I'm reading the output correctly, the rules seem to be creating two symlinks:

creating link '/dev/USBcul' to '/dev/ttyACM1'
preserve already existing symlink '/dev/USBcul' to 'ttyACM1'

The first line looks good, the second line looks wrong.

ls -l /dev/USB* gives:

lrwxrwxrwx 1 root root 7 Oct  1 14:46 /dev/USBcul -> ttyACM1

I think that should instead be:

lrwxrwxrwx 1 root root 7 Oct  1 14:46 /dev/USBcul -> /dev/ttyACM1

Also, the group specified in the rule seems to be being ignored, it should be set to dialout rather than root, also, the permissions are wrong, they're 777 not 660. I assume these permission issues are caused by the incorrect symlink.

So, what am I missing? It feels like it's staring me in the face but I just can't see it.


Both symlinks in your example point to the same thing. The second one (/dev/USBcul -> ttyACM) is a relative symlink. A relative symlink points to a file in the same directory the symlink resides in, in this case /dev.

Permissions on symlinks are not used: access to the target file is determined by the permissions and ownership of the target file. A symbolic link gets its user and group ownership from the uid and gid of the process that created the link. In your example the link was created by root. Once again, the ownership of the link has very little significance: access to the file pointed is determined by the ownership of the target file. One situation where the ownership of the link matters is when it is contained in a directory with the sticky bit set; then only the owner of the link can remove it.

What was your problem again?

| improve this answer | |
  • Now that is very interesting info, thanks. The reason I thought the links created by the udev rules didn't work is that when I changed the config the home automation software for the CUL device from /dev/ttyACM0 to /dev/USBcul the HA software output an error saying that the device couldn't be accessed. According to your info, there should be no problem with the symlinks. I'll check again. – higgers Oct 2 '17 at 16:27
  • 1
    The issue was that OpenHAB by default is only able to access devices in /dev that have a name beginning with the usual ttyXXXN. Once I'd added the names of the new symlinks to the JAVA_ARGS parameter in the openhab config file and restarted the problem went away. Many thanks for your help. – higgers Oct 3 '17 at 21:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.