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