Determining physical topology of hotplugged USB devices with udev

As part of a bigger project of mine, I wanted to answer the following questions: How can one tell which physical port a hotplugged usb-device is plugged into on Linux? Can one do this when the device is plugged into an usb-hub (i.e: non-root hub) too? Since this is potentially useful to others out there, I share my findings here.

The usual “lsusb” or “lsusb -v” gives no indication that the kernel knows about the physical topology of the devices connected to an USB bus. However “lsusb -t” does indeed show the topology, so the kernel does know about it and make this info available to user-space. So, how to use this in udev? Prodding some USB storage class devices with udevinfo, shows that there is no attribute that gives this information directly. But, the DEVPATH attribute for USB devices actually contains this information.

For instance, an USB mass storage device connected to port 2 of the root-hub with bus number 2 has the following devpath: “/devices/pci0000:00/0000:00:1d.7/usb2/2-2/2-2:1.0/host12/target12:0:0/12:0:0:0/block/sdb” and a USB mass storage device connected to port 5 of the root-hub with bus number 1 has the devpath “/devices/pci0000:00/0000:00:1d.7/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/block/sdb”. It becomes a bit confusing when there are USB hubs involved: “/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1.1/2-1.1.1/2-1.1.1:1.0/host16/target16:0:0/16:0:0:0/block/sdb” refers to a device plugged into port 1 of an USB hub plugged into port 1 of a second hub which is plugged into port 1 of the root-hub with bus number 2.

We see that in all cases the information about the physical topology is in the substring just before “:1.0”; “2-2”, “1-5” and “2-1.1.1”, respectively for the given examples. And that the format is “$busnumber-$port” for the simple case of connecting the device directly to the root-hub, and $busnumber-$port1.$port2  ->   .$portN for the general case, with N-1 usb-hubs between the device and the root-hub.

Just to show that this works, here is a quick and dirty udev rule and helper python script which parses the devpath and creates a symlink to the first partition of a USB mass storage device under /dev/usb based on the bus and port the device is connected to. Results might look like this:

tree /dev/usb/                                                                    Thu Jul 29 17:34:38 2010

/dev/usb/
`-- 2
    `-- 2
        |-- 2 -> ../../../sdc1
        `-- 4
            `-- 4 -> ../../../../sdb1

A more useful thing to do might for instance be passing through all devices connected to a certain physical usb-port to a certain virtual machine. Or maybe letting an embedded system responding differently to USB devices plugged into a physically secured root-hub than to one that is available to the user.

Linux everywhere?

I stopped by my local library today (must have been 5 years since last time!) and guess what I found:

library-linux-thinclient

Yes, Linux. Debian or a derivative with KDE3  running on a HP thin client. Even has Tux! At first I thought it was just this one terminal, but a quick peek told me that all the user available machines ran this system.  And several people where surfing around on the web using Firefox with the with no apparent struggles. The computers for the employees ran Windows XP though. Definitely a step in the right direction, but the fact that I was somewhat surprised tells me that Linux adoption still has a long way to go. Here is another machine:
library-linux-workstation

Maybe I’ll ask them about their experiences with the system when I go there next time. Would be interesting to hear.

At home I’ve migrated all my machines to Arch Linux x86_64 as of yesterday. Previously it was a mix of Arch 32/64 bit and Debian. No major issues yet so I guess I can say that it went pretty smooth. All the machines are now KVM capable so I’ll set them up as a small virtualization cluster. But first I want to install Linux (openWRT) on my router so that it can run DNS/BOOTP/DHCP and give me a bit more flexibility in the configuration.

I’m now also a Linux Foundation member. I’m not sure if I’ll ever use any of the benefits I get, but the cause is worth 25 usd per year none the less. I even asked them to not send me the free t-shirt. I’d never use it anyways, as it was bright white and had big logos on it. And the fit on such shirts are always the same crappy “loose” (read: “shoulder mounted tent” on a slim guy like me). Not my style.

Today I sent in my first deliverable for my senior project. We also had the first meeting and agreed on tasks for the next weeks/months. More about that later!