summaryrefslogtreecommitdiff
path: root/src/udiskslinuxdrive.c
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2012-01-10 16:01:35 -0500
committerDavid Zeuthen <davidz@redhat.com>2012-01-10 16:01:35 -0500
commit796f99ef8bde647131006f38164aa456a2d21e41 (patch)
tree53a17591483e0f787285a8561569677efc34511a /src/udiskslinuxdrive.c
parentbc07dfeb9d5f87ba91b0bdaecfd1530a552362c9 (diff)
Fix up how Drive:SortKey and Drive:TimeMediaDetected is calculated
Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'src/udiskslinuxdrive.c')
-rw-r--r--src/udiskslinuxdrive.c135
1 files changed, 107 insertions, 28 deletions
diff --git a/src/udiskslinuxdrive.c b/src/udiskslinuxdrive.c
index cdfd281..6f9f382 100644
--- a/src/udiskslinuxdrive.c
+++ b/src/udiskslinuxdrive.c
@@ -63,6 +63,7 @@ struct _UDisksLinuxDrive
gint64 time_detected;
gint64 time_media_detected;
+ gchar *sort_key;
};
struct _UDisksLinuxDriveClass
@@ -78,6 +79,17 @@ G_DEFINE_TYPE_WITH_CODE (UDisksLinuxDrive, udisks_linux_drive, UDISKS_TYPE_DRIVE
/* ---------------------------------------------------------------------------------------------------- */
static void
+udisks_linux_drive_finalize (GObject *object)
+{
+ UDisksLinuxDrive *drive = UDISKS_LINUX_DRIVE (object);
+
+ g_free (drive->sort_key);
+
+ if (G_OBJECT_CLASS (udisks_linux_drive_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (udisks_linux_drive_parent_class)->finalize (object);
+}
+
+static void
udisks_linux_drive_init (UDisksLinuxDrive *drive)
{
g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (drive),
@@ -87,6 +99,10 @@ udisks_linux_drive_init (UDisksLinuxDrive *drive)
static void
udisks_linux_drive_class_init (UDisksLinuxDriveClass *klass)
{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = udisks_linux_drive_finalize;
}
/**
@@ -327,6 +343,61 @@ set_connection_bus (UDisksDrive *iface,
;
}
+static void
+set_media_time_detected (UDisksLinuxDrive *drive,
+ GUdevDevice *device,
+ gboolean is_pc_floppy_drive,
+ gboolean coldplug)
+{
+ UDisksDrive *iface = UDISKS_DRIVE (drive);
+ gint64 now;
+
+ now = g_get_real_time ();
+
+ /* First, initialize time_detected */
+ if (drive->time_detected == 0)
+ {
+ if (coldplug)
+ {
+ drive->time_detected = now - g_udev_device_get_usec_since_initialized (device);
+ }
+ else
+ {
+ drive->time_detected = now;
+ }
+ }
+
+ if (!g_udev_device_get_sysfs_attr_as_boolean (device, "removable") || is_pc_floppy_drive)
+ {
+ drive->time_media_detected = drive->time_detected;
+ }
+ else
+ {
+ if (!udisks_drive_get_media_available (iface))
+ {
+ /* no media currently available */
+ drive->time_media_detected = 0;
+ }
+ else
+ {
+ /* media currently available */
+ if (drive->time_media_detected == 0)
+ {
+ if (coldplug)
+ {
+ drive->time_media_detected = drive->time_detected;
+ }
+ else
+ {
+ drive->time_media_detected = now;
+ }
+ }
+ }
+ }
+
+ udisks_drive_set_time_detected (iface, drive->time_detected);
+ udisks_drive_set_time_media_detected (iface, drive->time_media_detected);
+}
/**
* udisks_linux_drive_update:
@@ -341,17 +412,26 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive,
{
UDisksDrive *iface = UDISKS_DRIVE (drive);
GUdevDevice *device;
- gchar *sort_key;
guint64 size;
gboolean media_available;
gboolean media_change_detected;
gboolean is_pc_floppy_drive = FALSE;
gboolean removable_hint = FALSE;
+ UDisksDaemon *daemon;
+ UDisksLinuxProvider *provider;
+ gboolean coldplug = FALSE;
device = udisks_linux_drive_object_get_device (object, TRUE /* get_hw */);
if (device == NULL)
goto out;
+ if (object != NULL)
+ {
+ daemon = udisks_linux_drive_object_get_daemon (object);
+ provider = udisks_daemon_get_linux_provider (daemon);
+ coldplug = udisks_linux_provider_get_coldplug (provider);
+ }
+
if (g_udev_device_get_property_as_boolean (device, "ID_DRIVE_FLOPPY") ||
g_str_has_prefix (g_udev_device_get_name (device), "fd"))
is_pc_floppy_drive = TRUE;
@@ -509,36 +589,35 @@ udisks_linux_drive_update (UDisksLinuxDrive *drive,
removable_hint = TRUE;
udisks_drive_set_removable (iface, removable_hint);
- /* need to use this lame hack until libudev's get_usec_since_initialized() works
- * for devices received via the netlink socket
- */
- GUdevClient *client;
- GUdevDevice *ns_device;
- client = g_udev_client_new (NULL);
- ns_device = g_udev_client_query_by_sysfs_path (client, g_udev_device_get_sysfs_path (device));
+ set_media_time_detected (drive, device, is_pc_floppy_drive, coldplug);
- if (drive->time_detected == 0)
- drive->time_detected = g_get_real_time () - g_udev_device_get_usec_since_initialized (ns_device);
- if (!g_udev_device_get_sysfs_attr_as_boolean (device, "removable") || is_pc_floppy_drive)
- {
- drive->time_media_detected = drive->time_detected;
- }
- else
+ /* calculate sort-key */
+ if (drive->sort_key == NULL)
{
- if (!media_available)
- drive->time_media_detected = 0;
- else if (drive->time_media_detected == 0)
- drive->time_media_detected = g_get_real_time ();
+ if (coldplug)
+ {
+ const gchar *device_name;
+ /* TODO: adjust device_name for better sort order (so e.g. sdaa comes after sdz) */
+ device_name = g_udev_device_get_name (device);
+ if (udisks_drive_get_media_removable (iface))
+ {
+ /* make sure sr* devices comes before sd* devices */
+ if (g_str_has_prefix (device_name, "sr"))
+ drive->sort_key = g_strdup_printf ("00coldplug/10removable/%s", device_name);
+ else
+ drive->sort_key = g_strdup_printf ("00coldplug/11removable/%s", device_name);
+ }
+ else
+ {
+ drive->sort_key = g_strdup_printf ("00coldplug/00fixed/%s", device_name);
+ }
+ }
+ else
+ {
+ drive->sort_key = g_strdup_printf ("01hotplug/%" G_GINT64_FORMAT, drive->time_detected);
+ }
+ udisks_drive_set_sort_key (iface, drive->sort_key);
}
- g_object_unref (ns_device);
- g_object_unref (client);
-
- udisks_drive_set_time_detected (iface, drive->time_detected);
- udisks_drive_set_time_media_detected (iface, drive->time_media_detected);
-
- sort_key = g_strdup_printf ("%" G_GINT64_FORMAT, drive->time_detected);
- udisks_drive_set_sort_key (iface, sort_key);
- g_free (sort_key);
out:
if (device != NULL)