]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Run Grow_restart/Grow_continue when assembling the content of a container.
authorNeilBrown <neilb@suse.de>
Tue, 8 Mar 2011 06:14:00 +0000 (17:14 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 8 Mar 2011 06:14:00 +0000 (17:14 +1100)
As containers can now grow, we need to use both Grow_restart (to
replay any backup-file) and Grow_continue when assembling the content
of a container.

Note that we don't pass a backup-file when doing incremental assembly.
If such is needed in that case, the assembly will fail.

To restart such arrays, explicit assembly is required.

Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Incremental.c
mdadm.h

index ee5fcec46b0223ed32f20d7a2482aa290ba3f26b..20c27eb7e76b2d6e38ff09037035f3812838f117 100644 (file)
@@ -698,18 +698,9 @@ int Assemble(struct supertype *st, char *mddev,
                /* This is a member of a container.  Try starting the array. */
                int err;
                err = assemble_container_content(st, mdfd, content, runstop,
-                                                chosen_name, verbose);
-               if (!err) {
-                       /* check if reshape of external metadata
-                        * is in progress
-                        * and it is need to be monitored by mdadm
-                        */
-                       if (content->reshape_active)
-                               err = Grow_continue(mdfd, st, content,
-                                                   backup_file);
-               }
+                                                chosen_name, verbose,
+                                                backup_file);
                close(mdfd);
-
                return err;
        }
 #endif
@@ -1513,7 +1504,8 @@ int Assemble(struct supertype *st, char *mddev,
 #ifndef MDASSEMBLE
 int assemble_container_content(struct supertype *st, int mdfd,
                               struct mdinfo *content, int runstop,
-                              char *chosen_name, int verbose)
+                              char *chosen_name, int verbose,
+                              char *backup_file)
 {
        struct mdinfo *dev, *sra;
        int working = 0, preexist = 0;
@@ -1550,7 +1542,40 @@ int assemble_container_content(struct supertype *st, int mdfd,
                        content->array.working_disks) {
                int err;
 
-               switch(content->array.level) {
+               if (content->reshape_active) {
+                       int spare = content->array.raid_disks + expansion;
+                       int i;
+                       int *fdlist = malloc(sizeof(int) *
+                                            (working + expansion
+                                             + content->array.raid_disks));
+                       for (i=0; i<spare; i++)
+                               fdlist[i] = -1;
+                       for (dev = content->devs; dev; dev = dev->next) {
+                               int fd = open_dev(makedev(dev->disk.major,
+                                                         dev->disk.minor));
+                               if (dev->disk.raid_disk >= 0)
+                                       fdlist[dev->disk.raid_disk] = fd;
+                               else
+                                       fdlist[spare++] = fd;
+                       }
+                       err = Grow_restart(st, content, fdlist, spare,
+                                          backup_file, verbose > 0);
+                       while (spare > 0) {
+                               spare--;
+                               if (fdlist[spare] >= 0)
+                                       close(fdlist[spare]);
+                       }
+                       if (err) {
+                               fprintf(stderr, Name ": Failed to restore critical"
+                                       " section for reshape - sorry.\n");
+                               if (!backup_file)
+                                       fprintf(stderr, Name ":  Possibly you need"
+                                               " to specify a --backup-file\n");
+                               return 1;
+                       }
+
+                       err = Grow_continue(mdfd, st, content, backup_file);
+               } else switch(content->array.level) {
                case LEVEL_LINEAR:
                case LEVEL_MULTIPATH:
                case 0:
index 91359f4e93b453fedbf1575401dc0880c711135c..300bdca7a35ff4f800cadf03277ef2715f675306 100644 (file)
@@ -1555,7 +1555,7 @@ static int Incremental_container(struct supertype *st, char *devname,
                }
 
                assemble_container_content(st, mdfd, ra, runstop,
-                                          chosen_name, verbose);
+                                          chosen_name, verbose, NULL);
                close(mdfd);
        }
 
diff --git a/mdadm.h b/mdadm.h
index a1be8560631c2fa5f17e0792ab7793667ffe172c..db151753aed99a0dc4d7710f6036b14da29cc92c 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1129,7 +1129,8 @@ extern int flush_metadata_updates(struct supertype *st);
 extern void append_metadata_update(struct supertype *st, void *buf, int len);
 extern int assemble_container_content(struct supertype *st, int mdfd,
                                      struct mdinfo *content, int runstop,
-                                     char *chosen_name, int verbose);
+                                     char *chosen_name, int verbose,
+                                     char *backup_file);
 extern struct mdinfo *container_choose_spares(struct supertype *st,
                                              unsigned long long min_size,
                                              struct domainlist *domlist,