How to identify SD-cards and flash sticks as being such?

Since using Raspberry Pis, I've found myself frequently burning its
various distros to SD-cards, and I also burn "live" Linux distros to flash
sticks quite often. So I've written a bash script to write image files to
/dev/sdb using dd.
However, since I use a number of machines, it's not entirely safe to
assume that the external flash device will be on /dev/sdb, so I want to
include a safety check to ensure that I don't trash an internal drive.
Since flash devices now have a storage size comparable to the hard drives
of not-so-old PCs, checking the size with fdisk doesn't help.
Anybody know a technique to check the type of device on a /dev/sdx node?
Reply to
Dave Farrance
Loading thread data ...
["Followup-To:" header set to comp.sys.raspberry-pi.] Dana Fri, 10 Oct 2014 13:17:49 +0100, Dave Farrance napis'o:
By device id? /dev/disk/by-id /dev/disk/by-uuid
Reply to
Nikolaj Lazic
Thanks, but that doesn't seem to identify flash cards and sticks.
It seems that the by-id directory provides variously named devices linked to the device id, but I've just checked a bunch of devices, and about the only thing that I can distinguish consistently is the difference between ATA and USB:
These are internal ATA drives: ata-OCZ-VERTEX4_OCZ-1K1F4KH856G4W673 ata-Hitachi_HTS543216L9A300_090822FB2200VCGL464A
These are USB-attached hard drives: usb-IBM-DBCA_-206480_222022840943-0:0 usb-FUJITSU_MHT2060AH_801344C26237-0:0 usb-StoreJet_Transcend_74AGW0BPT-0:0
These are SD-Card readers: usb-ChipsBnk_SD_MMCReader_110074973765-0:0 usb-Multi_Flash_Reader_058F0O1111B-0:0 usb-USB2.0_CARD-READER_0201202010201000-0:0 usb-Mass_Storage_Device_121220130416-0:0 usb-Generic-_Multi-Card_20071114173400000-0:0
These are flash sticks: usb-Generic_Flash_Disk_E41C63C0-0:0 usb-USBest_Technology_USB_Mass_Storage_Device_08102382493394-0:0 usb-USB_Flash_Disk_FB08102900097261-0:0
Reply to
Dave Farrance
["Followup-To:" header set to comp.sys.raspberry-pi.] Dana Fri, 10 Oct 2014 15:40:31 +0100, Dave Farrance napis'o:
Well... I thought that you KNOW what device you just plugged in... and I still think this should be enough. Ok... maybe it would be confusing if you plug in two identical devices. Maybe use a label and then look at /dev/disk/by-label Or... lsusb and then check what you think is a device you are going to stamp on in a few moments after dd starts. :)
Reply to
Nikolaj Lazic
If establishing that it's USB is the only test that I can make, then so be it; I can probably ensure that the only USB device plugged in is the one that I'm going to burn. I'm just thinking that some internal devices can be connected via USB motherboard-headers.
It would be safer if I could figure out a way to distinguish between multiple USB devices, pick the flash device, select the corresponding device id, and only then supply the name of that device as a prompt to the user to OK the burn.
Reply to
Dave Farrance
Individual device serial numbers? Only allow you script to operate on known device serial numbers.
--
Cheers 
Dave.
Reply to
Dave Liquorice
The /sys pseudo-filesystem could help you. It is a jumble of symlinks, and it is actually a peek into the internal data structures and linkages in the kernel I/O system.
A good starting point could be /sys/class/block.
--

Tauno Voipio
Reply to
Tauno Voipio
As far as USB is concerned, there's no difference between a USB stick (being a USB to flash memory converter/controller and a flash chip) and a memory card in a reader (being a USB to SD/whatever converter and a flash card). They're all simply mass storage devices. So there's no universal way to do it - the only way to tell is by the name ('reader', 'card', etc).
A hint might be that readers typically have multiple slots which appear as multiple empty devices, but that's not guaranteed.
Theo
Reply to
Theo Markettos
I was able to generate files to compare between sda (hard drive) and sdb (flash) using that pseudo-filesystem with this:
( cd /sys/class/block/sda/; find . -type f -exec sh -c 'echo -n {}=; cat {};' \; ) >sda.txt ( cd /sys/class/block/sdb/; find . -type f -exec sh -c 'echo -n {}=; cat {};' \; ) >sdb.txt
There are numeric differences between the two that indicate things like sector sizes but it'd be very difficult to parse with a script.
Reply to
Dave Farrance
I see. I'll have to settle for just checking if it's USB. I googled for ways to check and this will have to do:
[[ -n $(udevadm info /dev/sdb | grep ID_BUS=usb) ]] && echo yes it is usb
Reply to
Dave Farrance
Plug the device in and then have a look at the last few lines in /var/log/messages.
That will look like this:
# tail /var/log/messages Oct 10 21:01:00 pcict9 kernel: [6733354.032100] usb 5-8: SerialNumber: FBG1108231001392 Oct 10 21:01:00 pcict9 kernel: [6733354.032368] usb-storage 5-8:1.0: USB Mass Storage device detected Oct 10 21:01:00 pcict9 kernel: [6733354.032442] scsi18 : usb-storage 5-8:1.0 Oct 10 21:01:00 pcict9 mtp-probe: checking bus 5, device 13: "/sys/devices/pci0000:00/0000:00:1d.7/usb5/5-8" Oct 10 21:01:00 pcict9 mtp-probe: bus: 5, device: 13 was not an MTP device Oct 10 21:01:01 pcict9 kernel: [6733355.249199] scsi 18:0:0:0: Direct-Access USB Flash Disk 1100 PQ: 0 ANSI: 4 Oct 10 21:01:01 pcict9 kernel: [6733355.250169] sd 18:0:0:0: [sdd] 3915776 512-byte logical blocks: (2.00 GB/1.86 GiB) Oct 10 21:01:01 pcict9 kernel: [6733355.251316] sd 18:0:0:0: [sdd] Write Protect is off Oct 10 21:01:01 pcict9 kernel: [6733355.256939] sdd: sdd1 Oct 10 21:01:01 pcict9 kernel: [6733355.261073] sd 18:0:0:0: [sdd] Attached SCSI removable disk
This shows that the device I plugged in has got the device name /dev/sdd and that the device has a single partition /dev/sdd1.
Regards,
Kees.
--
Kees Theunissen.
Reply to
Kees Theunissen
Is there a way to see the time and date of the drive being mounted? Maybe you can add a check that the drive being written must have been mounted within the last x minutes? Or prompt the user with the info on the drive including the mounting time and let the user have the final say.
--

Rick
Reply to
rickman
Ok, thanks for the suggestions. I've settled on this method:
First check that the user is in the disk group (necessary for the authority to write to usb devices, on Debian/Ubuntu distros, at least).
Check the file has suffix .img, or .iso, or is a .gz containing a single file (like raspbmc) or a .zip containing a single file (like raspian).
Scan /dev/sdb, dev/sdc, etc until the first USB-connected device is found.
Get the "ID_Model" string of the SD adaptor, which is things like: "SD_MMCReader" "CARD-READER" "Flash_Reader" "Storage_Device" "Multi-Card" or for flash sticks, "Flash_Disk" or "USB_Mass_Storage_Device".
Prompt the user with the above info and ask if it's OK to continue.
pv needs to be installed to provide a nice progress bar and ETA etc, but the other commands (udevadm, unzip, funzip) are default on Ubuntu/Debian.
I've tested it and it seems to be fully functional:
#!/bin/bash # burn specified iso to usb flash (verifies that it IS on USB) fail() { echo Error: $*; exit 1; } [[ -z $(grep '\bdisk\b' < &1 | grep ID_BUS=usb) ]] && break done sd=$(udevadm info /dev/sd$n | grep 'ID_MODEL=' | sed 's/.*ID_MODEL=//') read -p "Burn $1 into \"$sd\" at /dev/sd$n [Yn]" yn [[ "$yn" == [nN]* ]] && exit 1 [[ "$1" == ?(*.zip|*.gz) ]] && fz=funzip || fz='tee' pv -tpreb "$1" | $fz | dd bs=1M oflag=dsync of="/dev/sd$n"
Reply to
Dave Farrance
Just check the last few lines of dmesg output.
Reply to
Bob Martin
When you use usbmount to detect the appearance of a pluggable USB device you won't have to guess the devicename it got, you get it handed over in an environment variable. You can write your own script to handle the insert/remove action, the default script will mount it but you can undo that and you can add extra scripts that will be performing actions that you want.
Reply to
Rob
Yes, Kees suggested this too. After thinking about it, I realize that scanning the whole message log for the last instance of the [sd?] string probably is a quite robust method.
dmesg | grep -o '\[sd.\]' | tail -1 | sed -e 's:\[:/dev/:' -e 's:\]::'
Reply to
Dave Farrance
Although you normally don't mount the device for programming. It probably is safer to assume that it's inserted just before running the script as others have suggested.
dmesg | grep -o '\[sd.\]' | tail -1 | sed -e 's:\[:/dev/:' -e 's:\]::'
Reply to
Dave Farrance
That is why I say you can undo that (you can both undo the actual mount and you can remove the entire mount action)
It depends on what you want to refer to as "safe". The usbmount package presents an event handler for the actual insert/remove event. No need to peek in logfiles and no problem when more than one device is inserted or removed.
I wrote a simple script to play .mp3 files on a stick that is inserted, and it works like a breeze. Just added another script in the usbmount.d directory.
Reply to
Rob
Would it clash with HAL? I'd like that working as normal.
Reply to
Dave Farrance
I think HAL can do the same thing. usbmount is not tied to a desktop environment, it works fine on a system with only textmode.
Reply to
Rob

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.