udisks_drive_set_time_media_detected (iface, drive->time_media_detected);
}
+static gchar *
+append_fixedup_sd (const gchar *prefix,
+ const gchar *device_name)
+{
+ guint num_alphas, n;
+ GString *str;
+
+ g_return_val_if_fail (g_str_has_prefix (device_name, "sd"), NULL);
+
+ /* make sure sdaa comes after e.g. sdz by inserting up to 5 '_' characters
+ * between sd and a in sda...
+ */
+ for (num_alphas = 0; g_ascii_isalpha (device_name[num_alphas + 2]); num_alphas++)
+ ;
+ str = g_string_new (prefix);
+ g_string_append (str, "sd");
+ for (n = 0; n < 5 - num_alphas; n++)
+ g_string_append_c (str, '_');
+
+ g_string_append (str, device_name + 2);
+
+ return g_string_free (str, FALSE);
+}
+
/**
* udisks_linux_drive_update:
* @drive: A #UDisksLinuxDrive.
{
/* make sure fd* BEFORE sr* BEFORE sd* */
if (g_str_has_prefix (device_name, "fd"))
- drive->sort_key = g_strdup_printf ("00coldplug/10removable/%s", device_name);
+ {
+ drive->sort_key = g_strdup_printf ("00coldplug/10removable/%s", device_name);
+ }
else if (g_str_has_prefix (device_name, "sr"))
- drive->sort_key = g_strdup_printf ("00coldplug/11removable/%s", device_name);
+ {
+ drive->sort_key = g_strdup_printf ("00coldplug/11removable/%s", device_name);
+ }
+ else if (g_str_has_prefix (device_name, "sd"))
+ {
+ drive->sort_key = append_fixedup_sd ("00coldplug/12removable/", device_name);
+ }
else
- drive->sort_key = g_strdup_printf ("00coldplug/12removable/%s", device_name);
+ {
+ drive->sort_key = g_strdup_printf ("00coldplug/12removable/%s", device_name);
+ }
}
else
{
- drive->sort_key = g_strdup_printf ("00coldplug/00fixed/%s", device_name);
+ if (g_str_has_prefix (device_name, "sd"))
+ drive->sort_key = append_fixedup_sd ("00coldplug/00fixed/", device_name);
+ else
+ drive->sort_key = g_strdup_printf ("00coldplug/00fixed/%s", device_name);
}
}
else
provider);
}
+static guint
+count_alphas (const gchar *str)
+{
+ guint n = 0;
+ while (g_ascii_isalpha (str[n]))
+ n++;
+ return n;
+}
+
+static gint
+device_name_cmp (const gchar *a,
+ const gchar *b)
+{
+ /* Ensures that sda comes before sdz%d and sdz%d comes before sdaa%d */
+ if (g_str_has_prefix (a, "sd") && g_str_has_prefix (b, "sd"))
+ {
+ gint la = count_alphas (a);
+ gint lb = count_alphas (b);
+ if (la != lb)
+ return la - lb;
+ else
+ return g_strcmp0 (a, b);
+ }
+ else
+ {
+ return g_strcmp0 (a, b);
+ }
+}
+
+static gint
+udev_device_name_cmp (GUdevDevice *a,
+ GUdevDevice *b)
+{
+ return device_name_cmp (g_udev_device_get_name (a), g_udev_device_get_name (b));
+}
+
static void
udisks_linux_provider_start (UDisksProvider *_provider)
{
NULL);
devices = g_udev_client_query_by_subsystem (provider->gudev_client, "block");
+ /* make sure we process sda before sdz and sdz before sdaa */
+ devices = g_list_sort (devices, (GCompareFunc) udev_device_name_cmp);
for (l = devices; l != NULL; l = l->next)
udisks_linux_provider_handle_uevent (provider, "add", G_UDEV_DEVICE (l->data));
g_list_foreach (devices, (GFunc) g_object_unref, NULL);