OK, so now for a problem that probably only affects me. I have multiple UPSes in my server closet. A large one (APC BackUPS XS-1300 LCD) for most of the computers in the closet and a mid-sized one (APC BackUPS XS-900) for the computers in my office. I have a long wire running through the floor into my office. Why not put the mid-sized one in the office itself? Because it has a noisy fan.
Both these USPes are connected via USB to one computer. This computer assigns nearly randomly the device name, based on where I've plugged them into a USB hub. This resulted in the computers in the basement thinking they were on the 900 and my office thinking it was on the 1300. Not acceptable.
Using lsusb, I see the UPSes are at 2:5 and 2:4
# lsusb
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 005 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
Bus 002 Device 005: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 002 Device 002: ID 05e3:0604 Genesys Logic, Inc. USB 1.1 Hub
Bus 002 Device 001: ID 0000:0000
Bus 002 Device 004: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Again with lsusb, I can find the serial number:
# lsusb -v -s 2:5
Bus 002 Device 005: ID 051d:0002 American Power Conversion Uninterruptible Power Supp
ly
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x051d American Power Conversion
idProduct 0x0002 Uninterruptible Power Supply
bcdDevice 1.06
iManufacturer 3 American Power Conversion
iProduct 1 Back-UPS XS 900 FW:830.E8 .D USB FW:E8
iSerial 2 BB0842016813
... SNIP ...
Another way to get the same info:
# udevinfo -a -p /class/usb_device/usbdev2.5
looking at device '/class/usb_device/usbdev2.5':
KERNEL=="usbdev2.5"
SUBSYSTEM=="usb_device"
SYSFS{dev}=="189:132"
looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3':
ID=="2-1.3"
BUS=="usb"
DRIVER=="usb"
SYSFS{configuration}==""
SYSFS{serial}=="BB0842016813 "
SYSFS{product}=="Back-UPS XS 900 FW:830.E8 .D USB FW:E8 "
SYSFS{manufacturer}=="American Power Conversion"
SYSFS{maxchild}=="0"
SYSFS{version}==" 1.10"
... SNIP ...
Then I created some custom udev rules in /etc/udev/rules.d/99-apc.rules:
KERNEL=="hiddev*", SYSFS{serial}=="BB0842016813*", NAME="apc900"
KERNEL=="hiddev*", SYSFS{serial}=="JB0741003708*", NAME="apc1300"
I could also have used SYSFS{product} for matching, but the serial number uniquely defines these UPSes. I need the * for globbing because the serial number is padded with spaces, as can be seen in the udevinfo output.
Next reload the udev db:
# udevcontrol reload_rules
# udevtrigger
# ls -l /dev/apc*
crw------- 1 root root 180, 97 Oct 5 12:53 /dev/apc1300
crw------- 1 root root 180, 96 Oct 5 12:53 /dev/apc900
YAY!