mdadm/0038-mdadm-Introduce-new-array-state-broken-for-raid0-lin.patch
Neil Brown 1c8fb911e6 Accepting request 781064 from home:colyli:branches:Base:System
- Update for latest mdadm-4.1+ patches, this is required by
  jsc#SLE-10078 and jsc#SLE-9348. Mostly the purpose is for
  latest Intel IMSM raid support.
  The following patches also include previous patches with
  new re-ordered prefix numbers.
- Makefile: install mdadm_env.sh to /usr/lib/mdadm (bsc#1111960)
  0000-Makefile-install-mdadm_env.sh-to-usr-lib-mdadm.patch
- Assemble: keep MD_DISK_FAILFAST and MD_DISK_WRITEMOSTLY flag
  (jsc#SLE-10078, jsc#SLE-9348)
  0001-Assemble-keep-MD_DISK_FAILFAST-and-MD_DISK_WRITEMOST.patch
- Document PART-POLICY lines (jsc#SLE-10078, jsc#SLE-9348)
  0002-Document-PART-POLICY-lines.patc
- policy: support devices with multiple paths.
  (jsc#SLE-10078, jsc#SLE-9348)
  0003-policy-support-devices-with-multiple-paths.patch
- mdcheck: add systemd unit files to run mdcheck. (bsc#1115407)
  0004-mdcheck-add-systemd-unit-files-to-run-mdcheck.patch
- Monitor: add system timer to run --oneshot periodically (bsc#1115407)
  0005-Monitor-add-system-timer-to-run-oneshot-periodically.patch
- imsm: update metadata correctly while raid10 double
  (jsc#SLE-10078, jsc#SLE-9348)
  0006-imsm-update-metadata-correctly-while-raid10-double-d.patch
- Assemble: mask FAILFAST and WRITEMOSTLY flags when finding
  (jsc#SLE-10078, jsc#SLE-9348)
  0007-Assemble-mask-FAILFAST-and-WRITEMOSTLY-flags-when-fi.patch
- Grow: avoid overflow in compute_backup_blocks()
  (jsc#SLE-10078, jsc#SLE-9348)
  0008-Grow-avoid-overflow-in-compute_backup_blocks.patch
- Grow: report correct new chunk size. (jsc#SLE-10078, jsc#SLE-9348)
  0009-Grow-report-correct-new-chunk-size.patch

OBS-URL: https://build.opensuse.org/request/show/781064
OBS-URL: https://build.opensuse.org/package/show/Base:System/mdadm?expand=0&rev=181
2020-03-04 04:49:18 +00:00

168 lines
5.5 KiB
Diff

From 43ebc9105e9dafe5145b3e801c05da4736bf6e02 Mon Sep 17 00:00:00 2001
From: "Guilherme G. Piccoli" <gpiccoli@canonical.com>
Date: Tue, 3 Sep 2019 16:49:01 -0300
Subject: [PATCH] mdadm: Introduce new array state 'broken' for raid0/linear
Git-commit: 43ebc9105e9dafe5145b3e801c05da4736bf6e02
Patch-mainline: mdadm-4.1+
References: jsc#SLE-10078, jsc#SLE-9348
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.
Cc: Jes Sorensen <jes.sorensen@gmail.com>
Cc: NeilBrown <neilb@suse.de>
Cc: Song Liu <songliubraving@fb.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@canonical.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Signed-off-by: Coly Li <colyli@suse.de>
---
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 ad60434..3e61e37 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 43b07d5..c88ceab 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -373,6 +373,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.25.0