Find which drive corresponds to which USB mass storage device in Linux
Asked Answered
O

4

6

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.

Outwardly answered 7/10, 2010 at 12:7 Comment(2)
(tried the same thing in XP a while ago, abandoned the effort when requirements changed; the requirements changed back, but we've moved to Linux in the meantime: #733706 )Outwardly
Eyes I have, yet I don't see. Solved (/sys/block/sdX is a symlink to the USB device)!Outwardly
O
10

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.

Outwardly answered 7/10, 2010 at 12:54 Comment(0)
D
1

I use the path:

/sys/bus/usb/drivers/usb-storage/4-1:1.0/host4/target4:0:0/4:0:0:0/block/sda

so you can see usb bus 4, port 1 is connected with a usb storage /dev/sda

Dyslogia answered 9/4, 2014 at 9:5 Comment(0)
M
-1

Can't you use disk labels? http://ubuntuforums.org/showthread.php?t=322973

Mousebird answered 7/10, 2010 at 12:23 Comment(1)
Thank you, but I've already solved that step. I can map from a mountpoint to a block device - I'm looking for a way to map the block device to the USB device and therefore to the hardware device. Edited answer to clarify.Outwardly
M
-1

Here is how I do it.

lsusb -v shows all the devices disks get an iserial number take note of them

 ls -l /dev/disk | grep [iserial] 

Everything in /dev/disk is a symlink so follow the symlink to see the device.

Mckinzie answered 22/10, 2012 at 21:44 Comment(1)
Can't get that to work, sorry: ls -l /dev/disk, in my case, contains the directories by-id by-label by-path by-uuid; lsusb -v gives me results like iSerial 3, and I seem to be unable to match that by any of the symlinks in the above directories. Moreover, the serials reported in /dev/disk/by-id seem to be valid for SATA disks, but bogus for the USB devices I have at hand: usb-Generic_USB_12345678901234567890-0:0 -> ../../sde (literally, the sequence 1-0 repeated twice). Kubuntu 12.04, kernel 3.2.0-32Outwardly

© 2022 - 2024 — McMap. All rights reserved.