summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Lane <iainl@gnome.org>2019-02-08 16:45:49 +0000
committerIain Lane <iainl@gnome.org>2019-02-08 17:25:39 +0000
commit09ec2c19e0f4a5cbb6fe15a3b6bfabda224a73f8 (patch)
tree546032c079ab1abcbdf5ca615dad7b2126a280bc
parent529361870afe4b9da682043a906cf7e47194ec52 (diff)
downloadgnome-control-center-wip/info-udisks2-mdadm.tar.gz
info: Read MDADM arrays as their size, not the size of their underlying driveswip/info-udisks2-mdadm
These are exposed to the user as the size of the array. If we find such an array, read its size, record the drives and don't count their sizes individually. This is slightly fiddly for a couple of reasons: - There's no API exposed in udisks2 to get directly from the UDisksMDRaid object to the underlying UDisksDrives, so we have to construct proxies manually. - We might see the drives first, before we encounter the RAID array. So we keep a reference to the UDisks objects when counting disk sizes and then use this to later on subtract the size if we later find out a drive is actually part of an array.
-rw-r--r--panels/info/cc-info-overview-panel.c91
1 files changed, 86 insertions, 5 deletions
diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c
index 6f9707195..2c80ef923 100644
--- a/panels/info/cc-info-overview-panel.c
+++ b/panels/info/cc-info-overview-panel.c
@@ -501,24 +501,105 @@ get_primary_disc_info (CcInfoOverviewPanel *self)
manager = udisks_client_get_object_manager (priv->client);
objects = g_dbus_object_manager_get_objects (manager);
- added_drives = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+ added_drives = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
for (l = objects; l != NULL; l = l->next)
{
- UDisksDrive *drive;
- drive = udisks_object_peek_drive (UDISKS_OBJECT (l->data));
+ g_autoptr(UDisksDrive) drive = NULL;
+ g_autoptr(UDisksMDRaid) mdraid = NULL;
+ const gchar *object_path;
+
+ drive = udisks_object_get_drive (UDISKS_OBJECT (l->data));
+ mdraid = udisks_object_get_mdraid (UDISKS_OBJECT (l->data));
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (l->data));
+
+ /* Count MDRAID devices, and ignore their underlying drives */
+ if (mdraid != NULL &&
+ !g_hash_table_contains (added_drives, object_path))
+ {
+ GVariant *active_devices;
+ GVariantIter iter;
+ GVariant *child;
+
+ total_size += udisks_mdraid_get_size (mdraid);
+ g_hash_table_insert (added_drives,
+ (gpointer) g_dbus_object_get_object_path (G_DBUS_OBJECT (l->data)),
+ g_object_ref (mdraid));
+
+ /* Don't count the underlying devices again */
+ active_devices = udisks_mdraid_get_active_devices (mdraid);
+
+ g_variant_iter_init (&iter, active_devices);
+
+ while ((child = g_variant_iter_next_value (&iter)))
+ {
+ g_autoptr(UDisksBlock) block_device = NULL;
+ g_autoptr(GError) error = NULL;
+ GObject *existing_device;
+ const char *child_object_path, *drive_object_path;
+ GDBusObjectManagerClient *manager_client;
+
+ manager_client = G_DBUS_OBJECT_MANAGER_CLIENT (manager);
+
+ g_variant_get (child, "(&oiasta{sv})", &child_object_path, NULL, NULL, NULL, NULL, NULL);
+ block_device = udisks_block_proxy_new_sync (g_dbus_object_manager_client_get_connection (manager_client),
+ G_DBUS_PROXY_FLAGS_NONE,
+ g_dbus_object_manager_client_get_name (manager_client),
+ child_object_path,
+ NULL,
+ &error);
+
+ if (block_device == NULL)
+ {
+ g_critical ("Couldn't get proxy for block device '%s': %s", child_object_path, error->message);
+ continue;
+ }
+
+ drive_object_path = udisks_block_get_drive (block_device);
+
+ drive = udisks_drive_proxy_new_sync (g_dbus_object_manager_client_get_connection (manager_client),
+ G_DBUS_PROXY_FLAGS_NONE,
+ g_dbus_object_manager_client_get_name (manager_client),
+ drive_object_path,
+ NULL,
+ &error);
+
+ if (drive == NULL)
+ {
+ g_critical ("Couldn't get proxy for drive device '%s': %s", drive_object_path, error->message);
+ continue;
+ }
+
+ g_hash_table_insert (added_drives, (gpointer) drive_object_path, g_object_ref (drive));
+
+ /* Maybe we processed the underlying drive first; unprocess it */
+ existing_device = G_OBJECT (g_hash_table_lookup (added_drives,
+ drive_object_path));
+ if (existing_device != NULL)
+ {
+ guint64 size;
+
+ /* doing this via g_object_get() works for both UDisksMDRaid
+ * and UDisksDrive */
+ g_object_get (existing_device, "size", &size, NULL);
+ total_size -= size;
+ }
+ }
+
+ continue;
+ }
/* Skip removable devices */
if (drive == NULL ||
udisks_drive_get_removable (drive) ||
udisks_drive_get_ejectable (drive) ||
- g_hash_table_contains (added_drives, udisks_drive_get_id (drive)))
+ g_hash_table_contains (added_drives, object_path))
{
continue;
}
total_size += udisks_drive_get_size (drive);
- g_hash_table_add (added_drives, (gpointer) udisks_drive_get_id (drive));
+ g_hash_table_insert (added_drives, (gpointer) object_path, g_object_ref (drive));
}
if (total_size > 0)