diff options
author | NeilBrown <neilb@suse.de> | 2010-11-22 19:35:25 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-11-22 19:35:25 +1100 |
commit | a5d85af748aafe3e3830b9d16faa5c92e783b171 (patch) | |
tree | 226da96fa25afdd3bc97ead7e91b5e59b10a8e8f /super-ddf.c | |
parent | f94c116f56cb821bfd619481d94fcd78ab8b53c0 (diff) | |
download | mdadm-a5d85af748aafe3e3830b9d16faa5c92e783b171.tar.gz |
get_info_super: report which other devices are thought to be working/failed.
To accurately detect when an array has been split and is now being
recombined, we need to track which other devices each thinks is
working.
We should never include a device in an array if it thinks that the
primary device has failed.
This patch just allows get_info_super to return a list of devices
and whether they are thought to be working or not.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'super-ddf.c')
-rw-r--r-- | super-ddf.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/super-ddf.c b/super-ddf.c index fca8edd..e492b4e 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -1187,7 +1187,7 @@ static void examine_super_ddf(struct supertype *st, char *homehost) examine_pds(sb); } -static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info); +static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map); static void uuid_from_super_ddf(struct supertype *st, int uuid[4]); @@ -1197,7 +1197,7 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose) */ struct mdinfo info; char nbuf[64]; - getinfo_super_ddf(st, &info); + getinfo_super_ddf(st, &info, NULL); fname_from_uuid(st, &info, nbuf, ':'); printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5); @@ -1211,7 +1211,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose) struct mdinfo info; unsigned int i; char nbuf[64]; - getinfo_super_ddf(st, &info); + getinfo_super_ddf(st, &info, NULL); fname_from_uuid(st, &info, nbuf, ':'); for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) { @@ -1233,7 +1233,7 @@ static void export_examine_super_ddf(struct supertype *st) { struct mdinfo info; char nbuf[64]; - getinfo_super_ddf(st, &info); + getinfo_super_ddf(st, &info, NULL); fname_from_uuid(st, &info, nbuf, ':'); printf("MD_METADATA=ddf\n"); printf("MD_LEVEL=container\n"); @@ -1259,7 +1259,7 @@ static void brief_detail_super_ddf(struct supertype *st) // struct ddf_super *ddf = st->sb; struct mdinfo info; char nbuf[64]; - getinfo_super_ddf(st, &info); + getinfo_super_ddf(st, &info, NULL); fname_from_uuid(st, &info, nbuf,':'); printf(" UUID=%s", nbuf + 5); } @@ -1346,14 +1346,15 @@ static void uuid_from_super_ddf(struct supertype *st, int uuid[4]) memcpy(uuid, buf, 4*4); } -static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info); +static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map); -static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) +static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map) { struct ddf_super *ddf = st->sb; + int map_disks = info->array.raid_disks; if (ddf->currentconf) { - getinfo_super_ddf_bvd(st, info); + getinfo_super_ddf_bvd(st, info, map); return; } @@ -1397,17 +1398,29 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) uuid_from_super_ddf(st, info->uuid); + if (map) { + int i; + for (i = 0 ; i < map_disks; i++) { + if (i < info->array.raid_disks && + (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) && + !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed)) + map[i] = 1; + else + map[i] = 0; + } + } } static int rlq_to_layout(int rlq, int prl, int raiddisks); -static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) +static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map) { struct ddf_super *ddf = st->sb; struct vcl *vc = ddf->currentconf; int cd = ddf->currentdev; int j; struct dl *dl; + int map_disks = info->array.raid_disks; /* FIXME this returns BVD info - what if we want SVD ?? */ @@ -1470,6 +1483,18 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) for(j=0; j<16; j++) if (info->name[j] == ' ') info->name[j] = 0; + + if (map) + for (j = 0; j < map_disks; j++) { + map[j] = 0; + if (j < info->array.raid_disks) { + int i = find_phys(ddf, vc->conf.phys_refnum[j]); + if (i >= 0 && + (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) && + !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed)) + map[i] = 1; + } + } } |