diff -Nru mdadm-4.1/debian/changelog mdadm-4.1/debian/changelog --- mdadm-4.1/debian/changelog 2019-12-04 19:44:30.000000000 +0000 +++ mdadm-4.1/debian/changelog 2019-12-10 20:35:16.000000000 +0000 @@ -1,3 +1,9 @@ +mdadm (4.1-1ubuntu1.2) disco; urgency=medium + + * Introduce "broken" state for RAID0/Linear in mdadm (LP: #1847924) + + -- Guilherme G. Piccoli Tue, 10 Dec 2019 20:35:16 +0000 + mdadm (4.1-1ubuntu1.1) disco; urgency=medium * Add support for RAID0 layouts. Released kernels are being updated diff -Nru mdadm-4.1/debian/patches/lp1847924-Introduce-new-array-state-broken-for-raid0.patch mdadm-4.1/debian/patches/lp1847924-Introduce-new-array-state-broken-for-raid0.patch --- mdadm-4.1/debian/patches/lp1847924-Introduce-new-array-state-broken-for-raid0.patch 1970-01-01 00:00:00.000000000 +0000 +++ mdadm-4.1/debian/patches/lp1847924-Introduce-new-array-state-broken-for-raid0.patch 2019-12-10 20:35:05.000000000 +0000 @@ -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. + +NOTICE that the original version of this patch also changes the way the +array state is showed in the 'detail' command (for raid0/linear only), +taking the sysfs attribute 'array_state' into account. +But ** for SRU purposes ** this specific version keeps the old behavior +in Bionic / Disco / Eoan, adding just the 'broken' state, otherwise +always showing 'clean'. + +Author: Guilherme G. Piccoli +Origin: upstream, +git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=43ebc9105e9d +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1847924 +Last-Update: 2019-12-10 + +diff --git a/Detail.c b/Detail.c +index ce69796..2a69611 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,25 @@ 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); ++ ++ /* This is to keep output compatibility ++ * in the SRU for B/D/E - we only change ++ * the state output in case it's "broken" ++ */ ++ if (strcmp(arrayst, "broken")) ++ arrayst = "clean"; ++ } 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 f143552..a4fd279 100644 +--- a/maps.c ++++ b/maps.c +@@ -162,6 +162,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 8da9170..b23308c 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 || diff -Nru mdadm-4.1/debian/patches/series mdadm-4.1/debian/patches/series --- mdadm-4.1/debian/patches/series 2019-12-04 19:41:34.000000000 +0000 +++ mdadm-4.1/debian/patches/series 2019-12-10 20:35:05.000000000 +0000 @@ -16,3 +16,4 @@ mdmonitor-service-simplify.diff 0001-Create-add-support-for-RAID0-layouts.patch 0002-Assemble-add-support-for-RAID0-layouts.patch +lp1847924-Introduce-new-array-state-broken-for-raid0.patch