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