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