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