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