dcavalca / rpms / mdadm

Forked from rpms/mdadm 3 years ago
Clone

Blame SOURCES/0036-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch

6e099e
From 43ebc9105e9dafe5145b3e801c05da4736bf6e02 Mon Sep 17 00:00:00 2001
6e099e
From: "Guilherme G. Piccoli" <gpiccoli@canonical.com>
6e099e
Date: Tue, 3 Sep 2019 16:49:01 -0300
6e099e
Subject: [RHEL7.8 PATCH V2 36/47] mdadm: Introduce new array state 'broken'
6e099e
 for raid0/linear
6e099e
6e099e
Currently if a md raid0/linear array gets one or more members removed while
6e099e
being mounted, kernel keeps showing state 'clean' in the 'array_state'
6e099e
sysfs attribute. Despite udev signaling the member device is gone, 'mdadm'
6e099e
cannot issue the STOP_ARRAY ioctl successfully, given the array is mounted.
6e099e
6e099e
Nothing else hints that something is wrong (except that the removed devices
6e099e
don't show properly in the output of mdadm 'detail' command). There is no
6e099e
other property to be checked, and if user is not performing reads/writes
6e099e
to the array, even kernel log is quiet and doesn't give a clue about the
6e099e
missing member.
6e099e
6e099e
This patch is the mdadm counterpart of kernel new array state 'broken'.
6e099e
The 'broken' state mimics the state 'clean' in every aspect, being useful
6e099e
only to distinguish if an array has some member missing. All necessary
6e099e
paths in mdadm were changed to deal with 'broken' state, and in case the
6e099e
tool runs in a kernel that is not updated, it'll work normally, i.e., it
6e099e
doesn't require the 'broken' state in order to work.
6e099e
Also, this patch changes the way the array state is showed in the 'detail'
6e099e
command (for raid0/linear only) - now it takes the 'array_state' sysfs
6e099e
attribute into account instead of only rely in the MD_SB_CLEAN flag.
6e099e
6e099e
Cc: Jes Sorensen <jes.sorensen@gmail.com>
6e099e
Cc: NeilBrown <neilb@suse.de>
6e099e
Cc: Song Liu <songliubraving@fb.com>
6e099e
Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
6e099e
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
6e099e
---
6e099e
 Detail.c  | 14 ++++++++++++--
6e099e
 Monitor.c |  8 ++++++--
6e099e
 maps.c    |  1 +
6e099e
 mdadm.h   |  1 +
6e099e
 mdmon.h   |  2 +-
6e099e
 monitor.c |  4 ++--
6e099e
 6 files changed, 23 insertions(+), 7 deletions(-)
6e099e
6e099e
diff --git a/Detail.c b/Detail.c
6e099e
index ad60434..3e61e37 100644
6e099e
--- a/Detail.c
6e099e
+++ b/Detail.c
6e099e
@@ -81,6 +81,7 @@ int Detail(char *dev, struct context *c)
6e099e
 	int external;
6e099e
 	int inactive;
6e099e
 	int is_container = 0;
6e099e
+	char *arrayst;
6e099e
 
6e099e
 	if (fd < 0) {
6e099e
 		pr_err("cannot open %s: %s\n",
6e099e
@@ -485,9 +486,18 @@ int Detail(char *dev, struct context *c)
6e099e
 			else
6e099e
 				st = ", degraded";
6e099e
 
6e099e
+			if (array.state & (1 << MD_SB_CLEAN)) {
6e099e
+				if ((array.level == 0) ||
6e099e
+				    (array.level == LEVEL_LINEAR))
6e099e
+					arrayst = map_num(sysfs_array_states,
6e099e
+							  sra->array_state);
6e099e
+				else
6e099e
+					arrayst = "clean";
6e099e
+			} else
6e099e
+				arrayst = "active";
6e099e
+
6e099e
 			printf("             State : %s%s%s%s%s%s \n",
6e099e
-			       (array.state & (1 << MD_SB_CLEAN)) ?
6e099e
-			       "clean" : "active", st,
6e099e
+			       arrayst, st,
6e099e
 			       (!e || (e->percent < 0 &&
6e099e
 				       e->percent != RESYNC_PENDING &&
6e099e
 				       e->percent != RESYNC_DELAYED)) ?
6e099e
diff --git a/Monitor.c b/Monitor.c
6e099e
index 036103f..b527165 100644
6e099e
--- a/Monitor.c
6e099e
+++ b/Monitor.c
6e099e
@@ -1055,8 +1055,11 @@ int Wait(char *dev)
6e099e
 	}
6e099e
 }
6e099e
 
6e099e
+/* The state "broken" is used only for RAID0/LINEAR - it's the same as
6e099e
+ * "clean", but used in case the array has one or more members missing.
6e099e
+ */
6e099e
 static char *clean_states[] = {
6e099e
-	"clear", "inactive", "readonly", "read-auto", "clean", NULL };
6e099e
+	"clear", "inactive", "readonly", "read-auto", "clean", "broken", NULL };
6e099e
 
6e099e
 int WaitClean(char *dev, int verbose)
6e099e
 {
6e099e
@@ -1116,7 +1119,8 @@ int WaitClean(char *dev, int verbose)
6e099e
 			rv = read(state_fd, buf, sizeof(buf));
6e099e
 			if (rv < 0)
6e099e
 				break;
6e099e
-			if (sysfs_match_word(buf, clean_states) <= 4)
6e099e
+			if (sysfs_match_word(buf, clean_states) <
6e099e
+			    (int)ARRAY_SIZE(clean_states) - 1)
6e099e
 				break;
6e099e
 			rv = sysfs_wait(state_fd, &delay);
6e099e
 			if (rv < 0 && errno != EINTR)
6e099e
diff --git a/maps.c b/maps.c
6e099e
index 02a0474..49b7f2c 100644
6e099e
--- a/maps.c
6e099e
+++ b/maps.c
6e099e
@@ -150,6 +150,7 @@ mapping_t sysfs_array_states[] = {
6e099e
 	{ "read-auto", ARRAY_READ_AUTO },
6e099e
 	{ "clean", ARRAY_CLEAN },
6e099e
 	{ "write-pending", ARRAY_WRITE_PENDING },
6e099e
+	{ "broken", ARRAY_BROKEN },
6e099e
 	{ NULL, ARRAY_UNKNOWN_STATE }
6e099e
 };
6e099e
 
6e099e
diff --git a/mdadm.h b/mdadm.h
6e099e
index 43b07d5..c88ceab 100644
6e099e
--- a/mdadm.h
6e099e
+++ b/mdadm.h
6e099e
@@ -373,6 +373,7 @@ struct mdinfo {
6e099e
 		ARRAY_ACTIVE,
6e099e
 		ARRAY_WRITE_PENDING,
6e099e
 		ARRAY_ACTIVE_IDLE,
6e099e
+		ARRAY_BROKEN,
6e099e
 		ARRAY_UNKNOWN_STATE,
6e099e
 	} array_state;
6e099e
 	struct md_bb bb;
6e099e
diff --git a/mdmon.h b/mdmon.h
6e099e
index 818367c..b3d72ac 100644
6e099e
--- a/mdmon.h
6e099e
+++ b/mdmon.h
6e099e
@@ -21,7 +21,7 @@
6e099e
 extern const char Name[];
6e099e
 
6e099e
 enum array_state { clear, inactive, suspended, readonly, read_auto,
6e099e
-		   clean, active, write_pending, active_idle, bad_word};
6e099e
+		   clean, active, write_pending, active_idle, broken, bad_word};
6e099e
 
6e099e
 enum sync_action { idle, reshape, resync, recover, check, repair, bad_action };
6e099e
 
6e099e
diff --git a/monitor.c b/monitor.c
6e099e
index 81537ed..e0d3be6 100644
6e099e
--- a/monitor.c
6e099e
+++ b/monitor.c
6e099e
@@ -26,7 +26,7 @@
6e099e
 
6e099e
 static char *array_states[] = {
6e099e
 	"clear", "inactive", "suspended", "readonly", "read-auto",
6e099e
-	"clean", "active", "write-pending", "active-idle", NULL };
6e099e
+	"clean", "active", "write-pending", "active-idle", "broken", NULL };
6e099e
 static char *sync_actions[] = {
6e099e
 	"idle", "reshape", "resync", "recover", "check", "repair", NULL
6e099e
 };
6e099e
@@ -476,7 +476,7 @@ static int read_and_act(struct active_array *a, fd_set *fds)
6e099e
 		a->next_state = clean;
6e099e
 		ret |= ARRAY_DIRTY;
6e099e
 	}
6e099e
-	if (a->curr_state == clean) {
6e099e
+	if ((a->curr_state == clean) || (a->curr_state == broken)) {
6e099e
 		a->container->ss->set_array_state(a, 1);
6e099e
 	}
6e099e
 	if (a->curr_state == active ||
6e099e
-- 
6e099e
2.7.5
6e099e