Commit af195ac8 authored by Jonathan Brassow's avatar Jonathan Brassow Committed by Alasdair G Kergon

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: default avatarJonathan Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 06386bbf
...@@ -1781,29 +1781,57 @@ static void mirror_resume(struct dm_target *ti) ...@@ -1781,29 +1781,57 @@ static void mirror_resume(struct dm_target *ti)
rh_start_recovery(&ms->rh); 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, static int mirror_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen) char *result, unsigned int maxlen)
{ {
unsigned int m, sz = 0; unsigned int m, sz = 0;
struct mirror_set *ms = (struct mirror_set *) ti->private; struct mirror_set *ms = (struct mirror_set *) ti->private;
struct dirty_log *log = ms->rh.log;
char buffer[ms->nr_mirrors + 1];
switch (type) { switch (type) {
case STATUSTYPE_INFO: case STATUSTYPE_INFO:
DMEMIT("%d ", ms->nr_mirrors); 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); DMEMIT("%s ", ms->mirror[m].dev->name);
buffer[m] = device_status_char(&(ms->mirror[m]));
}
buffer[m] = '\0';
DMEMIT("%llu/%llu 0 ", DMEMIT("%llu/%llu 1 %s ",
(unsigned long long)ms->rh.log->type-> (unsigned long long)log->type->get_sync_count(ms->rh.log),
get_sync_count(ms->rh.log), (unsigned long long)ms->nr_regions, buffer);
(unsigned long long)ms->nr_regions);
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; break;
case STATUSTYPE_TABLE: 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); DMEMIT("%d", ms->nr_mirrors);
for (m = 0; m < ms->nr_mirrors; m++) for (m = 0; m < ms->nr_mirrors; m++)
...@@ -1819,7 +1847,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type, ...@@ -1819,7 +1847,7 @@ static int mirror_status(struct dm_target *ti, status_type_t type,
static struct target_type mirror_target = { static struct target_type mirror_target = {
.name = "mirror", .name = "mirror",
.version = {1, 0, 3}, .version = {1, 0, 20},
.module = THIS_MODULE, .module = THIS_MODULE,
.ctr = mirror_ctr, .ctr = mirror_ctr,
.dtr = mirror_dtr, .dtr = mirror_dtr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment