[gvfs] gdu: Use DriveDetach() method to power down hard disk enclosures
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Subject: [gvfs] gdu: Use DriveDetach() method to power down hard disk enclosures
- Date: Mon, 8 Jun 2009 20:30:22 -0400 (EDT)
commit 27b14622b7fcc228ddd617ebd723751ccd8dadaa
Author: David Zeuthen <davidz redhat com>
Date: Mon Jun 8 20:19:02 2009 -0400
gdu: Use DriveDetach() method to power down hard disk enclosures
See this commit
http://cgit.freedesktop.org/DeviceKit/DeviceKit-disks/commit/?id=5b7350df8b63cf4178a2fe69ee740b5222130421
for details about DriveDetach(). In a nutshell it allows us to offer
an Eject() option on USB enclosures. Currently we don't do this since
such devices don't have removable media.
With this change, we'll set can_eject to TRUE if the device is
detachable. If the device is both detachable and removable, we prefer
Eject over Detach() when doing the deed (e.g. consider a USB optical
drive; it is both detachable and removable).
To sum up, the net result of this change is that users of Nautilus
will get an Eject option and the eject icon in Nautilus' sidebar. Upon
the user pressing Eject in the UI we'll unmount all partitions as
usual. Then if the device is not removable, we'll invoke
DriveDetach(). That will make DeviceKit-disks send these two SCSI
commands
SYNCHRONIZE CACHE
STOP
and then we'll unbind e.g. the usb-storage driver from the USB
interface of the USB device. The net result is that the device appears
to be disconnected (ie. we get remove uevents for e.g. /dev/sdb[0..N]
and /dev/sdb) and also that the device powers down.
Right now DeviceKit-disks only supports DriveDetach() for USB devices
but should it gain support for doing the same thing for Firewire,
eSATA, whatever then we'll get that support for free too.
---
monitor/gdu/ggdudrive.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/monitor/gdu/ggdudrive.c b/monitor/gdu/ggdudrive.c
index c2c8b76..8e04104 100644
--- a/monitor/gdu/ggdudrive.c
+++ b/monitor/gdu/ggdudrive.c
@@ -169,7 +169,7 @@ update_drive (GGduDrive *drive)
*
* See http://bugzilla.gnome.org/show_bug.cgi?id=576587 for why we want this.
*/
- drive->can_eject = gdu_device_drive_get_is_media_ejectable (device) || gdu_device_drive_get_requires_eject (device) || gdu_device_is_removable (device);
+ drive->can_eject = gdu_device_drive_get_is_media_ejectable (device) || gdu_device_drive_get_requires_eject (device) || gdu_device_is_removable (device) || gdu_device_drive_get_can_detach (device);
drive->is_media_check_automatic = gdu_device_is_media_change_detected (device);
drive->can_poll_for_media = TRUE;
}
@@ -352,6 +352,23 @@ g_gdu_drive_can_poll_for_media (GDrive *_drive)
}
static void
+detach_cb (GduDevice *device,
+ GError *error,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+ if (error != NULL)
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static void
eject_cb (GduDevice *device,
GError *error,
gpointer user_data)
@@ -360,9 +377,6 @@ eject_cb (GduDevice *device,
if (error != NULL)
{
- /* We could handle PolicyKit integration here but this action is allowed by default
- * and this won't be needed when porting to PolicyKit 1.0 anyway
- */
g_simple_async_result_set_from_error (simple, error);
g_error_free (error);
}
@@ -401,7 +415,27 @@ g_gdu_drive_eject_do (GDrive *_drive,
user_data,
NULL);
- gdu_device_op_drive_eject (device, eject_cb, simple);
+ /* Note that we also offer the Eject option for non-removable
+ * devices (see update_drive() above) that are detachable so the
+ * device may actually not be removable when we get here...
+ *
+ * However, keep in mind that a device may be both removable and
+ * detachable (e.g. a usb optical drive)..
+ *
+ * Now, consider what would happen if we detached a USB optical
+ * drive? The device would power down without actually ejecting
+ * the media... and it would require a power-cycle or a replug
+ * to use it for other media. Therefore, never detach devices
+ * with removable media, only eject them.
+ */
+ if (gdu_device_drive_get_can_detach (device) && !gdu_device_is_removable (device))
+ {
+ gdu_device_op_drive_detach (device, detach_cb, simple);
+ }
+ else
+ {
+ gdu_device_op_drive_eject (device, eject_cb, simple);
+ }
g_object_unref (device);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]