summaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2008-02-08 03:11:39 +0100
committerAlasdair G Kergon <agk@redhat.com>2008-02-08 03:11:39 +0100
commitaf195ac82e38ba802fd86b5a014ed05ef6dd88bb (patch)
tree661e5848dd970f6213cbcf181818f234cef2c571 /drivers/md
parentdm raid1: handle read failures (diff)
downloadlinux-af195ac82e38ba802fd86b5a014ed05ef6dd88bb.tar.xz
linux-af195ac82e38ba802fd86b5a014ed05ef6dd88bb.zip
dm raid1: report fault status
This patch adds extra information to the mirror status output, so that it can be determined which device(s) have failed. For each mirror device, a character is printed indicating the most severe error encountered. The characters are: * A => Alive - No failures * D => Dead - A write failure occurred leaving mirror out-of-sync * S => Sync - A sychronization failure occurred, mirror out-of-sync * R => Read - A read failure occurred, mirror data unaffected This allows userspace to properly reconfigure the mirror set. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-raid1.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 38efa7071dd7..edc057f5cdcc 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1781,29 +1781,57 @@ static void mirror_resume(struct dm_target *ti)
rh_start_recovery(&ms->rh);
}
+/*
+ * device_status_char
+ * @m: mirror device/leg we want the status of
+ *
+ * We return one character representing the most severe error
+ * we have encountered.
+ * A => Alive - No failures
+ * D => Dead - A write failure occurred leaving mirror out-of-sync
+ * S => Sync - A sychronization failure occurred, mirror out-of-sync
+ * R => Read - A read failure occurred, mirror data unaffected
+ *
+ * Returns: <char>
+ */
+static char device_status_char(struct mirror *m)
+{
+ if (!atomic_read(&(m->error_count)))
+ return 'A';
+
+ return (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
+ (test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' :
+ (test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U';
+}
+
+
static int mirror_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen)
{
unsigned int m, sz = 0;
struct mirror_set *ms = (struct mirror_set *) ti->private;
+ struct dirty_log *log = ms->rh.log;
+ char buffer[ms->nr_mirrors + 1];
switch (type) {
case STATUSTYPE_INFO:
DMEMIT("%d ", ms->nr_mirrors);
- for (m = 0; m < ms->nr_mirrors; m++)
+ for (m = 0; m < ms->nr_mirrors; m++) {
DMEMIT("%s ", ms->mirror[m].dev->name);
+ buffer[m] = device_status_char(&(ms->mirror[m]));
+ }
+ buffer[m] = '\0';
- DMEMIT("%llu/%llu 0 ",
- (unsigned long long)ms->rh.log->type->
- get_sync_count(ms->rh.log),
- (unsigned long long)ms->nr_regions);
+ DMEMIT("%llu/%llu 1 %s ",
+ (unsigned long long)log->type->get_sync_count(ms->rh.log),
+ (unsigned long long)ms->nr_regions, buffer);
- sz += ms->rh.log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
+ sz += log->type->status(ms->rh.log, type, result+sz, maxlen-sz);
break;
case STATUSTYPE_TABLE:
- sz = ms->rh.log->type->status(ms->rh.log, type, result, maxlen);
+ sz = log->type->status(ms->rh.log, type, result, maxlen);
DMEMIT("%d", ms->nr_mirrors);
for (m = 0; m < ms->nr_mirrors; m++)
@@ -1819,7 +1847,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
static struct target_type mirror_target = {
.name = "mirror",
- .version = {1, 0, 3},
+ .version = {1, 0, 20},
.module = THIS_MODULE,
.ctr = mirror_ctr,
.dtr = mirror_dtr,