neil / rpms / udisks2

Forked from rpms/udisks2 a year ago
Clone
980768
From 5bcb348b17935328a2344d811ddba9847ab3c846 Mon Sep 17 00:00:00 2001
980768
From: Vojtech Trefny <vtrefny@redhat.com>
980768
Date: Mon, 16 Oct 2017 12:33:14 +0200
980768
Subject: [PATCH 1/5] Move some useful mdraid functions to a helper file
980768
980768
Related: rhbz#1400056
980768
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
980768
---
980768
 src/Makefile.am                |   1 +
980768
 src/udiskslinuxmdraid.c        |  83 ++------------------------------
980768
 src/udiskslinuxmdraidhelpers.c | 104 +++++++++++++++++++++++++++++++++++++++++
980768
 src/udiskslinuxmdraidhelpers.h |  41 ++++++++++++++++
980768
 4 files changed, 149 insertions(+), 80 deletions(-)
980768
 create mode 100644 src/udiskslinuxmdraidhelpers.c
980768
 create mode 100644 src/udiskslinuxmdraidhelpers.h
980768
980768
diff --git a/src/Makefile.am b/src/Makefile.am
980768
index 396ab4e..9cca8cd 100644
980768
--- a/src/Makefile.am
980768
+++ b/src/Makefile.am
980768
@@ -66,6 +66,7 @@ libudisks_daemon_la_SOURCES =                                                  \
980768
 	udiskslinuxdrive.h             udiskslinuxdrive.c                      \
980768
 	udiskslinuxdriveata.h          udiskslinuxdriveata.c                   \
980768
 	udiskslinuxmdraidobject.h      udiskslinuxmdraidobject.c               \
980768
+	udiskslinuxmdraidhelpers.h     udiskslinuxmdraidhelpers.c              \
980768
 	udiskslinuxmdraid.h            udiskslinuxmdraid.c                     \
980768
 	udiskslinuxmanager.h           udiskslinuxmanager.c                    \
980768
 	udiskslinuxfsinfo.h            udiskslinuxfsinfo.c                     \
980768
diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c
980768
index 9bf6ae9..2dcf0ff 100644
980768
--- a/src/udiskslinuxmdraid.c
980768
+++ b/src/udiskslinuxmdraid.c
980768
@@ -38,6 +38,7 @@
980768
 #include "udiskslinuxprovider.h"
980768
 #include "udiskslinuxmdraidobject.h"
980768
 #include "udiskslinuxmdraid.h"
980768
+#include "udiskslinuxmdraidhelpers.h"
980768
 #include "udiskslinuxblockobject.h"
980768
 #include "udisksdaemon.h"
980768
 #include "udisksstate.h"
980768
@@ -128,68 +129,6 @@ udisks_linux_mdraid_new (void)
980768
 
980768
 /* ---------------------------------------------------------------------------------------------------- */
980768
 
980768
-static gchar *
980768
-read_sysfs_attr (GUdevDevice *device,
980768
-                 const gchar *attr)
980768
-{
980768
-  gchar *ret = NULL;
980768
-  gchar *path = NULL;
980768
-  GError *error = NULL;
980768
-
980768
-  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
980768
-
980768
-  path = g_strdup_printf ("%s/%s", g_udev_device_get_sysfs_path (device), attr);
980768
-  if (!g_file_get_contents (path, &ret, NULL /* size */, &error))
980768
-    {
980768
-      udisks_warning ("Error reading sysfs attr `%s': %s (%s, %d)",
980768
-                      path, error->message, g_quark_to_string (error->domain), error->code);
980768
-      g_clear_error (&error);
980768
-      goto out;
980768
-    }
980768
-
980768
- out:
980768
-  g_free (path);
980768
-  return ret;
980768
-}
980768
-
980768
-static gint
980768
-read_sysfs_attr_as_int (GUdevDevice *device,
980768
-                        const gchar *attr)
980768
-{
980768
-  gint ret = 0;
980768
-  gchar *str = NULL;
980768
-
980768
-  str = read_sysfs_attr (device, attr);
980768
-  if (str == NULL)
980768
-    goto out;
980768
-
980768
-  ret = atoi (str);
980768
-  g_free (str);
980768
-
980768
- out:
980768
-  return ret;
980768
-}
980768
-
980768
-static guint64
980768
-read_sysfs_attr_as_uint64 (GUdevDevice *device,
980768
-                           const gchar *attr)
980768
-{
980768
-  guint64 ret = 0;
980768
-  gchar *str = NULL;
980768
-
980768
-  str = read_sysfs_attr (device, attr);
980768
-  if (str == NULL)
980768
-    goto out;
980768
-
980768
-  ret = atoll (str);
980768
-  g_free (str);
980768
-
980768
- out:
980768
-  return ret;
980768
-}
980768
-
980768
-/* ---------------------------------------------------------------------------------------------------- */
980768
-
980768
 static gboolean
980768
 on_polling_timout (gpointer user_data)
980768
 {
980768
@@ -306,8 +245,6 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
   guint64 sync_remaining_time = 0;
980768
   GVariantBuilder builder;
980768
   UDisksDaemon *daemon = NULL;
980768
-  gboolean has_redundancy = FALSE;
980768
-  gboolean has_stripes = FALSE;
980768
   UDisksBaseJob *job = NULL;
980768
 
980768
   daemon = udisks_linux_mdraid_object_get_daemon (object);
980768
@@ -377,23 +314,9 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
 
980768
   udisks_mdraid_set_running (iface, raid_device != NULL);
980768
 
980768
-  if (g_strcmp0 (level, "raid1") == 0 ||
980768
-      g_strcmp0 (level, "raid4") == 0 ||
980768
-      g_strcmp0 (level, "raid5") == 0 ||
980768
-      g_strcmp0 (level, "raid6") == 0 ||
980768
-      g_strcmp0 (level, "raid10") == 0)
980768
-    has_redundancy = TRUE;
980768
-
980768
-  if (g_strcmp0 (level, "raid0") == 0 ||
980768
-      g_strcmp0 (level, "raid4") == 0 ||
980768
-      g_strcmp0 (level, "raid5") == 0 ||
980768
-      g_strcmp0 (level, "raid6") == 0 ||
980768
-      g_strcmp0 (level, "raid10") == 0)
980768
-    has_stripes = TRUE;
980768
-
980768
   if (raid_device != NULL)
980768
     {
980768
-      if (has_redundancy)
980768
+      if (mdraid_has_redundancy (level))
980768
         {
980768
           /* Can't use GUdevDevice methods as they cache the result and these variables vary */
980768
           degraded = read_sysfs_attr_as_int (raid_device->udev_device, "md/degraded");
980768
@@ -408,7 +331,7 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
             g_strstrip (bitmap_location);
980768
         }
980768
 
980768
-      if (has_stripes)
980768
+      if (mdraid_has_stripes (level))
980768
         {
980768
           chunk_size = read_sysfs_attr_as_uint64 (raid_device->udev_device, "md/chunk_size");
980768
         }
980768
diff --git a/src/udiskslinuxmdraidhelpers.c b/src/udiskslinuxmdraidhelpers.c
980768
new file mode 100644
980768
index 0000000..dafdddf
980768
--- /dev/null
980768
+++ b/src/udiskslinuxmdraidhelpers.c
980768
@@ -0,0 +1,104 @@
980768
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
980768
+ *
980768
+ * Copyright (C) 2017 Red Hat, Inc.
980768
+ *
980768
+ * This program is free software; you can redistribute it and/or modify
980768
+ * it under the terms of the GNU General Public License as published by
980768
+ * the Free Software Foundation; either version 2 of the License, or
980768
+ * (at your option) any later version.
980768
+ *
980768
+ * This program is distributed in the hope that it will be useful,
980768
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
980768
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
980768
+ * GNU General Public License for more details.
980768
+ *
980768
+ * You should have received a copy of the GNU General Public License
980768
+ * along with this program; if not, write to the Free Software
980768
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
980768
+ *
980768
+ * Author: Vojtech Trefny <vtrefny@redhat.com>
980768
+ *
980768
+ */
980768
+
980768
+#include <glib.h>
980768
+#include <gudev/gudev.h>
980768
+#include <stdlib.h>
980768
+
980768
+#include "udiskslinuxmdraidhelpers.h"
980768
+#include "udiskslogging.h"
980768
+
980768
+gboolean
980768
+mdraid_has_redundancy (const gchar *raid_level)
980768
+{
980768
+  return raid_level != NULL &&
980768
+         g_str_has_prefix (raid_level, "raid") &&
980768
+         g_strcmp0 (raid_level, "raid0") != 0;
980768
+}
980768
+
980768
+gboolean
980768
+mdraid_has_stripes (const gchar *raid_level)
980768
+{
980768
+  return raid_level != NULL &&
980768
+         g_str_has_prefix (raid_level, "raid") &&
980768
+         g_strcmp0 (raid_level, "raid1") != 0;
980768
+}
980768
+
980768
+gchar *
980768
+read_sysfs_attr (GUdevDevice *device,
980768
+                 const gchar *attr)
980768
+{
980768
+  gchar *ret = NULL;
980768
+  gchar *path = NULL;
980768
+  GError *error = NULL;
980768
+
980768
+  g_return_val_if_fail (G_UDEV_IS_DEVICE (device), NULL);
980768
+
980768
+  path = g_strdup_printf ("%s/%s", g_udev_device_get_sysfs_path (device), attr);
980768
+  if (!g_file_get_contents (path, &ret, NULL /* size */, &error))
980768
+    {
980768
+      udisks_warning ("Error reading sysfs attr `%s': %s (%s, %d)",
980768
+                      path, error->message, g_quark_to_string (error->domain), error->code);
980768
+      g_clear_error (&error);
980768
+      goto out;
980768
+    }
980768
+
980768
+ out:
980768
+  g_free (path);
980768
+  return ret;
980768
+}
980768
+
980768
+gint
980768
+read_sysfs_attr_as_int (GUdevDevice *device,
980768
+                        const gchar *attr)
980768
+{
980768
+  gint ret = 0;
980768
+  gchar *str = NULL;
980768
+
980768
+  str = read_sysfs_attr (device, attr);
980768
+  if (str == NULL)
980768
+    goto out;
980768
+
980768
+  ret = atoi (str);
980768
+  g_free (str);
980768
+
980768
+ out:
980768
+  return ret;
980768
+}
980768
+
980768
+guint64
980768
+read_sysfs_attr_as_uint64 (GUdevDevice *device,
980768
+                           const gchar *attr)
980768
+{
980768
+  guint64 ret = 0;
980768
+  gchar *str = NULL;
980768
+
980768
+  str = read_sysfs_attr (device, attr);
980768
+  if (str == NULL)
980768
+    goto out;
980768
+
980768
+  ret = atoll (str);
980768
+  g_free (str);
980768
+
980768
+ out:
980768
+  return ret;
980768
+}
980768
diff --git a/src/udiskslinuxmdraidhelpers.h b/src/udiskslinuxmdraidhelpers.h
980768
new file mode 100644
980768
index 0000000..6d2b714
980768
--- /dev/null
980768
+++ b/src/udiskslinuxmdraidhelpers.h
980768
@@ -0,0 +1,41 @@
980768
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
980768
+ *
980768
+ * Copyright (C) 2017 Red Hat, Inc.
980768
+ *
980768
+ * This program is free software; you can redistribute it and/or modify
980768
+ * it under the terms of the GNU General Public License as published by
980768
+ * the Free Software Foundation; either version 2 of the License, or
980768
+ * (at your option) any later version.
980768
+ *
980768
+ * This program is distributed in the hope that it will be useful,
980768
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
980768
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
980768
+ * GNU General Public License for more details.
980768
+ *
980768
+ * You should have received a copy of the GNU General Public License
980768
+ * along with this program; if not, write to the Free Software
980768
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
980768
+ *
980768
+ * Author: Vojtech Trefny <vtrefny@redhat.com>
980768
+ *
980768
+ */
980768
+
980768
+#ifndef __UDISKS_LINUX_MDRAID_HELPERS_H__
980768
+#define __UDISKS_LINUX_MDRAID_HEPLERS_H__
980768
+
980768
+#include <glib.h>
980768
+#include <gudev/gudev.h>
980768
+
980768
+
980768
+G_BEGIN_DECLS
980768
+
980768
+gboolean mdraid_has_redundancy (const gchar *raid_level);
980768
+gboolean mdraid_has_stripes (const gchar *raid_level);
980768
+gchar   *read_sysfs_attr (GUdevDevice *device, const gchar *attr);
980768
+gint     read_sysfs_attr_as_int (GUdevDevice *device, const gchar *attr);
980768
+guint64  read_sysfs_attr_as_uint64 (GUdevDevice *device, const gchar *attr);
980768
+
980768
+G_END_DECLS
980768
+
980768
+
980768
+#endif /* __UDISKS_LINUX_MDRAID_HEPLERS_H__ */
980768
-- 
980768
2.9.5
980768
980768
From 61ff342139f21663958bcc2972a3efa37cf7bc83 Mon Sep 17 00:00:00 2001
980768
From: Vojtech Trefny <vtrefny@redhat.com>
980768
Date: Mon, 16 Oct 2017 12:41:22 +0200
980768
Subject: [PATCH 2/5] Remove leading/trailing white space in 'read_sysfs_attr'
980768
980768
So we don't have to call 'g_strstrip' after using it.
980768
980768
Related: rhbz#1400056
980768
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
980768
---
980768
 src/udiskslinuxmdraid.c        | 8 --------
980768
 src/udiskslinuxmdraidhelpers.c | 4 ++++
980768
 2 files changed, 4 insertions(+), 8 deletions(-)
980768
980768
diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c
980768
index 2dcf0ff..22b4ee4 100644
980768
--- a/src/udiskslinuxmdraid.c
980768
+++ b/src/udiskslinuxmdraid.c
980768
@@ -321,14 +321,8 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
           /* Can't use GUdevDevice methods as they cache the result and these variables vary */
980768
           degraded = read_sysfs_attr_as_int (raid_device->udev_device, "md/degraded");
980768
           sync_action = read_sysfs_attr (raid_device->udev_device, "md/sync_action");
980768
-          if (sync_action != NULL)
980768
-            g_strstrip (sync_action);
980768
           sync_completed = read_sysfs_attr (raid_device->udev_device, "md/sync_completed");
980768
-          if (sync_completed != NULL)
980768
-            g_strstrip (sync_completed);
980768
           bitmap_location = read_sysfs_attr (raid_device->udev_device, "md/bitmap/location");
980768
-          if (bitmap_location != NULL)
980768
-            g_strstrip (bitmap_location);
980768
         }
980768
 
980768
       if (mdraid_has_stripes (level))
980768
@@ -472,7 +466,6 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
               member_state = read_sysfs_attr (raid_device->udev_device, buf);
980768
               if (member_state != NULL)
980768
                 {
980768
-                  g_strstrip (member_state);
980768
                   member_state_elements = g_strsplit (member_state, ",", 0);
980768
                 }
980768
               else
980768
@@ -486,7 +479,6 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
               member_slot = read_sysfs_attr (raid_device->udev_device, buf);
980768
               if (member_slot != NULL)
980768
                 {
980768
-                  g_strstrip (member_slot);
980768
                   if (g_strcmp0 (member_slot, "none") != 0)
980768
                     member_slot_as_int = atoi (member_slot);
980768
                 }
980768
diff --git a/src/udiskslinuxmdraidhelpers.c b/src/udiskslinuxmdraidhelpers.c
980768
index dafdddf..297b1fa 100644
980768
--- a/src/udiskslinuxmdraidhelpers.c
980768
+++ b/src/udiskslinuxmdraidhelpers.c
980768
@@ -62,6 +62,10 @@ read_sysfs_attr (GUdevDevice *device,
980768
       goto out;
980768
     }
980768
 
980768
+  /* remove newline from the attribute */
980768
+  if (ret != NULL)
980768
+    g_strstrip (ret);
980768
+
980768
  out:
980768
   g_free (path);
980768
   return ret;
980768
-- 
980768
2.9.5
980768
980768
From 756571efc1b0d602bca2dd4ff761dca686dc08bd Mon Sep 17 00:00:00 2001
980768
From: Vojtech Trefny <vtrefny@redhat.com>
980768
Date: Mon, 16 Oct 2017 12:42:42 +0200
980768
Subject: [PATCH 3/5] Do not try to create file watchers for RAIDs without
980768
 redundancy
980768
980768
We are trying to watch 'md/degraded' and 'md/sync_action' sysfs
980768
files for all RAIDs but these files exist only for RAIDs with
980768
redundancy -- we shouldn't do this for raid0, containers and linear
980768
RAIDs.
980768
980768
Resolves: rhbz#1400056
980768
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
980768
---
980768
 src/udiskslinuxmdraidobject.c | 19 +++++++++++++++++++
980768
 1 file changed, 19 insertions(+)
980768
980768
diff --git a/src/udiskslinuxmdraidobject.c b/src/udiskslinuxmdraidobject.c
980768
index 493145e..1d2f07a 100644
980768
--- a/src/udiskslinuxmdraidobject.c
980768
+++ b/src/udiskslinuxmdraidobject.c
980768
@@ -30,6 +30,7 @@
980768
 #include "udisksdaemonutil.h"
980768
 #include "udiskslinuxprovider.h"
980768
 #include "udiskslinuxmdraidobject.h"
980768
+#include "udiskslinuxmdraidhelpers.h"
980768
 #include "udiskslinuxmdraid.h"
980768
 #include "udiskslinuxblockobject.h"
980768
 #include "udiskslinuxdevice.h"
980768
@@ -552,9 +553,18 @@ static void
980768
 raid_device_added (UDisksLinuxMDRaidObject *object,
980768
                    UDisksLinuxDevice       *device)
980768
 {
980768
+  gchar *level = NULL;
980768
+
980768
   g_assert (object->sync_action_source == NULL);
980768
   g_assert (object->degraded_source == NULL);
980768
 
980768
+  if (!UDISKS_IS_LINUX_DEVICE (device))
980768
+    goto out;
980768
+
980768
+  level = read_sysfs_attr (device->udev_device, "md/level");
980768
+  if (level == NULL || !mdraid_has_redundancy (level))
980768
+    goto out;
980768
+
980768
   /* udisks_debug ("start watching %s", g_udev_device_get_sysfs_path (device->udev_device)); */
980768
   object->sync_action_source = watch_attr (device,
980768
                                            "md/sync_action",
980768
@@ -564,6 +574,9 @@ raid_device_added (UDisksLinuxMDRaidObject *object,
980768
                                         "md/degraded",
980768
                                         (GSourceFunc) attr_changed,
980768
                                         object);
980768
+
980768
+ out:
980768
+  g_free (level);
980768
 }
980768
 
980768
 static void
980768
@@ -684,6 +697,12 @@ udisks_linux_mdraid_object_uevent (UDisksLinuxMDRaidObject *object,
980768
                   object->raid_device = g_object_ref (device);
980768
                   raid_device_added (object, object->raid_device);
980768
                 }
980768
+              else if (object->sync_action_source == NULL && object->degraded_source == NULL)
980768
+                {
980768
+                  /* we don't have file watchers, adding them may failed because
980768
+                     we were unable to get raid level, let's try again */
980768
+                  raid_device_added (object, object->raid_device);
980768
+                }
980768
             }
980768
         }
980768
     }
980768
-- 
980768
2.9.5
980768
980768
From ab6ee79abac6a75eddd0ecfba7fc5111663bc50f Mon Sep 17 00:00:00 2001
980768
From: Vojtech Trefny <vtrefny@redhat.com>
980768
Date: Mon, 16 Oct 2017 15:26:16 +0200
980768
Subject: [PATCH 5/5] Try to use libblockdev to get RAID array size
980768
980768
If reading size from sysfs fails, try to use libblockdev to read
980768
it from mdadm --examine data.
980768
980768
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
980768
---
980768
 src/udiskslinuxmdraid.c | 15 ++++++++++++++-
980768
 1 file changed, 14 insertions(+), 1 deletion(-)
980768
980768
diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c
980768
index 22b4ee4..6c94a2b 100644
980768
--- a/src/udiskslinuxmdraid.c
980768
+++ b/src/udiskslinuxmdraid.c
980768
@@ -246,6 +246,8 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
   GVariantBuilder builder;
980768
   UDisksDaemon *daemon = NULL;
980768
   UDisksBaseJob *job = NULL;
980768
+  GError *error = NULL;
980768
+  BDMDExamineData *raid_data = NULL;
980768
 
980768
   daemon = udisks_linux_mdraid_object_get_daemon (object);
980768
 
980768
@@ -303,7 +305,15 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
     }
980768
   else
980768
     {
980768
-      /* TODO: need MD_ARRAY_SIZE, see https://bugs.freedesktop.org/show_bug.cgi?id=53239#c5 */
980768
+      raid_data = bd_md_examine (g_udev_device_get_device_file (device->udev_device),
980768
+                                 &error);
980768
+      if (raid_data == NULL)
980768
+        {
980768
+          udisks_debug ("Failed to read array size: %s", error->message);
980768
+          g_clear_error (&error);
980768
+        }
980768
+      else
980768
+          size = raid_data->size;
980768
     }
980768
 
980768
   udisks_mdraid_set_uuid (iface, uuid);
980768
@@ -523,11 +533,14 @@ udisks_linux_mdraid_update (UDisksLinuxMDRaid       *mdraid,
980768
                                                                                 uuid));
980768
 
980768
  out:
980768
+  if (raid_data)
980768
+      bd_md_examine_data_free (raid_data);
980768
   g_free (sync_completed);
980768
   g_free (sync_action);
980768
   g_free (bitmap_location);
980768
   g_list_free_full (member_devices, g_object_unref);
980768
   g_clear_object (&raid_device);
980768
+  g_clear_error (&error);
980768
   return ret;
980768
 }
980768
 
980768
-- 
980768
2.9.5
980768