Under the impression of loosing some really important data because of a damaged partition table on a USB flash drive I am developing a backup strategy for my system. I know myself and so I decided that I need to automate this. While trying to figure out how one can run a script as soon as a specific drive is mounted, I came across DeviceKit. It’s the planned replacement of HAL and is used in Ubuntu Karmic. Udev is not an option for me, because I don’t want to mess around with mounting myself (and I hate running stuff as root…). So here is what I found out about using DBus and DeviceKit in Python:
import dbus
bus = dbus.SystemBus()
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
#enumerates all devices
print iface.EnumerateDevices()
#gets the device kit path of a specific device
path = iface.FindDeviceByDeviceFile("/dev/sdc1")
#= "/org/freedesktop/DeviceKit/Disks/devices/sdc"
#gets an object representing the device specified by the path
device = bus.get_object("org.freedesktop.DeviceKit.Disks", path)
#prints some XML that shows you the available methods, signals and properties
print device.Introspect()
#gets a proxy for getting properties
device_prop = dbus.Interface(device, "org.freedesktop.DBus.Properties")
#you need to specify an interface (properties could be ambiguous)
print device_prop.Get("org.freedesktop.DeviceKit.Disks.Device", "device-mount-paths")
#gets a proxy you can call methods on
device_iface = dbus.Interface(device, "org.freedesktop.DeviceKit.Disks.Device")
#unmounts the partition
device_iface.FilesystemUnmount(dbus.Array([], 's'))
The DBus API of DeviceKit is documented here. Now we want to be notified when a drive is mounted:
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
def device_added_callback(device):
print 'Device %s was added' % (device)
def device_changed_callback(device):
print 'Device %s was changed' % (device)
#must be done before connecting to DBus
DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
proxy = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
iface = dbus.Interface(proxy, "org.freedesktop.DeviceKit.Disks")
#addes two signal listeners
iface.connect_to_signal('DeviceAdded', device_added_callback)
iface.connect_to_signal('DeviceChanged', device_changed_callback)
#start the main loop
mainloop = gobject.MainLoop()
mainloop.run()
A typical output when a flash drive is plugged in looks like this:
Device /org/freedesktop/DeviceKit/Disks/devices/sdc was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was added
Device /org/freedesktop/DeviceKit/Disks/devices/sdc1 was changed
With this knowledge I’m currently working on a little python script that runs in background and executes a shell script when a file system is mounted. I’ll post it, when it’s finished :-)