From f98d41ddb4ac543176f33454ceb70983109272d9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 31 Jul 2009 17:11:41 -0700 Subject: [PATCH] fix RebuildMap() to retrieve 'subarray' info RebuildMap falsely returns container info for member arrays. Retrieving the subarray and container_dev details prior to ->load_super() changes the result from: md127 imsm 082c6371:74b5ce03:64972e41:6b0860d5 /dev/md/imsm md126 imsm 082c6371:74b5ce03:64972e41:6b0860d5 /dev/md/vol0 ...to: md126 /md127/0 3e03aee2:78c3c593:1e8ecaf0:eefb53ed /dev/md/vol0 md127 imsm 082c6371:74b5ce03:64972e41:6b0860d5 /dev/md/imsm Reported-by: Ignacy Kasperowicz Signed-off-by: Dan Williams --- mapfile.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/mapfile.c b/mapfile.c index 601c4cc..a3038be 100644 --- a/mapfile.c +++ b/mapfile.c @@ -297,6 +297,34 @@ struct map_ent *map_by_name(struct map_ent **map, char *name) return NULL; } +/* sets the proper subarray and container_dev according to the metadata + * version super_by_fd does this automatically, this routine is meant as + * a supplement for guess_super() + */ +static void set_member_info(struct supertype *st, struct mdstat_ent *ent) +{ + char version[strlen(ent->metadata_version)+1]; + + st->subarray[0] = '\0'; + + if (strncmp(ent->metadata_version, "external:", 9) != 0) + return; + + strcpy(version, ent->metadata_version); + + if (is_subarray(&version[9])) { + char *subarray = strrchr(version, '/'); + char *name = &version[10]; + + if (!subarray) + return; + *subarray++ = '\0'; + + st->container_dev = devname2devnum(name); + strncpy(st->subarray, subarray, sizeof(st->subarray)); + } +} + void RebuildMap(void) { struct mdstat_ent *mdstat = mdstat_read(0, 0); @@ -337,8 +365,10 @@ void RebuildMap(void) st = guess_super(dfd); if ( st == NULL) ok = -1; - else + else { + set_member_info(st, md); ok = st->ss->load_super(st, dfd, NULL); + } close(dfd); if (ok != 0) continue;