]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Make -IRs and --run work properly for containers.
authorNeilBrown <neilb@suse.de>
Fri, 13 Sep 2013 00:51:20 +0000 (10:51 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 13 Sep 2013 00:51:20 +0000 (10:51 +1000)
We really need to make sure assemble_container_content()
gets called to finished the assembly of these.

Reported-by: Francis Moreau <francis.moro@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Incremental.c
Manage.c
mdadm.c
mdadm.h

index bc85603d45e2b55f754f3fcccad41e2e73c06320..86b4c894b260c4b1d13eff1c3224775045badc46 100644 (file)
@@ -1817,7 +1817,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
                                working++;
                } else if (errno == EEXIST)
                        preexist++;
-       if (working + expansion == 0)
+       if (working + expansion == 0 && c->runstop <= 0)
                return 1;/* Nothing new, don't try to start */
 
        map_update(&map, fd2devnm(mdfd),
index f256b48de64d8185e1df6e54cf96dfbddb8abc57..1bb3638f92132bf38bd6a9fa784c879b2a544c9b 100644 (file)
@@ -44,7 +44,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
                     struct supertype *st, int verbose);
 
 static int Incremental_container(struct supertype *st, char *devname,
-                                struct context *c);
+                                struct context *c, char *only);
 
 int Incremental(char *devname, struct context *c,
                struct supertype *st)
@@ -138,7 +138,7 @@ int Incremental(char *devname, struct context *c,
                        if (map_lock(&map))
                                pr_err("failed to get "
                                       "exclusive lock on mapfile\n");
-                       rv = Incremental_container(st, devname, c);
+                       rv = Incremental_container(st, devname, c, NULL);
                        map_unlock(&map);
                        return rv;
                }
@@ -478,7 +478,7 @@ int Incremental(char *devname, struct context *c,
                close(mdfd);
                sysfs_free(sra);
                if (!rv)
-                       rv = Incremental_container(st, chosen_name, c);
+                       rv = Incremental_container(st, chosen_name, c, NULL);
                map_unlock(&map);
                if (rv == 1)
                        /* Don't fail the whole -I if a subarray didn't
@@ -1278,7 +1278,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
        return rv;
 }
 
-int IncrementalScan(int verbose, char *devnm)
+int IncrementalScan(struct context *c, char *devnm)
 {
        /* look at every device listed in the 'map' file.
         * If one is found that is not running then:
@@ -1290,10 +1290,13 @@ int IncrementalScan(int verbose, char *devnm)
        struct map_ent *me;
        struct mddev_ident *devs, *mddev;
        int rv = 0;
+       char container[32];
+       char *only = NULL;
 
        map_read(&mapl);
        devs = conf_get_ident(NULL);
 
+restart:
        for (me = mapl ; me ; me = me->next) {
                mdu_array_info_t array;
                mdu_bitmap_file_t bmf;
@@ -1302,10 +1305,42 @@ int IncrementalScan(int verbose, char *devnm)
 
                if (devnm && strcmp(devnm, me->devnm) != 0)
                        continue;
+               if (devnm && me->metadata[0] == '/') {
+                       char *sl;
+                       /* member array, need to work on container */
+                       strncpy(container, me->metadata+1, 32);
+                       container[31] = 0;
+                       sl = strchr(container, '/');
+                       if (sl)
+                               *sl = 0;
+                       only = devnm;
+                       devnm = container;
+                       goto restart;
+               }
                mdfd = open_dev(me->devnm);
 
                if (mdfd < 0)
                        continue;
+               if (!isdigit(me->metadata[0])) {
+                       /* must be a container */
+                       struct supertype *st = super_by_fd(mdfd, NULL);
+                       int ret = 0;
+                       struct map_ent *map = NULL;
+                       if (st)
+                               st->ignore_hw_compat = 1;
+                       if (st && st->ss->load_container)
+                               ret = st->ss->load_container(st, mdfd, NULL);
+                       close(mdfd);
+                       if (!ret && st->ss->container_content) {
+                               if (map_lock(&map))
+                                       pr_err("failed to get exclusive lock on mapfile\n");
+                               ret = Incremental_container(st, me->path, c, only);
+                               map_unlock(&map);
+                       }
+                       if (ret)
+                               rv = 1;
+                       continue;
+               }
                if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
                    errno != ENODEV) {
                        close(mdfd);
@@ -1330,7 +1365,7 @@ int IncrementalScan(int verbose, char *devnm)
                                        close(bmfd);
                                }
                        }
-                       if (verbose >= 0) {
+                       if (c->verbose >= 0) {
                                if (added == 0)
                                        pr_err("Added bitmap %s to %s\n",
                                               mddev->bitmap_file, me->path);
@@ -1346,7 +1381,7 @@ int IncrementalScan(int verbose, char *devnm)
                if (sra) {
                        if (sysfs_set_str(sra, NULL,
                                          "array_state", "read-auto") == 0) {
-                               if (verbose >= 0)
+                               if (c->verbose >= 0)
                                        pr_err("started array %s\n",
                                               me->path ?: me->devnm);
                        } else {
@@ -1387,7 +1422,7 @@ static char *container2devname(char *devname)
 }
 
 static int Incremental_container(struct supertype *st, char *devname,
-                                struct context *c)
+                                struct context *c, char *only)
 {
        /* Collect the contents of this container and for each
         * array, choose a device name and assemble the array.
@@ -1458,7 +1493,7 @@ static int Incremental_container(struct supertype *st, char *devname,
                                strcpy(chosen_name, mp->path);
                        else
                                strcpy(chosen_name, mp->devnm);
-               } else {
+               } else if (!only) {
 
                        /* Check in mdadm.conf for container == devname and
                         * member == ra->text_version after second slash.
@@ -1515,6 +1550,8 @@ static int Incremental_container(struct supertype *st, char *devname,
                                            trustworthy,
                                            chosen_name);
                }
+               if (only && (!mp || strcmp(mp->devnm, only) != 0))
+                       continue;
 
                if (mdfd < 0) {
                        pr_err("failed to open %s: %s.\n",
index 910caa6662162cabb5d51e92f3fcb3b0c5ce11cb..c8276ca1f72d40baa76535b8f0dace52ba86ab12 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -170,7 +170,7 @@ static void remove_devices(char *devnm, char *path)
        free(path2);
 }
 
-int Manage_run(char *devname, int fd, int verbose)
+int Manage_run(char *devname, int fd, struct context *c)
 {
        /* Run the array.  Array must already be configured
         *  Requires >= 0.90.0
@@ -187,7 +187,7 @@ int Manage_run(char *devname, int fd, int verbose)
                return 1;
        }
        strcpy(nm, nmp);
-       return IncrementalScan(verbose, nm);
+       return IncrementalScan(c, nm);
 }
 
 int Manage_stop(char *devname, int fd, int verbose, int will_retry)
diff --git a/mdadm.c b/mdadm.c
index 1ada6079272885bc8bec8751ffbb66a5b68e3f12..f55a035ca8af4fa29a6fdbd4cc13e7301f63ba23 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
                if (!rv && c.readonly < 0)
                        rv = Manage_ro(devlist->devname, mdfd, c.readonly);
                if (!rv && c.runstop > 0)
-                       rv = Manage_run(devlist->devname, mdfd, c.verbose);
+                       rv = Manage_run(devlist->devname, mdfd, &c);
                if (!rv && c.runstop < 0)
                        rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
                break;
@@ -1535,7 +1535,7 @@ int main(int argc, char *argv[])
                                pr_err("--incremental --scan --fail not supported.\n");
                                break;
                        }
-                       rv = IncrementalScan(c.verbose, NULL);
+                       rv = IncrementalScan(&c, NULL);
                }
                if (!devlist) {
                        if (!rebuild_map && !c.scan) {
@@ -1804,7 +1804,8 @@ static int misc_list(struct mddev_dev *devlist,
                if (mdfd>=0) {
                        switch(dv->disposition) {
                        case 'R':
-                               rv |= Manage_run(dv->devname, mdfd, c->verbose); break;
+                               c->runstop = 1;
+                               rv |= Manage_run(dv->devname, mdfd, c); break;
                        case 'S':
                                rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break;
                        case 'o':
diff --git a/mdadm.h b/mdadm.h
index 2eca60321aa3e86a0dce421a3c09c200c06949be..c90fe105b872fe145f86451f042845febde36903 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1171,7 +1171,7 @@ struct stat64;
 extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s);
 
 extern int Manage_ro(char *devname, int fd, int readonly);
-extern int Manage_run(char *devname, int fd, int quiet);
+extern int Manage_run(char *devname, int fd, struct context *c);
 extern int Manage_stop(char *devname, int fd, int quiet,
                       int will_retry);
 extern int Manage_subdevs(char *devname, int fd,
@@ -1237,7 +1237,7 @@ extern int WaitClean(char *dev, int sock, int verbose);
 extern int Incremental(char *devname, struct context *c,
                       struct supertype *st);
 extern void RebuildMap(void);
-extern int IncrementalScan(int verbose, char *devnm);
+extern int IncrementalScan(struct context *c, char *devnm);
 extern int IncrementalRemove(char *devname, char *path, int verbose);
 extern int CreateBitmap(char *filename, int force, char uuid[16],
                        unsigned long chunksize, unsigned long daemon_sleep,