From f7e7067b47d2ca9994f9222dfa5833ac84ce3b22 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sat, 12 Jul 2008 20:27:38 +1000 Subject: [PATCH] Add subarray field to supertype. When loading the metadata for a subarray (super_by_fd), we set ->subarray to be the name read from md/metadata_version so that getinfo_super can return info about the correct array. With this we can differentiate between a container and an array within the container by looking at ->subarray[0]. --- Create.c | 6 +++--- Manage.c | 4 ++-- mdadm.h | 2 +- super-ddf.c | 12 ++++++++++++ super-intel.c | 6 ++++++ super0.c | 3 +++ super1.c | 3 +++ util.c | 37 +++++++++++++++++++++++++++++-------- 8 files changed, 59 insertions(+), 14 deletions(-) diff --git a/Create.c b/Create.c index eb67968b..495cf39a 100644 --- a/Create.c +++ b/Create.c @@ -550,7 +550,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, char ver[100]; strcat(strcpy(ver, "external:"), info.text_version); - if (st->ss->external == 2) { + if (st->ss->external && st->subarray[0]) { /* member */ /* When creating a member, we need to be careful @@ -651,7 +651,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, strcasecmp(dv->devname, "missing")==0) continue; - if (st->ss->external == 2) + if (st->ss->external && st->subarray[0]) fd = open(dv->devname, O_RDWR, 0); else fd = open(dv->devname, O_RDWR|O_EXCL,0); @@ -732,7 +732,7 @@ int Create(struct supertype *st, char *mddev, int mdfd, } if (verbose >= 0) fprintf(stderr, Name ": array %s started.\n", mddev); - if (st->ss->external == 2) { + if (st->ss->external && st->subarray[0]) { if (need_mdmon) { int dn = st->container_dev; int i; diff --git a/Manage.c b/Manage.c index 003d8157..9197eea5 100644 --- a/Manage.c +++ b/Manage.c @@ -354,7 +354,7 @@ int Manage_subdevs(char *devname, int fd, return 1; case 'a': /* add the device */ - if (tst == &supertype_container_member) { + if (tst->subarray[0]) { fprintf(stderr, Name ": Cannot add disks to a" " \'member\' array, perform this" " operation on the parent container\n"); @@ -551,7 +551,7 @@ int Manage_subdevs(char *devname, int fd, case 'r': /* hot remove */ - if (tst == &supertype_container_member) { + if (tst->subarray[0]) { fprintf(stderr, Name ": Cannot remove disks from a" " \'member\' array, perform this" " operation on the parent container\n"); diff --git a/mdadm.h b/mdadm.h index 97569fad..c728badc 100644 --- a/mdadm.h +++ b/mdadm.h @@ -563,6 +563,7 @@ struct supertype { int minor_version; int max_devs; int container_dev; /* devnum of container */ + char subarray[32]; /* name of array inside container */ void *sb; void *info; @@ -582,7 +583,6 @@ struct supertype { }; -extern struct supertype supertype_container_member; extern struct supertype *super_by_fd(int fd); extern struct supertype *guess_super(int fd); extern struct supertype *dup_super(struct supertype *st); diff --git a/super-ddf.c b/super-ddf.c index 5644aeab..378a5d2b 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -733,6 +733,8 @@ static int load_super_ddf(struct supertype *st, int fd, if (load_super_ddf_all(st, fd, &st->sb, devname, 1) == 0) return 0; #endif + if (st->subarray[0]) + return 1; /* FIXME Is this correct */ if (get_dev_size(fd, devname, &dsize) == 0) return 1; @@ -1826,6 +1828,7 @@ static int init_super_ddf_bvd(struct supertype *st, vcl = malloc(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512); vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe]; vcl->vcnum = venum; + sprintf(st->subarray, "%d", venum); vcl->block_sizes = NULL; /* FIXME not for CONCAT */ vc = &vcl->conf; @@ -2449,6 +2452,15 @@ static int load_super_ddf_all(struct supertype *st, int fd, seq = load_ddf_local(dfd, super, NULL, keep_fd); if (!keep_fd) close(dfd); } + if (st->subarray[0]) { + struct vcl *v; + + for (v = super->conflist; v; v = v->next) + if (v->vcnum == atoi(st->subarray)) + super->newconf = v; + if (!super->newconf) + return 1; + } *sbp = super; if (st->ss == NULL) { st->ss = &super_ddf_container; diff --git a/super-intel.c b/super-intel.c index 33245299..30b29626 100644 --- a/super-intel.c +++ b/super-intel.c @@ -980,6 +980,10 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp, close(dfd); } + if (st->subarray[0]) { + /* FIXME */ + } + *sbp = super; if (st->ss == NULL) { st->ss = &super_imsm_container; @@ -1001,6 +1005,8 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) if (load_super_imsm_all(st, fd, &st->sb, devname, 1) == 0) return 0; #endif + if (st->subarray[0]) + return 1; /* FIXME */ super = alloc_super(0); if (!super) { diff --git a/super0.c b/super0.c index 6bb5a7ef..99847126 100644 --- a/super0.c +++ b/super0.c @@ -783,6 +783,9 @@ static int load_super0(struct supertype *st, int fd, char *devname) free_super0(st); + if (st->subarray[0]) + return 1; + if (!get_dev_size(fd, devname, &dsize)) return 1; diff --git a/super1.c b/super1.c index ae6c8a37..a6a308a6 100644 --- a/super1.c +++ b/super1.c @@ -1065,6 +1065,9 @@ static int load_super1(struct supertype *st, int fd, char *devname) free_super1(st); + if (st->subarray[0]) + return 1; + if (st->ss == NULL || st->minor_version == -1) { int bestvers = -1; struct supertype tst; diff --git a/util.c b/util.c index 08c6bb0b..3a5daa26 100644 --- a/util.c +++ b/util.c @@ -788,8 +788,6 @@ struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, N #if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) -struct supertype supertype_container_member; - struct supertype *super_by_fd(int fd) { mdu_array_info_t array; @@ -800,6 +798,7 @@ struct supertype *super_by_fd(int fd) char *verstr; char version[20]; int i; + char *subarray = NULL; sra = sysfs_read(fd, 0, GET_VERSION); @@ -819,16 +818,37 @@ struct supertype *super_by_fd(int fd) sprintf(version, "%d.%d", vers, minor); verstr = version; } - if (minor == -2 && verstr[0] == '/') - st = &supertype_container_member; - else - for (i = 0; st == NULL && superlist[i] ; i++) - st = superlist[i]->match_metadata_desc(verstr); + if (minor == -2 && verstr[0] == '/') { + char *dev = verstr+1; + subarray = strchr(dev, '/'); + int devnum; + if (subarray) + *subarray++ = '\0'; + if (strncmp(dev, "md_d", 4) == 0) + devnum = -1-atoi(dev+4); + else + devnum = atoi(dev+2); + subarray = strdup(subarray); + if (sra) + sysfs_free(sra); + sra = sysfs_read(-1, devnum, GET_VERSION); + verstr = sra->text_version ? : "-no-metadata-"; + } + + for (i = 0; st == NULL && superlist[i] ; i++) + st = superlist[i]->match_metadata_desc(verstr); if (sra) sysfs_free(sra); - if (st) + if (st) { st->sb = NULL; + if (subarray) { + strncpy(st->subarray, subarray, 32); + st->subarray[31] = 0; + free(subarray); + } else + st->subarray[0] = 0; + } return st; } #endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */ @@ -845,6 +865,7 @@ struct supertype *dup_super(struct supertype *orig) st->ss = orig->ss; st->max_devs = orig->max_devs; st->minor_version = orig->minor_version; + strcpy(st->subarray, orig->subarray); st->sb = NULL; st->info = NULL; return st; -- 2.39.2