--- Begin Message ---
Package: mdadm
Version: 4.1-2
Severity: normal
Tags: patch
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu focal ubuntu-patch
Dear Maintainer,
* Currently, mounted raid0/md-linear arrays have no indication/warning when one
or more members are removed or suffer from some non-recoverable error
condition. The mdadm tool shows "clean" state regardless if a member was
removed.
* The patch proposed in this SRU addresses this issue by introducing a new
state "broken", which is analog to "clean" but indicates that array is not in a
good/correct state. The commit, available upstream as 43ebc910 ("mdadm:
Introduce new array state 'broken' for raid0/linear") [0], was extensively
discussed and received a good amount of reviews/analysis by both the current
mdadm maintainer as well as an old maintainer.
* One important note here is that this patch requires a counter-part in the
kernel to be fully functional, which was SRUed in LP: #1847773.
It works fine/transparently without this kernel counter-part though.
In Ubuntu, the attached patch was applied to achieve the following:
* Introduce "broken" state for RAID0/Linear in mdadm (LP: #1847924)
Thanks for considering the patch.
diff -Nru mdadm-4.1/debian/control mdadm-4.1/debian/control
--- mdadm-4.1/debian/control 2019-05-04 23:58:27.000000000 -0400
+++ mdadm-4.1/debian/control 2019-10-13 17:04:34.000000000 -0400
@@ -1,8 +1,7 @@
Source: mdadm
Section: admin
Priority: optional
-Maintainer: Ubuntu Developers <ubuntu-devel-disc...@lists.ubuntu.com>
-XSBC-Original-Maintainer: Debian QA Group <packa...@qa.debian.org>
+Maintainer: Debian QA Group <packa...@qa.debian.org>
Build-Depends: debhelper (>= 11), po-debconf, groff-base
Standards-Version: 4.3.0
Vcs-Git: https://git.dgit.debian.org/mdadm
diff -Nru
mdadm-4.1/debian/patches/lp-1847924-introduce-new-array-state-broken.patch
mdadm-4.1/debian/patches/lp-1847924-introduce-new-array-state-broken.patch
--- mdadm-4.1/debian/patches/lp-1847924-introduce-new-array-state-broken.patch
1969-12-31 19:00:00.000000000 -0500
+++ mdadm-4.1/debian/patches/lp-1847924-introduce-new-array-state-broken.patch
2019-10-13 17:04:34.000000000 -0400
@@ -0,0 +1,159 @@
+Subject: Introduce new array state 'broken' for raid0/linear
+
+Currently if a md raid0/linear array gets one or more members removed while
+being mounted, kernel keeps showing state 'clean' in the 'array_state'
+sysfs attribute. Despite udev signaling the member device is gone, 'mdadm'
+cannot issue the STOP_ARRAY ioctl successfully, given the array is mounted.
+
+Nothing else hints that something is wrong (except that the removed devices
+don't show properly in the output of mdadm 'detail' command). There is no
+other property to be checked, and if user is not performing reads/writes
+to the array, even kernel log is quiet and doesn't give a clue about the
+missing member.
+
+This patch is the mdadm counterpart of kernel new array state 'broken'.
+The 'broken' state mimics the state 'clean' in every aspect, being useful
+only to distinguish if an array has some member missing. All necessary
+paths in mdadm were changed to deal with 'broken' state, and in case the
+tool runs in a kernel that is not updated, it'll work normally, i.e., it
+doesn't require the 'broken' state in order to work.
+Also, this patch changes the way the array state is showed in the 'detail'
+command (for raid0/linear only) - now it takes the 'array_state' sysfs
+attribute into account instead of only rely in the MD_SB_CLEAN flag.
+
+Author: Guilherme G. Piccoli <gpicc...@canonical.com>
+Origin: upstream,
+git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=cb77f8c598ede2b7efec23f899b1cda44c315195
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1847924
+Last-Update: 2019-10-13
+---
+ Detail.c | 14 ++++++++++++--
+ Monitor.c | 8 ++++++--
+ maps.c | 1 +
+ mdadm.h | 1 +
+ mdmon.h | 2 +-
+ monitor.c | 4 ++--
+ 6 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/Detail.c b/Detail.c
+index b3e857a..d24f334 100644
+--- a/Detail.c
++++ b/Detail.c
+@@ -81,6 +81,7 @@ int Detail(char *dev, struct context *c)
+ int external;
+ int inactive;
+ int is_container = 0;
++ char *arrayst;
+
+ if (fd < 0) {
+ pr_err("cannot open %s: %s\n",
+@@ -485,9 +486,18 @@ int Detail(char *dev, struct context *c)
+ else
+ st = ", degraded";
+
++ if (array.state & (1 << MD_SB_CLEAN)) {
++ if ((array.level == 0) ||
++ (array.level == LEVEL_LINEAR))
++ arrayst = map_num(sysfs_array_states,
++ sra->array_state);
++ else
++ arrayst = "clean";
++ } else
++ arrayst = "active";
++
+ printf(" State : %s%s%s%s%s%s \n",
+- (array.state & (1 << MD_SB_CLEAN)) ?
+- "clean" : "active", st,
++ arrayst, st,
+ (!e || (e->percent < 0 &&
+ e->percent != RESYNC_PENDING &&
+ e->percent != RESYNC_DELAYED)) ?
+diff --git a/Monitor.c b/Monitor.c
+index 036103f..b527165 100644
+--- a/Monitor.c
++++ b/Monitor.c
+@@ -1055,8 +1055,11 @@ int Wait(char *dev)
+ }
+ }
+
++/* The state "broken" is used only for RAID0/LINEAR - it's the same as
++ * "clean", but used in case the array has one or more members missing.
++ */
+ static char *clean_states[] = {
+- "clear", "inactive", "readonly", "read-auto", "clean", NULL };
++ "clear", "inactive", "readonly", "read-auto", "clean", "broken", NULL };
+
+ int WaitClean(char *dev, int verbose)
+ {
+@@ -1116,7 +1119,8 @@ int WaitClean(char *dev, int verbose)
+ rv = read(state_fd, buf, sizeof(buf));
+ if (rv < 0)
+ break;
+- if (sysfs_match_word(buf, clean_states) <= 4)
++ if (sysfs_match_word(buf, clean_states) <
++ (int)ARRAY_SIZE(clean_states) - 1)
+ break;
+ rv = sysfs_wait(state_fd, &delay);
+ if (rv < 0 && errno != EINTR)
+diff --git a/maps.c b/maps.c
+index 02a0474..49b7f2c 100644
+--- a/maps.c
++++ b/maps.c
+@@ -150,6 +150,7 @@ mapping_t sysfs_array_states[] = {
+ { "read-auto", ARRAY_READ_AUTO },
+ { "clean", ARRAY_CLEAN },
+ { "write-pending", ARRAY_WRITE_PENDING },
++ { "broken", ARRAY_BROKEN },
+ { NULL, ARRAY_UNKNOWN_STATE }
+ };
+
+diff --git a/mdadm.h b/mdadm.h
+index 705bd9b..216b491 100644
+--- a/mdadm.h
++++ b/mdadm.h
+@@ -345,6 +345,7 @@ struct mdinfo {
+ ARRAY_ACTIVE,
+ ARRAY_WRITE_PENDING,
+ ARRAY_ACTIVE_IDLE,
++ ARRAY_BROKEN,
+ ARRAY_UNKNOWN_STATE,
+ } array_state;
+ struct md_bb bb;
+diff --git a/mdmon.h b/mdmon.h
+index 818367c..b3d72ac 100644
+--- a/mdmon.h
++++ b/mdmon.h
+@@ -21,7 +21,7 @@
+ extern const char Name[];
+
+ enum array_state { clear, inactive, suspended, readonly, read_auto,
+- clean, active, write_pending, active_idle, bad_word};
++ clean, active, write_pending, active_idle, broken, bad_word};
+
+ enum sync_action { idle, reshape, resync, recover, check, repair, bad_action
};
+
+diff --git a/monitor.c b/monitor.c
+index 81537ed..e0d3be6 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -26,7 +26,7 @@
+
+ static char *array_states[] = {
+ "clear", "inactive", "suspended", "readonly", "read-auto",
+- "clean", "active", "write-pending", "active-idle", NULL };
++ "clean", "active", "write-pending", "active-idle", "broken", NULL };
+ static char *sync_actions[] = {
+ "idle", "reshape", "resync", "recover", "check", "repair", NULL
+ };
+@@ -476,7 +476,7 @@ static int read_and_act(struct active_array *a, fd_set
*fds)
+ a->next_state = clean;
+ ret |= ARRAY_DIRTY;
+ }
+- if (a->curr_state == clean) {
++ if ((a->curr_state == clean) || (a->curr_state == broken)) {
+ a->container->ss->set_array_state(a, 1);
+ }
+ if (a->curr_state == active ||
+--
+2.23.0
+
diff -Nru mdadm-4.1/debian/patches/series mdadm-4.1/debian/patches/series
--- mdadm-4.1/debian/patches/series 2019-06-18 11:27:42.000000000 -0400
+++ mdadm-4.1/debian/patches/series 2019-10-13 17:04:34.000000000 -0400
@@ -15,3 +15,4 @@
readlink-path.patch
mdmonitor-service-simplify.diff
randomize-timers.patch
+lp-1847924-introduce-new-array-state-broken.patch
--- End Message ---