2

I'm working on custom Bash scripts for mass duplication of USB flash memory and mass testing (using f3).

I wonder if it's possible to identify what USB port is a pendrive plugged into.

I have USB hubs with numbered ports. If the have some static addresses that I could identify and know if something is plugged into them or not, and what is that (essentially: which /dev/sd* file corresponds to that USB port) I could make it much easier for the users to know what is going on and allow them to remove bad drives early in the process, without waiting till the whole batch is processed and then try to sort out the bad drives from the good ones (this is how I do it now).

I tried searching around but nothing I found seemed to mesh together with what I want to achieve so I decided to ask directly for help in this context.

Rigth now I identify drives by /dev/sd* node names, and the users have no idea what is that. If I could map these to USB ports in a hub, I could present the information based on the USB ports and users could know that port 5 has a bad drive plugged in and they can remove that without interfering with the rest of the process taking place.

I could then even stop doing this in batches and make all ports work simultaneously in loop, the user could plug the drives in and out all the time, keeping track on what is what by the HUB port numbers, it could greatly seed up the workflow.

So the basic question: how can I identify USB ports and USB flash memory plugged into these ports?

4

You can use udevadm to get the device path of some device. This is done by examining the symlinks in /sys/, so you could also do this manually (but it's easier to use udevadm).

For example, an USB stick plugged into an external USB hub on my system produces

$ udevadm info -q path -n /dev/sdh
/devices/pci0000:00/0000:00:1d.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3.2/3-1.1.3.2:1.0/host7/target7:0:0/7:0:0:0/block/sdh

As one can see by comparing with the USB tree,

$ lsusb -t
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
        |__ Port 1: Dev 26, If 0, Class=Hub, Driver=hub/4p, 480M
            |__ Port 3: Dev 29, If 0, Class=Hub, Driver=hub/4p, 480M
                |__ Port 2: Dev 31, If 0, Class=Mass Storage, Driver=usb-storage, 480M
                |__ Port 4: Dev 30, If 0, Class=Mass Storage, Driver=usb-storage, 480M
...

the part 3-1.1.3.2 of the path says that on bus 3, it goes through port 1 (on southbridge), again port 1 (on motherboard), port 3 (still on motherboard), and then on port 2 of the external USB hub. Port 4 of this hub is used for an SD card reader.

So depending on how your USB hub is connected, you need to do something similar, and extract the last port you are interested in.

1

Looks like /dev/disk/by-path contains symlinks to /dev/sd* nodes, and can be used to find out exactly that.

Issuing a file /dev/disk/by-path/* command lists all /dev/sd* nodes and their physical addresses. I should be able to grep my way through that pretty easily.

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.