]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add subarray field to supertype.
authorNeil Brown <neilb@suse.de>
Sat, 12 Jul 2008 10:27:38 +0000 (20:27 +1000)
committerNeil Brown <neilb@suse.de>
Sat, 12 Jul 2008 10:27:38 +0000 (20:27 +1000)
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
Manage.c
mdadm.h
super-ddf.c
super-intel.c
super0.c
super1.c
util.c

index eb67968b377613d3536fbcd032507570b8429168..495cf39a575c7c130287355efe7238fb6b6c11b6 100644 (file)
--- 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;
index 003d81573fff87ce3c498a87bfa54badbe5fe4d0..9197eea5358970fffc196b8cc729b68ba17aa1ab 100644 (file)
--- 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 97569fad0711dd5d5fddbf1fb3ccd5b7c841f072..c728badcdcc1f4dca8ef60dac411617d75434db0 100644 (file)
--- 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);
index 5644aeab9e32a490106c9e8a92db0b846f963d54..378a5d2b4c75995e14127d2a4cf2b866466a712e 100644 (file)
@@ -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;
index 33245299ae3d39ba862635f3b912e9d76cf65a38..30b2962688a70aeca5144927914af63fabe32e80 100644 (file)
@@ -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) {
index 6bb5a7eff2cef87418b96b29b6165e6f3d4cc29a..9984712614d954eed220ede438a95a2ed07729fb 100644 (file)
--- 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;
 
index ae6c8a371f315e72f0e3d9d8177f54869e0d67d9..a6a308a60a286a8eee5e88e6e799914bbd9d2487 100644 (file)
--- 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 08c6bb0b0e977acbb8c2bba724a96f456b1e58cd..3a5daa265284012702cc16c2fae4ea9cdd745846 100644 (file)
--- 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;