7

In my question Bash script to output path to USB flash memory stick I got stuck on a problem nobody else seems to be having. (The issue also impedes my desire to use this answer.)

So I made that specific problem into this new question.

Apparently removable devices listed in /sys/block end with 1. It is stated here and several other places in this site and this principle is used in the answers I referenced above.

My removable device, a Sandisk 64GB flash memory stick, is listed as:

/sys/block/sdl/removable:0 

Apparently, removable devices should end in 1 (and my others do). Why does my USB memory stick not follow the rule?

It was automounted by Dolphin. I'm running Kubuntu 12.04.

Dolphin shows it as "59.6GiB Removable Media".

And it is mounted (automatically) at /media/me/70E8-1567

sudo blkid shows it as:

/dev/sdl1: UUID="70E8-1567" TYPE="vfat". 

lsblk -do name,rm shows:

sdl 0 

And lsusb -vv shows:

Bus 001 Device 008: ID 0781:5530 SanDisk Corp. Cruzer Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0781 SanDisk Corp. idProduct 0x5530 Cruzer bcdDevice 2.01 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 200mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 1 
5
  • How is it listed if you do: lsblk -do name,rm? 1 or 0 ? Commented Mar 15, 2014 at 1:36
  • Could you give us lsusb ID corresponding? Commented Mar 15, 2014 at 1:39
  • @F.Hauri added lsusb output. Thanks Commented Mar 15, 2014 at 3:32
  • @mikeserv I added output of lsblk -do name,rm. Thanks. Commented Mar 15, 2014 at 3:32
  • Ok, could you please give me the output of: grep -H . /sys/block/sdl/events (meaning sdl is your usb key;)... Commented Mar 15, 2014 at 10:30

3 Answers 3

4

Ok, so to pull this in a list, you can use the same command I gave you before, but just drop the removeable requirement:

% for blk in $(lsblk -ndo name) ; do > udevadm info --query=all --name "$/dev/$blk" |\ > grep -q ID_BUS=usb && printf \ > 'findmnt %s -no TARGET ;'\ > "/dev/$blk" /dev/"$blk"[0-9] > } ; done 2>&- |. /dev/stdin 

It's no big deal - it will now only output active mountpoints for block devices on the usb bus and I, for one, can't think of many examples of non-removable usb block devices anyway.

Regarding why your current device does not register as removeable, the most likely answer is that its driver simply doesn't list it that way. When devices are detected by udev it pulls in information on them as soon as it can based on its rules database. You can see all of those classifications with:

% udevadm info --query=all --name /dev/$BLOCK_DEVICE 

That will return a list of all of the key=value entries the system uses to classify the hardware referenced by /dev/$BLOCK_DEVICE. At the bottom of this post slm advises how this information can be easily parsed to serve your needs - and it's pretty simple indeed. The documentation rightly describes it as "human-readable, grep-friendly." Above I filter all block devices to only those on the usb bus with:

% grep -q ID_BUS=usb 

You can also attribute-walk all the way up the device tree for your current device and another whose attributes you think it should reflect. If it doesn't, it is because udev assigned it differently than you think it should have. Thankfully, though, you can see every datapoint that affected its assignment with:

udevadm info --attribute-walk --name /dev/$BLOCK_DEVICE 

You can use this data to model new assignment rules as you please.

9
  • Unfortunely, this may show empty card reader or empty cdrom. Commented Mar 15, 2014 at 9:48
  • This is not an answer to the question: Why USB stick listed as non-removable... Commented Mar 15, 2014 at 10:22
  • I hope I fixed that just now. Commented Mar 15, 2014 at 13:13
  • If you wanna have a look, there is the whole script: Commented Mar 18, 2014 at 6:16
  • I saw it. It's pretty good, but you'd be a lot better off working with the tools as intended instead of manipulating their side effects. The problem with side effects is that they tend to change without notice. Commented Mar 18, 2014 at 6:46
2

USB removable storage selector: USBKeyChooser

Rewrited 2022-01-05:

USBKEYS=() while read _{,,,,,,} dev _ rdev;do [[ $rdev == */usb[0-9]* ]] && grep -q '^DRIVER=sd$' /sys/block/$dev/device/uevent && (( $(</sys/block/$dev/size) )) && (( $(</sys/block/$dev/removable) )) && USBKEYS+=($dev) done < <(/bin/ls --color=never -g /sys/block) 

Rewind:

In this I

  • Ensure this is USB

  • Ensure device is removable

  • Ensure this work as an hard drive (not a CD-Rom)

  • Ensure they have size greater than 0 (not an empty Card reader)

In fine: usbKeyChooser

There is the final version of usbKeyChooser subroutine in my live installer:

#!/bin/bash DIALOG=whiptail usbKeyChoose() { while [ ! -b /dev/$STICK ] ;do USBKEYS=() while read _{,,,,,,} dev _ rdev;do [[ $rdev == */usb[0-9]* ]] && grep -q '^DRIVER=sd$' /sys/block/$dev/device/uevent && (( $(</sys/block/$dev/size) )) && (( $(</sys/block/$dev/removable) )) && USBKEYS+=($dev) done < <(/bin/ls --color=never -g /sys/block) (( ${#USBKEYS[@]} )) && title="Choose wich USB stick have to be installed" || title="No key found" menu=(R "Re scan devices") for dev in ${USBKEYS[@]} ;do read model </sys/block/$dev/device/model menu+=($dev "$model") done ans=$($DIALOG --menu "$title" 21 72 14 "${menu[@]}" 2>&1 >/dev/tty) if [ ! "$ans" ]; then echo "User aborted."; return 1; fi [[ $ans == R ]] || STICK=$ans done } usbKeyChoose [[ $0 == "$BASH_SOURCE" ]] && [[ $STICK ]] && echo $STICK true 

I like this looping solution because they

  • let insert many keys,
  • wait for kernel registration,
  • valid the choice,
  • default to nothing and
  • permit user abort.

Anyway, even if user did wrong ok choice, next screen is another choice asking user for which image have to be written on key defaulting to create new image wich is a very long process where user could hit Ctrl+c

13
  • So you negate ATA devices from your possible results? What if you have an nfs mount? Will your script diskdump on it? Commented Mar 15, 2014 at 13:36
  • @mikeserv nfs mount could not be listed by /sys/block/*/device/... maybe dr::bd (I will look), but not nfs! Commented Mar 15, 2014 at 14:23
  • @mikeserv /sys/block/drbd1/removable hold 0 and /sys/block/drbd1/device/vendor don't exist anyway. Commented Mar 15, 2014 at 14:27
  • What about real SCSI? Or serial? Commented Mar 15, 2014 at 15:24
  • this works for me. I like it. Commented Mar 15, 2014 at 16:26
0

This is F. Hauri's answer adapted for kdialog:

#!/bin/bash DIALOG=kdialog usbKeyChoose() { while [ ! -b /dev/$STICK ] ;do USBKEYS=($( xargs -n1 readlink < <(echo /sys/block/*) | sed -ne 's+^.*/usb[0-9].*/\([^/]*\)$+/sys/block/\1/device/uevent+p' | xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ | cut -d / -f 4 )) if [ ${#USBKEYS[@]} -eq 0 ];then title="No key found" else title="Choose wich USB stick have to be installed" fi menu=(R "Re scan devices") i=0 for dev in ${USBKEYS[@]} ;do read model </sys/block/$dev/device/model #echo $i $dev "$model" menu+=("$i" "$dev $model") i=$[i + 1] done num=$($DIALOG --menu "$title" "${menu[@]}") #echo "num=$num" #echo "USBKEYS[num]=${USBKEYS[num]}" if [ ! "$num" ] ; then echo "User aborted." exit 0; fi [ ! "$num" = "R" ] && [ "${USBKEYS[num]}" ] && STICK=${USBKEYS[num]} done; } usbKeyChoose echo $STICK 
2
  • If you've choosed my anser for use, why did you not accept them? Commented Mar 17, 2014 at 9:15
  • @F.Hauri I did choose your answer now. I learned from both answers (yours and @mikeserv) , so thanks to both of you! Commented Mar 17, 2014 at 23:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.