From 38249ffa0ddd55c83a8d9101cd8d934d9acf2a28 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
Date: Mon, 16 Oct 2017 12:42:42 +0200
Subject: [PATCH] Do not try to create file watchers for RAIDs without
 redundancy

We are trying to watch 'md/degraded' and 'md/sync_action' sysfs
files for all RAIDs but these files exist only for RAIDs with
redundancy -- we shouldn't do this for raid0, containers and linear
RAIDs.

Resolves: rhbz#1400056
(cherry picked from commit 756571efc1b0d602bca2dd4ff761dca686dc08bd)

[tblume: ported to version 2.1.3]
---
 src/udiskslinuxmdraid.c       |  2 +-
 src/udiskslinuxmdraid.h       |  3 ++-
 src/udiskslinuxmdraidobject.c | 26 +++++++++++++++++++++++++-
 src/udiskslinuxmdraidobject.h |  1 +
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/udiskslinuxmdraid.c b/src/udiskslinuxmdraid.c
index d7c507a4..07502717 100644
--- a/src/udiskslinuxmdraid.c
+++ b/src/udiskslinuxmdraid.c
@@ -123,7 +123,7 @@ udisks_linux_mdraid_new (void)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static gchar *
+gchar *
 read_sysfs_attr (GUdevDevice *device,
                  const gchar *attr)
 {
diff --git a/src/udiskslinuxmdraid.h b/src/udiskslinuxmdraid.h
index e8909878..a586cdf4 100644
--- a/src/udiskslinuxmdraid.h
+++ b/src/udiskslinuxmdraid.h
@@ -33,7 +33,8 @@ GType         udisks_linux_mdraid_get_type  (void) G_GNUC_CONST;
 UDisksMDRaid *udisks_linux_mdraid_new       (void);
 gboolean      udisks_linux_mdraid_update    (UDisksLinuxMDRaid       *mdraid,
                                              UDisksLinuxMDRaidObject *object);
-
+gchar        *read_sysfs_attr               (GUdevDevice             *device,
+                                             const gchar             *attr);
 G_END_DECLS
 
 #endif /* __UDISKS_LINUX_MDRAID_H__ */
diff --git a/src/udiskslinuxmdraidobject.c b/src/udiskslinuxmdraidobject.c
index dbfdec06..bd37624c 100644
--- a/src/udiskslinuxmdraidobject.c
+++ b/src/udiskslinuxmdraidobject.c
@@ -544,9 +544,18 @@ static void
 raid_device_added (UDisksLinuxMDRaidObject *object,
                    UDisksLinuxDevice       *device)
 {
+  gchar *level = NULL;
+
   g_assert (object->sync_action_source == NULL);
   g_assert (object->degraded_source == NULL);
 
+  if (!UDISKS_IS_LINUX_DEVICE (device))
+    goto out;
+
+  level = read_sysfs_attr (device->udev_device, "md/level");
+  if (level == NULL || !mdraid_has_redundancy (level))
+    goto out;
+
   /* udisks_debug ("start watching %s", g_udev_device_get_sysfs_path (device->udev_device)); */
   object->sync_action_source = watch_attr (device,
                                            "md/sync_action",
@@ -556,6 +565,9 @@ raid_device_added (UDisksLinuxMDRaidObject *object,
                                         "md/degraded",
                                         (GSourceFunc) attr_changed,
                                         object);
+
+ out:
+  g_free (level);
 }
 
 static void
@@ -673,6 +685,12 @@ udisks_linux_mdraid_object_uevent (UDisksLinuxMDRaidObject *object,
                   g_clear_object (&object->raid_device);
                   object->raid_device = g_object_ref (device);
                 }
+              else if (object->sync_action_source == NULL && object->degraded_source == NULL)
+                {
+                  /* we don't have file watchers, adding them may failed because
+                     we were unable to get raid level, let's try again */
+                  raid_device_added (object, object->raid_device);
+                }
             }
         }
     }
@@ -722,4 +740,10 @@ udisks_linux_mdraid_object_get_uuid (UDisksLinuxMDRaidObject *object)
   return object->uuid;
 }
 
-
+gboolean
+mdraid_has_redundancy (const gchar *raid_level)
+{
+  return raid_level != NULL &&
+         g_str_has_prefix (raid_level, "raid") &&
+         g_strcmp0 (raid_level, "raid0") != 0;
+}
diff --git a/src/udiskslinuxmdraidobject.h b/src/udiskslinuxmdraidobject.h
index 350d659d..582cb705 100644
--- a/src/udiskslinuxmdraidobject.h
+++ b/src/udiskslinuxmdraidobject.h
@@ -43,6 +43,7 @@ GList                   *udisks_linux_mdraid_object_get_members   (UDisksLinuxMD
 UDisksLinuxDevice       *udisks_linux_mdraid_object_get_device    (UDisksLinuxMDRaidObject   *object);
 
 gboolean                 udisks_linux_mdraid_object_have_devices  (UDisksLinuxMDRaidObject   *object);
+gboolean                 mdraid_has_redundancy                    (const gchar *raid_level);
 
 G_END_DECLS
 
-- 
2.13.6

