Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find which drive corresponds to which USB mass storage device in Linux

I have several USB mass storage flash drives connected to a Ubuntu Linux computer (Ubuntu 10.04.1, kernel 2.6.32-25-386), and I need to tell them apart programatically (from bash if possible, but I'm not afraid of compiling either) - I need to find which block device corresponds to which physical device (e.g. /dev/sdb1 -> device in USB port 1; in my case, one device ~ one volume).

In other words, I know that I have three hardware devices plugged into USB ports; each of them shows up in the system as a USB mass storage device (as seen with lsusb), is created as a block device (/dev/sdb1) and automounted by UUID (/media/1234-5678).

USB device               block device    mountpoint
USB device in port 2.2 <-> /dev/sdb1   <-> /media/1234-5678

I'm not trying to find the relationship between block device and mountpoint; I'm trying to find the relationship between block device and USB device, is there a way?

Why? There will be some writes on the disks, with unpredictable time of completion. I need to give the operator some indication like "you can now remove the disk in port 2 (which is second from the left)". I have found which physical port corresponds to which port number on that specific machine, and finding block devices from mountpoints is simple; now I'm stuck mapping the logical USB ports to block devices.

I can see the disks with lsusb :

Bus 001 Device 058: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device
Bus 001 Device 060: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device
Bus 001 Device 061: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device

and I can see them mounted (by their UUID):

/dev/sdb1 on /media/BC88-15C4 type vfat
/dev/sdc1 on /media/AE54-65AA type vfat
/dev/sdd1 on /media/58D2-FED1 type vfat

Now, all the drives are the same model from the same manufacturer, so I can't distinguish them by that, and I can't guarantee they'll be plugged in a particular order.

I have found /sys/bus/usb/devices (a list of USB devices), but it seems to be the same data that I get from lsusb - I don't see a mapping to disks there.

There's also /sys/block/sdb and /sys/block/sdb/sdb1 (the block device and its first partition; similarly for sdc and sdd), but again, I see no mapping to devices.

like image 898
Piskvor left the building Avatar asked Oct 07 '10 12:10

Piskvor left the building


1 Answers

I'm not sure in which kernel version this was implemented, but the /sys/block/* entries are symlinks to the devices.

In other words, /sys/block/sdb symlinks to a different directory, and its name contains the USB device ID.

$ file /sys/block/sdb
/sys/block/sdb: symbolic link to `../devices/pci0000:00/0000:00:02.1/usb1/1-1/1-1.1/1-1.1:1.0/host31/target31:0:0/31:0:0:0/block/sdb'
                                                  USB version and port here---^^^^^

The 1-1.1 is the interesting part, denoting usb1-port 1.device 1. When plugged into a hub, another level is added: 1-2.3.1, denoting usb1-port 2.port 3.device 1.

Pseudocode:

get partition name # e.g. /dev/sdb1
get disk name # that would be /dev/sdb
get your basename # sdb
see where /sys/block/$your_basename points to # e.g. ../devices/blah/blah/1-2.1/blah
get the longest substring matching "\d-\d+(.\d+)*"  # e.g. 1-2.1
that is the device id you want
/sys/bus/usb/devices/$device_id/ has all kinds of information about it
the ID corresponds to hardware USB ports

Working example script in bash.

like image 134
Piskvor left the building Avatar answered Nov 14 '22 21:11

Piskvor left the building