summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-11-22 19:35:25 +1100
committerNeilBrown <neilb@suse.de>2010-11-22 19:35:25 +1100
commita5d85af748aafe3e3830b9d16faa5c92e783b171 (patch)
tree226da96fa25afdd3bc97ead7e91b5e59b10a8e8f
parentf94c116f56cb821bfd619481d94fcd78ab8b53c0 (diff)
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>
-rw-r--r--Assemble.c12
-rw-r--r--Create.c8
-rw-r--r--Detail.c2
-rw-r--r--Examine.c4
-rw-r--r--Grow.c6
-rw-r--r--Incremental.c16
-rw-r--r--Manage.c4
-rw-r--r--Query.c2
-rw-r--r--managemon.c2
-rw-r--r--mapfile.c2
-rw-r--r--mdadm.h6
-rw-r--r--super-ddf.c43
-rw-r--r--super-gpt.c2
-rw-r--r--super-intel.c52
-rw-r--r--super-mbr.c2
-rw-r--r--super0.c9
-rw-r--r--super1.c13
-rw-r--r--util.c4
18 files changed, 127 insertions, 62 deletions
diff --git a/Assemble.c b/Assemble.c
index a25fdbe1..0900f26a 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -283,7 +283,7 @@ int Assemble(struct supertype *st, char *mddev,
} else {
content = &info;
memset(content, 0, sizeof(*content));
- tst->ss->getinfo_super(tst, content);
+ tst->ss->getinfo_super(tst, content, NULL);
}
if (dfd >= 0) close(dfd);
@@ -520,7 +520,7 @@ int Assemble(struct supertype *st, char *mddev,
/* Now need to open the array device. Use create_mddev */
if (content == &info)
- st->ss->getinfo_super(st, content);
+ st->ss->getinfo_super(st, content, NULL);
trustworthy = FOREIGN;
name = content->name;
@@ -643,7 +643,7 @@ int Assemble(struct supertype *st, char *mddev,
close(mdfd);
return 1;
}
- tst->ss->getinfo_super(tst, content);
+ tst->ss->getinfo_super(tst, content, NULL);
memcpy(content->uuid, ident->uuid, 16);
strcpy(content->name, ident->name);
@@ -704,7 +704,7 @@ int Assemble(struct supertype *st, char *mddev,
close(mdfd);
return 1;
}
- tst->ss->getinfo_super(tst, content);
+ tst->ss->getinfo_super(tst, content, NULL);
tst->ss->free_super(tst);
close(dfd);
}
@@ -798,7 +798,7 @@ int Assemble(struct supertype *st, char *mddev,
if (update && strcmp(update, "byteorder")==0)
st->minor_version = 90;
- st->ss->getinfo_super(st, content);
+ st->ss->getinfo_super(st, content, NULL);
clean = content->array.state & 1;
/* now we have some devices that might be suitable.
@@ -955,7 +955,7 @@ int Assemble(struct supertype *st, char *mddev,
close(mdfd);
return 1;
}
- st->ss->getinfo_super(st, content);
+ st->ss->getinfo_super(st, content, NULL);
#ifndef MDASSEMBLE
sysfs_init(content, mdfd, 0);
#endif
diff --git a/Create.c b/Create.c
index 2bf7ebe2..bbf2f2b0 100644
--- a/Create.c
+++ b/Create.c
@@ -614,7 +614,7 @@ int Create(struct supertype *st, char *mddev,
total_slots = info.array.nr_disks;
sysfs_init(&info, mdfd, 0);
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (did_default && verbose >= 0) {
if (is_subarray(info.text_version)) {
@@ -797,7 +797,7 @@ int Create(struct supertype *st, char *mddev,
ioctl(mdfd, STOP_ARRAY, NULL);
goto abort;
}
- st->ss->getinfo_super(st, inf);
+ st->ss->getinfo_super(st, inf, NULL);
safe_mode_delay = inf->safe_mode_delay;
if (have_container && verbose > 0)
@@ -842,7 +842,7 @@ int Create(struct supertype *st, char *mddev,
* again returns container info.
*/
map_lock(&map);
- st->ss->getinfo_super(st, &info_new);
+ st->ss->getinfo_super(st, &info_new, NULL);
if (st->ss->external && level != LEVEL_CONTAINER &&
!same_uuid(info_new.uuid, info.uuid, 0)) {
map_update(&map, fd2devnum(mdfd),
@@ -857,7 +857,7 @@ int Create(struct supertype *st, char *mddev,
if (me) {
char *path = strdup(me->path);
- st->ss->getinfo_super(st, &info_new);
+ st->ss->getinfo_super(st, &info_new, NULL);
map_update(&map, st->container_dev,
info_new.text_version,
info_new.uuid, path);
diff --git a/Detail.c b/Detail.c
index fdfffb72..eb51a3ec 100644
--- a/Detail.c
+++ b/Detail.c
@@ -143,7 +143,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
close(fd2);
if (err)
continue;
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (array.raid_disks != 0 && /* container */
(info.array.ctime != array.ctime ||
diff --git a/Examine.c b/Examine.c
index 01838c8b..f646805b 100644
--- a/Examine.c
+++ b/Examine.c
@@ -119,9 +119,9 @@ int Examine(mddev_dev_t devlist, int brief, int export, int scan,
ap->spares = 0;
ap->st = st;
arrays = ap;
- st->ss->getinfo_super(st, &ap->info);
+ st->ss->getinfo_super(st, &ap->info, NULL);
} else
- st->ss->getinfo_super(st, &ap->info);
+ st->ss->getinfo_super(st, &ap->info, NULL);
if (!st->loaded_container &&
!(ap->info.disk.state & (1<<MD_DISK_SYNC)))
ap->spares++;
diff --git a/Grow.c b/Grow.c
index 0571f5b0..800dbb55 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1728,7 +1728,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
if (st->ss->load_super(st, fd, NULL))
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
st->ss->free_super(st);
if (lseek64(fd,
@@ -1846,7 +1846,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
if (st->ss->load_super(st, fdlist[j], NULL))
/* FIXME should be this be an error */
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
st->ss->free_super(st);
offsets[j] = dinfo.data_offset * 512;
}
@@ -1908,7 +1908,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
if (fdlist[j] < 0) continue;
if (st->ss->load_super(st, fdlist[j], NULL))
continue;
- st->ss->getinfo_super(st, &dinfo);
+ st->ss->getinfo_super(st, &dinfo, NULL);
dinfo.reshape_progress = info->reshape_progress;
st->ss->update_super(st, &dinfo,
"_reshape_progress",
diff --git a/Incremental.c b/Incremental.c
index a60be47a..23f59800 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -156,7 +156,7 @@ int Incremental(char *devname, int verbose, int runstop,
close (dfd); dfd = -1;
memset(&info, 0, sizeof(info));
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
/* 3/ Check if there is a match in mdadm.conf */
array_list = conf_get_ident(NULL);
@@ -433,7 +433,7 @@ int Incremental(char *devname, int verbose, int runstop,
}
close(dfd2);
memset(&info2, 0, sizeof(info2));
- st2->ss->getinfo_super(st2, &info2);
+ st2->ss->getinfo_super(st2, &info2, NULL);
st2->ss->free_super(st2);
if (info.array.level != info2.array.level ||
memcmp(info.uuid, info2.uuid, 16) != 0 ||
@@ -623,7 +623,7 @@ static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
close(dfd);
continue;
}
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
st->ss->free_super(st);
close(dfd);
@@ -668,7 +668,7 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
close(dfd);
if (ok != 0)
continue;
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (!avail) {
avail = malloc(info.array.raid_disks);
if (!avail) {
@@ -685,7 +685,7 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
cnt++;
max_events = info.events;
avail[info.disk.raid_disk] = 2;
- st->ss->getinfo_super(st, bestinfo);
+ st->ss->getinfo_super(st, bestinfo, NULL);
} else if (info.events == max_events) {
cnt++;
avail[info.disk.raid_disk] = 2;
@@ -703,12 +703,12 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
if (avail[i])
avail[i]--;
avail[info.disk.raid_disk] = 2;
- st->ss->getinfo_super(st, bestinfo);
+ st->ss->getinfo_super(st, bestinfo, NULL);
} else { /* info.events much bigger */
cnt = 1; cnt1 = 0;
memset(avail, 0, info.disk.raid_disk);
max_events = info.events;
- st->ss->getinfo_super(st, bestinfo);
+ st->ss->getinfo_super(st, bestinfo, NULL);
}
}
st->ss->free_super(st);
@@ -944,7 +944,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
goto next;
}
- st2->ss->getinfo_super(st2, &info);
+ st2->ss->getinfo_super(st2, &info, NULL);
if (info.component_size > devsectors)
/* This partitioning doesn't fit in the device */
goto next;
diff --git a/Manage.c b/Manage.c
index acfec750..d9530a48 100644
--- a/Manage.c
+++ b/Manage.c
@@ -664,7 +664,7 @@ int Manage_subdevs(char *devname, int fd,
;
else if (st->sb) {
struct mdinfo mdi;
- st->ss->getinfo_super(st, &mdi);
+ st->ss->getinfo_super(st, &mdi, NULL);
st->ss->uuid_from_super(st, ouuid);
if ((mdi.disk.state & (1<<MD_DISK_ACTIVE)) &&
!(mdi.disk.state & (1<<MD_DISK_FAULTY)) &&
@@ -855,7 +855,7 @@ int Manage_subdevs(char *devname, int fd,
}
sra->array.level = LEVEL_CONTAINER;
/* Need to set data_offset and component_size */
- tst->ss->getinfo_super(tst, &new_mdi);
+ tst->ss->getinfo_super(tst, &new_mdi, NULL);
new_mdi.disk.major = disc.major;
new_mdi.disk.minor = disc.minor;
new_mdi.recovery_start = 0;
diff --git a/Query.c b/Query.c
index 8847be7e..f9857d6d 100644
--- a/Query.c
+++ b/Query.c
@@ -90,7 +90,7 @@ int Query(char *dev)
close(fd);
if (superror == 0) {
/* array might be active... */
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (st->ss == &super0) {
mddev = get_md_name(info.array.md_minor);
disc.number = info.disk.number;
diff --git a/managemon.c b/managemon.c
index bab03979..b6f99252 100644
--- a/managemon.c
+++ b/managemon.c
@@ -276,7 +276,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
*/
st2 = dup_super(st);
if (st2->ss->load_super(st2, dfd, NULL) == 0) {
- st2->ss->getinfo_super(st, &info);
+ st2->ss->getinfo_super(st, &info, NULL);
if (st->ss->compare_super(st, st2) == 0 &&
info.disk.raid_disk >= 0) {
/* Looks like a good member of array.
diff --git a/mapfile.c b/mapfile.c
index f334822b..b22772c4 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -408,7 +408,7 @@ void RebuildMap(void)
close(dfd);
if (ok != 0)
continue;
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (md->devnum >= 0)
path = map_dev(MD_MAJOR, md->devnum, 0);
else
diff --git a/mdadm.h b/mdadm.h
index 577d858e..6f7f06f5 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -534,8 +534,12 @@ extern struct superswitch {
* The particular device should be:
* The last device added by add_to_super
* The device the metadata was loaded from by load_super
+ * If 'map' is present, then it is an array raid_disks long
+ * (raid_disk must already be set and correct) and it is filled
+ * with 1 for slots that are thought to be active and 0 for slots which
+ * appear to be failed/missing.
*/
- void (*getinfo_super)(struct supertype *st, struct mdinfo *info);
+ void (*getinfo_super)(struct supertype *st, struct mdinfo *info, char *map);
/* Check if the given metadata is flagged as belonging to "this"
* host. 0 for 'no', 1 for 'yes', -1 for "Don't record homehost"
diff --git a/super-ddf.c b/super-ddf.c
index fca8edd7..e492b4e5 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;
+ }
+ }
}
diff --git a/super-gpt.c b/super-gpt.c
index 982b4e9b..116e5686 100644
--- a/super-gpt.c
+++ b/super-gpt.c
@@ -156,7 +156,7 @@ static int store_gpt(struct supertype *st, int fd)
return 0;
}
-static void getinfo_gpt(struct supertype *st, struct mdinfo *info)
+static void getinfo_gpt(struct supertype *st, struct mdinfo *info, char *map)
{
struct GPT *gpt = st->sb + 512;
struct GPT_part_entry *gpe = st->sb + 1024;
diff --git a/super-intel.c b/super-intel.c
index 38d0ae30..156585c4 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -741,7 +741,7 @@ static void print_imsm_disk(struct imsm_super *mpb, int index, __u32 reserved)
human_size(sz * 512));
}
-static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info);
+static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map);
static void examine_super_imsm(struct supertype *st, char *homehost)
{
@@ -762,7 +762,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
printf(" Orig Family : %08x\n", __le32_to_cpu(mpb->orig_family_num));
printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf(" UUID : %s\n", nbuf + 5);
sum = __le32_to_cpu(mpb->check_sum);
@@ -789,7 +789,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
struct imsm_dev *dev = __get_imsm_dev(mpb, i);
super->current_vol = i;
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
print_imsm_dev(dev, nbuf + 5, super->disks->index);
}
@@ -812,7 +812,7 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose)
return;
}
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf("ARRAY metadata=imsm UUID=%s\n", nbuf + 5);
}
@@ -829,13 +829,13 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose)
if (!super->anchor->num_raid_devs)
return;
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
super->current_vol = i;
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf1, ':');
printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n",
dev->volume, nbuf + 5, i, nbuf1 + 5);
@@ -849,7 +849,7 @@ static void export_examine_super_imsm(struct supertype *st)
struct mdinfo info;
char nbuf[64];
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf("MD_METADATA=imsm\n");
printf("MD_LEVEL=container\n");
@@ -862,7 +862,7 @@ static void detail_super_imsm(struct supertype *st, char *homehost)
struct mdinfo info;
char nbuf[64];
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf("\n UUID : %s\n", nbuf + 5);
}
@@ -871,7 +871,7 @@ static void brief_detail_super_imsm(struct supertype *st)
{
struct mdinfo info;
char nbuf[64];
- getinfo_super_imsm(st, &info);
+ getinfo_super_imsm(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf(" UUID=%s", nbuf + 5);
}
@@ -1434,13 +1434,14 @@ static int imsm_level_to_layout(int level)
return UnSet;
}
-static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
+static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, char *dmap)
{
struct intel_super *super = st->sb;
struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
struct imsm_map *map = get_imsm_map(dev, 0);
struct dl *dl;
char *devname;
+ int map_disks = info->array.raid_disks;
for (dl = super->disks; dl; dl = dl->next)
if (dl->raiddisk == info->disk.raid_disk)
@@ -1512,7 +1513,21 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
free(devname);
info->safe_mode_delay = 4000; /* 4 secs like the Matrix driver */
uuid_from_super_imsm(st, info->uuid);
-}
+
+ if (dmap) {
+ int i, j;
+ for (i=0; i<map_disks; i++) {
+ dmap[i] = 0;
+ if (i < info->array.raid_disks) {
+ struct imsm_disk *dsk;
+ j = get_imsm_disk_idx(dev, i);
+ dsk = get_imsm_disk(super, j);
+ if (dsk && (dsk->status & CONFIGURED_DISK))
+ dmap[i] = 1;
+ }
+ }
+ }
+}
/* check the config file to see if we can return a real uuid for this spare */
static void fixup_container_spare_uuid(struct mdinfo *inf)
@@ -1559,13 +1574,14 @@ static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
return NULL;
}
-static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
+static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map)
{
struct intel_super *super = st->sb;
struct imsm_disk *disk;
+ int map_disks = info->array.raid_disks;
if (super->current_vol >= 0) {
- getinfo_super_imsm_volume(st, info);
+ getinfo_super_imsm_volume(st, info, map);
return;
}
@@ -1664,6 +1680,14 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
memcpy(info->uuid, uuid_match_any, sizeof(int[4]));
fixup_container_spare_uuid(info);
}
+
+ /* I don't know how to compute 'map' on imsm, so use safe default */
+ if (map) {
+ int i;
+ for (i = 0; i < map_disks; i++)
+ map[i] = 1;
+ }
+
}
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
@@ -4353,7 +4377,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
this->next = rest;
super->current_vol = i;
- getinfo_super_imsm_volume(st, this);
+ getinfo_super_imsm_volume(st, this, NULL);
for (slot = 0 ; slot < map->num_members; slot++) {
unsigned long long recovery_start;
struct mdinfo *info_d;
diff --git a/super-mbr.c b/super-mbr.c
index 811ad1dc..0751e17c 100644
--- a/super-mbr.c
+++ b/super-mbr.c
@@ -148,7 +148,7 @@ static int store_mbr(struct supertype *st, int fd)
return 0;
}
-static void getinfo_mbr(struct supertype *st, struct mdinfo *info)
+static void getinfo_mbr(struct supertype *st, struct mdinfo *info, char *map)
{
struct MBR *sb = st->sb;
int i;
diff --git a/super0.c b/super0.c
index a650c3e6..b9d149eb 100644
--- a/super0.c
+++ b/super0.c
@@ -339,11 +339,12 @@ static void uuid_from_super0(struct supertype *st, int uuid[4])
}
}
-static void getinfo_super0(struct supertype *st, struct mdinfo *info)
+static void getinfo_super0(struct supertype *st, struct mdinfo *info, char *map)
{
mdp_super_t *sb = st->sb;
int working = 0;
int i;
+ int map_disks = info->array.raid_disks;
info->array.major_version = sb->major_version;
info->array.minor_version = sb->minor_version;
@@ -391,8 +392,12 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info)
if ((sb->disks[i].state & (1<<MD_DISK_SYNC)) &&
(sb->disks[i].raid_disk < (unsigned)info->array.raid_disks) &&
(sb->disks[i].state & (1<<MD_DISK_ACTIVE)) &&
- !(sb->disks[i].state & (1<<MD_DISK_FAULTY)))
+ !(sb->disks[i].state & (1<<MD_DISK_FAULTY))) {
working ++;
+ if (map && i < map_disks)
+ map[i] = 1;
+ } else if (map && i < map_disks)
+ map[i] = 0;
info->array.working_disks = working;
}
diff --git a/super1.c b/super1.c
index 24c18c0e..a52df645 100644
--- a/super1.c
+++ b/super1.c
@@ -558,12 +558,13 @@ static void uuid_from_super1(struct supertype *st, int uuid[4])
cuuid[i] = super->set_uuid[i];
}
-static void getinfo_super1(struct supertype *st, struct mdinfo *info)
+static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
{
struct mdp_superblock_1 *sb = st->sb;
int working = 0;
unsigned int i;
- int role;
+ unsigned int role;
+ unsigned int map_disks = info->array.raid_disks;
info->array.major_version = 1;
info->array.minor_version = st->minor_version;
@@ -629,10 +630,16 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info)
} else
info->reshape_active = 0;
+ if (map)
+ for (i=0; i<map_disks; i++)
+ map[i] = 0;
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
role = __le16_to_cpu(sb->dev_roles[i]);
- if (/*role == 0xFFFF || */role < info->array.raid_disks)
+ if (/*role == 0xFFFF || */role < (unsigned) info->array.raid_disks) {
working++;
+ if (map && role < map_disks)
+ map[role] = 1;
+ }
}
info->array.working_disks = working;
diff --git a/util.c b/util.c
index c9976218..27989636 100644
--- a/util.c
+++ b/util.c
@@ -500,7 +500,7 @@ int check_raid(int fd, char *name)
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
st->ss->free_super(st);
crtime = info.array.ctime;
level = map_num(pers, info.array.level);
@@ -1140,7 +1140,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
rv = ss->load_super(st, fd, NULL);
if (rv == 0) {
struct mdinfo info;
- st->ss->getinfo_super(st, &info);
+ st->ss->getinfo_super(st, &info, NULL);
if (bestsuper == -1 ||
besttime < info.array.ctime) {
bestsuper = i;