984f77
From ebb3e759bba99ea85b3be9608258d6a5bb7e907a Mon Sep 17 00:00:00 2001
984f77
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
984f77
Date: Tue, 29 Mar 2022 12:49:54 +0200
984f77
Subject: [PATCH] shutdown: get only active md arrays.
984f77
984f77
Current md_list_get() implementation filters all block devices, started from
984f77
"md*". This is ambiguous because list could contain:
984f77
- partitions created upon md device (mdXpY)
984f77
- external metadata container- specific type of md array.
984f77
984f77
For partitions there is no issue, because they aren't handle STOP_ARRAY
984f77
ioctl sent later. It generates misleading errors only.
984f77
984f77
Second case is more problematic because containers are not locked in kernel.
984f77
They are stopped even if container member array is active. For that reason
984f77
reboot or shutdown flow could be blocked because metadata manager cannot be
984f77
restarted after switch root on shutdown.
984f77
984f77
Add filters to remove partitions and containers from md_list. Partitions
984f77
can be excluded by DEVTYPE. Containers are determined by MD_LEVEL
984f77
property, we are excluding all with "container" value.
984f77
984f77
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
984f77
(cherry picked from commit 3a3b022d2cc112803ea7b9beea98bbcad110368a)
984f77
984f77
Related: #1817706
984f77
---
984f77
 src/core/umount.c | 18 +++++++++++++++++-
984f77
 1 file changed, 17 insertions(+), 1 deletion(-)
984f77
984f77
diff --git a/src/core/umount.c b/src/core/umount.c
984f77
index ed90c6b1fc..b513e91c4d 100644
984f77
--- a/src/core/umount.c
984f77
+++ b/src/core/umount.c
984f77
@@ -358,11 +358,16 @@ static int md_list_get(MountPoint **head) {
984f77
         if (r < 0)
984f77
                 return r;
984f77
 
984f77
+        /* Filter out partitions. */
984f77
+        r = udev_enumerate_add_match_property(e, "DEVTYPE", "disk");
984f77
+        if (r < 0)
984f77
+                return r;
984f77
+
984f77
         first = udev_enumerate_get_list_entry(e);
984f77
         udev_list_entry_foreach(item, first) {
984f77
                 _cleanup_(udev_device_unrefp) struct udev_device *d;
984f77
                 _cleanup_free_ char *p = NULL;
984f77
-                const char *dn;
984f77
+                const char *dn, *md_level;
984f77
                 MountPoint *m;
984f77
                 dev_t devnum;
984f77
 
984f77
@@ -375,6 +380,17 @@ static int md_list_get(MountPoint **head) {
984f77
                 if (major(devnum) == 0 || !dn)
984f77
                         continue;
984f77
 
984f77
+                md_level = udev_device_get_property_value(d, "MD_LEVEL");
984f77
+                if (!m) {
984f77
+                        log_warning("Failed to get MD_LEVEL property for %s, ignoring", dn);
984f77
+                        continue;
984f77
+                }
984f77
+
984f77
+                /* MD "containers" are a special type of MD devices, used for external metadata.
984f77
+                 * Since it doesn't provide RAID functionality in itself we don't need to stop it. */
984f77
+                if (streq(md_level, "container"))
984f77
+                        continue;
984f77
+
984f77
                 p = strdup(dn);
984f77
                 if (!p)
984f77
                         return -ENOMEM;