How to create an persistent name for a device.
My Surfstick HUAWEI E160 should always have a persistent name between boots or in case i do a reconnect. The E160 creates two /dev/ttyUSB? entries, the first one for the modem, the second one for control and status information.
Examine all infos:
udevadm info --name=/dev/ttyUSB1 --attribute-walk
looking at device '/class/tty/ttyUSB1':
KERNEL=="ttyUSB1"
SUBSYSTEM=="tty"
DRIVER==""
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.0/ttyUSB1':
KERNELS=="ttyUSB1"
SUBSYSTEMS=="usb-serial"
DRIVERS=="option1"
ATTRS{port_number}=="0"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.0':
KERNELS=="5-5:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="option"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bNumEndpoints}=="03"
ATTRS{bInterfaceClass}=="ff"
ATTRS{bInterfaceSubClass}=="ff"
ATTRS{bInterfaceProtocol}=="ff"
ATTRS{modalias}=="usb:v12D1p1003d0000dc00dsc00dp00icFFiscFFipFF"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5':
KERNELS=="5-5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 4"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bMaxPower}=="500mA"
ATTRS{urbnum}=="641"
ATTRS{idVendor}=="12d1"
ATTRS{idProduct}=="1003"
ATTRS{bcdDevice}=="0000"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="5"
ATTRS{devnum}=="10"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="HUAWEI Technology"
ATTRS{product}=="HUAWEI Mobile"
looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb5':
KERNELS=="usb5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bMaxPower}==" 0mA"
ATTRS{urbnum}=="217"
ATTRS{idVendor}=="1d6b"
ATTRS{idProduct}=="0002"
ATTRS{bcdDevice}=="0206"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="5"
ATTRS{devnum}=="1"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="8"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="Linux 2.6.26-2-686 ehci_hcd"
ATTRS{product}=="EHCI Host Controller"
ATTRS{serial}=="0000:00:1d.7"
ATTRS{authorized_default}=="1"
looking at parent device '/devices/pci0000:00/0000:00:1d.7':
KERNELS=="0000:00:1d.7"
SUBSYSTEMS=="pci"
DRIVERS=="ehci_hcd"
ATTRS{vendor}=="0x8086"
ATTRS{device}=="0x24dd"
ATTRS{subsystem_vendor}=="0x1458"
ATTRS{subsystem_device}=="0x5006"
ATTRS{class}=="0x0c0320"
ATTRS{irq}=="23"
ATTRS{local_cpus}=="ff"
ATTRS{local_cpulist}=="0-7"
ATTRS{modalias}=="pci:v00008086d000024DDsv00001458sd00005006bc0Csc03i20"
ATTRS{enable}=="1"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}==""
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
The only difference between ttyUSB1 and ttyUSB2 is ATTRS{bInterfaceNumber}==“00” and ATTRS{bInterfaceNumber}==“01”, so it is essential to use only the parent who matches this information (⇒ If multiple keys that match a parent device are specified in a single rule, all these keys must match at one and the same parent device).
Now we go to /etc/udev/rules.d and create out custom rules definition:
touch 92-persistent-local.rules
Next we want a symlink created to point to the Surfstick without the need to fiddle with ttyUSB?:
KERNEL=="ttyUSB?", ATTRS{bInterfaceNumber}=="00", ATTRS{modalias}=="usb:v12D1p1003d0000dc00d", SYMLINK+="ttyHUAWEI0"
KERNEL=="ttyUSB?", ATTRS{bInterfaceNumber}=="01", ATTRS{modalias}=="usb:v12D1p1003d0000dc00d", SYMLINK+="ttyHUAWEI1"
Test if all works as expcted:
udevadm test /devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.1/ttyUSB2
OK, our symlinks ttyHUAWEI? should be created if we force the change:
udevadm test /devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.1/ttyUSB2 --force This program is for debugging only, it does not run any program, specified by a RUN key. It may show incorrect results, because some values may be different, or not available at a simulation run. add_matching_files: unable to open '/lib/udev/rules.d': No such file or directory parse_file: reading '/etc/udev/rules.d/50-udev.rules' as rules file parse_file: reading '/etc/udev/rules.d/60-persistent-input.rules' as rules file parse_file: reading '/etc/udev/rules.d/60-persistent-storage-tape.rules' as rules file parse_file: reading '/etc/udev/rules.d/60-persistent-storage.rules' as rules file parse_file: reading '/etc/udev/rules.d/60-persistent-v4l.rules' as rules file parse_file: reading '/dev/.udev/rules.d/61-dev-root-link.rules' as rules file parse_file: reading '/etc/udev/rules.d/65_mdadm.vol_id.rules' as rules file parse_file: reading '/etc/udev/rules.d/70-persistent-cd.rules' as rules file parse_file: reading '/etc/udev/rules.d/70-persistent-net.rules' as rules file parse_file: reading '/etc/udev/rules.d/75-cd-aliases-generator.rules' as rules file parse_file: reading '/etc/udev/rules.d/75-persistent-net-generator.rules' as rules file parse_file: reading '/etc/udev/rules.d/80-drivers.rules' as rules file parse_file: reading '/etc/udev/rules.d/91-permissions.rules' as rules file parse_file: reading '/etc/udev/rules.d/92-persistent-local.rules' as rules file parse_file: reading '/etc/udev/rules.d/95-late.rules' as rules file import_uevent_var: import into environment: 'DRIVER=option1' import_uevent_var: import into environment: 'PHYSDEVBUS=usb-serial' import_uevent_var: import into environment: 'PHYSDEVDRIVER=option1' udevtest: looking at device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.1/ttyUSB2' from subsystem 'usb-serial' udevtest: run: 'socket:@/org/kernel/udev/monitor'
And that's the result:
ls -la /dev/ttyHUAWEI? lrwxrwxrwx 1 root root 7 23. Nov 15:32 /dev/ttyHUAWEI0 -> ttyUSB0 lrwxrwxrwx 1 root root 7 23. Nov 15:32 /dev/ttyHUAWEI1 -> ttyUSB1
With a Debian Etch installation I encounterd the following problem:
the system was installed with an (optional) Intel Etherexpress (eepro100) as eth0. After installation the card was removed. There were still two Intel Pro/1000 cards present (eth1 and eth2).
Problem:
After reboot, eth0 wouldn't work as the system expects the eepro100 card still present.
Solution: