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