I am working on making a simple python program to mount and unmount flash drives so that I don't have to do more than just look at a list and choose what I want to mount. Right now, I have a list of objects and properties for each device. What I want to know is which properties I should look at to tell if a device is a usb mass storage device. My first instinct is to look at 'Detachable', however I only have one device plugged in (my kindle) but I'm getting two detachable devices. The two properties that I'm noticing are different are that /dev/sdb has a blank 'IdLabel' and 'IdUsage'. This is the code that I have right now:
#!/usr/bin/python
import dbus
def get_devices():
bus = dbus.SystemBus()
ud_manager_obj = bus.get_object('org.freedesktop.UDisks',
'/org/freedesktop/UDisks')
ud_manager = dbus.Interface(ud_manager_obj, 'org.freedesktop.UDisks')
proplist = []
for device in ud_manager.EnumerateDevices():
device_obj = bus.get_object('org.freedesktop.UDisks', device)
device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
proplist.append(device_props.GetAll('org.freedesktop.UDisks.Device'))
for device_props in proplist:
print '----------'
print device_props['IdLabel']
print device_props['DeviceFile']
print device_props['IdUsage']
if device_props['DriveCanDetach']:
print 'Device is detachable'
else:
print 'Device is not detachable'
get_devices()
And the two outputs I'm talking about are:
Kindle
/dev/sdb1
filesystem
Device is detachable
----------
/dev/sdb
Device is detachable
Result of udisks --show-info /dev/sdb1
Showing information for /org/freedesktop/UDisks/devices/sdb1
native-path: /sys/devices/pci0000:00/0000:00:1c.3/0000:04:00.0/usb3/3-1/3
-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb/sdb1
device: 8:17
device-file: /dev/sdb1
presentation: /dev/sdb1
by-id: /dev/disk/by-id/usb-Kindle_Internal_Storage_90D42204345600JR
-0:0-part1
by-id: /dev/disk/by-uuid/386D-5422
by-path: /dev/disk/by-path/pci-0000:04:00.0-usb-0:1:1.0-scsi-0:0:0:0-
part1
detected at: Sat 04 Jan 2014 03:56:35 PM EST
system internal: 0
removable: 0
has media: 1 (detected at Sat 04 Jan 2014 03:56:35 PM EST)
detects change: 0
detection by polling: 0
detection inhibitable: 0
detection inhibited: 0
is read only: 0
is mounted: 0
mount paths:
mounted by uid: 0
presentation hide: 0
presentation nopolicy: 0
presentation name:
presentation icon: multimedia-player
automount hint:
size: 1432346624
block size: 512
job underway: no
usage: filesystem
type: vfat
version: FAT32
uuid: 386D-5422
label: Kindle
partition:
part of: /org/freedesktop/UDisks/devices/sdb
scheme: mbr
number: 1
type: 0x0b
flags:
offset: 8192
alignment offset: 0
size: 1432346624
label:
uuid:
Result of udisks --show-info /dev/sdb
Showing information for /org/freedesktop/UDisks/devices/sdb
native-path: /sys/devices/pci0000:00/0000:00:1c.3/0000:04:00.0/usb3/3-1/3
-1:1.0/host7/target7:0:0/7:0:0:0/block/sdb
device: 8:16
device-file: /dev/sdb
presentation: /dev/sdb
by-id: /dev/disk/by-id/usb-Kindle_Internal_Storage_90D42204345600JR
-0:0
by-path: /dev/disk/by-path/pci-0000:04:00.0-usb-0:1:1.0-scsi-0:0:0:0
detected at: Sat 04 Jan 2014 03:56:34 PM EST
system internal: 0
removable: 1
has media: 1 (detected at Sat 04 Jan 2014 03:56:34 PM EST)
detects change: 1
detection by polling: 1
detection inhibitable: 1
detection inhibited: 0
is read only: 0
is mounted: 0
mount paths:
mounted by uid: 0
presentation hide: 0
presentation nopolicy: 0
presentation name:
presentation icon: multimedia-player
automount hint:
size: 1432354816
block size: 512
job underway: no
usage:
type:
version:
uuid:
label:
partition table:
scheme: mbr
count: 1
drive:
vendor: Kindle
model: Internal Storage
revision: 0100
serial: 90D42204345600JR
WWN:
detachable: 1
can spindown: 0
rotational media: Yes, unknown rate
write-cache: unknown
ejectable: 0
adapter: Unknown
ports:
similar devices:
media:
compat:
interface: usb
if speed: 480000000 bits/s
ATA SMART: not available
So what I would like to know if checking that there is an IdLabel and IdUsage are enough to assume something is a USB mass storage device.
If you could go with UDisks2 DBus interface the answer would be quite simple :-) First of all, it seems that UDisks2 (and probably UDisks1, but I haven't it installed) handles only Mass Storage devices connected via USB, completely ignoring USB-connected MTP-devices and other kinds of USB devices such as printers and mice. Have a look:
Right now I have 6 USB devices connected:
alex@galene ~ $ /usr/sbin/lsusb | grep -v 'root hub' Bus 001 Device 004: ID 058f:6362 Alcor Micro Corp. Flash Card Reader/Writer Bus 001 Device 003: ID 09da:000a A4 Tech Co., Ltd Optical Mouse Opto 510D Bus 008 Device 090: ID 04e8:6860 Samsung Electronics Co., Ltd GT-I9100 Phone [Galaxy S II], GT-P7500 [Galaxy Tab 10.1] Bus 008 Device 075: ID 04b8:0007 Seiko Epson Corp. Printer Bus 009 Device 002: ID 058f:6387 Alcor Micro Corp. Flash Drive Bus 009 Device 088: ID 1058:1010 Western Digital Technologies, Inc. Elements External HDD
058f:6362 is an "all-in one" card reader w/ a SD-card currently plugged in. 058f:6387 and 1058:1010 are real USB Mass Storage devs, a flash and an external HDD respectively. 04e8:6860 is a Samsung Galaxy Note1 (an MTP-device) and the rest are the mouse and the printer.
Also I have an internal SATA drive.
Here's the current udisksctl status
output (as you may see Galaxy Note is missing):
MODEL REVISION SERIAL DEVICE -------------------------------------------------------------------------- Hitachi HDT725040VLA360 V5COA7EA VFM301R3196R5F sda Generic Flash Disk 8.07 8D0147DF sdb WDC WD1200BEVS-22RST0 04.01G04 WD-WXE108V72690 sdc Generic USB CF Reader 1.01 058F312D81B sde Generic USB SM Reader 1.02 058F312D81B sdf Generic USB MS Reader 1.03 058F312D81B sdg Generic USB SD Reader 1.00 058F312D81B sdd
To distinguish pluggable USB Mass storage devices from stationary drives one may check 'ConnectedBus' and ''Removable' properties. Please note that there's another property 'MediaRemovable' which corresponds to the physical media of the device. Here's the script which selects removable USB Mass Storage devices and prints their 'MediaRemovable' property
alex@galene ~ $ cat <<EOF | python - > import dbus > bus = dbus.SystemBus() > ud_manager_obj = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2') > om = dbus.Interface(ud_manager_obj, 'org.freedesktop.DBus.ObjectManager') > for k,v in om.GetManagedObjects().iteritems(): > drive_info = v.get('org.freedesktop.UDisks2.Drive', {}) > if drive_info.get('ConnectionBus') == 'usb' and drive_info.get('Removable'): > print("Device Path: %s, MediaRemovable: %s" % (k, drive_info['MediaRemovable'])) > block_devices = [''.join(chr(c) for c in device[dbus.String(u'org.freedesktop.UDisks2.Block')][dbus.String(u'PreferredDevice')] if chr(c) != '\x00' ) for device in om.GetManagerObjects().values() if dbus.String(u'org.freedesktop.UDisks2.Block') in device] > EOF Device Path: /org/freedesktop/UDisks2/drives/Generic_USB_SM_Reader_058F312D81B, MediaRemovable: 1 Device Path: /org/freedesktop/UDisks2/drives/Generic_Flash_Disk_8D0147DF, MediaRemovable: 1 Device Path: /org/freedesktop/UDisks2/drives/Generic_USB_SD_Reader_058F312D81B, MediaRemovable: 1 Device Path: /org/freedesktop/UDisks2/drives/WDC_WD1200BEVS_22RST0_WD_WXE108V72690, MediaRemovable: 0 Device Path: /org/freedesktop/UDisks2/drives/Generic_USB_CF_Reader_058F312D81B, MediaRemovable: 1 Device Path: /org/freedesktop/UDisks2/drives/Generic_USB_MS_Reader_058F312D81B, MediaRemovable: 1
Basically it solves the problem you're trying to solve. Rumors say that there're non-removable USB-connected storage devices but I haven't seen such.