]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add continue option to grow command
authorAdam Kwolek <adam.kwolek@intel.com>
Sun, 2 Oct 2011 22:26:48 +0000 (09:26 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 2 Oct 2011 22:26:48 +0000 (09:26 +1100)
To allow for reshape continuation '--continue' option is added
to grow command.
Function that will be executed in grow-continue case doesn't require
information about reshape geometry. All required information are read
from metadata.
For external metadata reshape can be run for monitored array/container
only. In case when array/container is not monitored run mdmon for it.

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c
ReadMe.c
mdadm.c
mdadm.h

diff --git a/Grow.c b/Grow.c
index a7e528fa55bcf8818ac0c508afc450d90b96afbf..fad4dc88f337f59314bc1b916a0d97348f65ff9f 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -3632,6 +3632,137 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
        return 1;
 }
 
+int Grow_continue_command(char *devname, int fd,
+                         char *backup_file, int verbose)
+{
+       int ret_val = 0;
+       struct supertype *st = NULL;
+       struct mdinfo *content = NULL;
+       struct mdinfo array;
+       char *subarray = NULL;
+       struct mdinfo *cc = NULL;
+       struct mdstat_ent *mdstat = NULL;
+       char buf[40];
+       int cfd = -1;
+       int fd2 = -1;
+
+       dprintf("Grow continue from command line called for %s\n",
+               devname);
+
+       st = super_by_fd(fd, &subarray);
+       if (!st || !st->ss) {
+               fprintf(stderr,
+                       Name ": Unable to determine metadata format for %s\n",
+                       devname);
+               return 1;
+       }
+       dprintf("Grow continue is run for ");
+       if (st->ss->external == 0) {
+               dprintf("native array (%s)\n", devname);
+               if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
+                       fprintf(stderr, Name ": %s is not an active md array -"
+                               " aborting\n", devname);
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+               content = &array;
+               sysfs_init(content, fd, st->devnum);
+       } else {
+               int container_dev;
+
+               if (subarray) {
+                       dprintf("subarray (%s)\n", subarray);
+                       container_dev = st->container_dev;
+                       cfd = open_dev_excl(st->container_dev);
+               } else {
+                       container_dev = st->devnum;
+                       close(fd);
+                       cfd = open_dev_excl(st->devnum);
+                       dprintf("container (%i)\n", container_dev);
+                       fd = cfd;
+               }
+               if (cfd < 0) {
+                       fprintf(stderr, Name ": Unable to open container "
+                               "for %s\n", devname);
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+               fmt_devname(buf, container_dev);
+
+               /* find in container array under reshape
+                */
+               ret_val = st->ss->load_container(st, cfd, NULL);
+               if (ret_val) {
+                       fprintf(stderr,
+                               Name ": Cannot read superblock for %s\n",
+                               devname);
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+
+               cc = st->ss->container_content(st, NULL);
+               for (content = cc; content ; content = content->next) {
+                       char *array;
+
+                       if (content->reshape_active == 0)
+                               continue;
+
+                       array = strchr(content->text_version+1, '/')+1;
+                       mdstat = mdstat_by_subdev(array, container_dev);
+                       if (!mdstat)
+                               continue;
+                       break;
+               }
+               if (!content) {
+                       fprintf(stderr,
+                               Name ": Unable to determine reshaped "
+                               "array for %s\n", devname);
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+               fd2 = open_dev(mdstat->devnum);
+               if (fd2 < 0) {
+                       fprintf(stderr, Name ": cannot open (md%i)\n",
+                               mdstat->devnum);
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+
+               sysfs_init(content, fd2, mdstat->devnum);
+
+               /* start mdmon in case it is not running
+                */
+               if (!mdmon_running(container_dev))
+                       start_mdmon(container_dev);
+               ping_monitor(buf);
+
+               if (mdmon_running(container_dev))
+                       st->update_tail = &st->updates;
+               else {
+                       fprintf(stderr, Name ":  No mdmon found. "
+                               "Grow cannot continue.\n");
+                       ret_val = 1;
+                       goto Grow_continue_command_exit;
+               }
+       }
+
+       /* continue reshape
+        */
+       ret_val = Grow_continue(fd, st, content, backup_file, 0);
+
+Grow_continue_command_exit:
+       if (fd2 > -1)
+               close(fd2);
+       if (cfd > -1)
+               close(cfd);
+       st->ss->free_super(st);
+       free_mdstat(mdstat);
+       sysfs_free(cc);
+       free(subarray);
+
+       return ret_val;
+}
+
 int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
                  char *backup_file, int freeze_reshape)
 {
index 89dd7af5ee453393ba3a34769369b97e7330b740..25426d326e2e263606f4590fd7425fcff1f1c1e7 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -191,6 +191,7 @@ struct option long_options[] = {
     {"backup-file", 1,0, BackupFile},
     {"invalid-backup",0,0,InvalidBackup},
     {"array-size", 1, 0, 'Z'},
+    {"continue", 0, 0, Continue},
 
     /* For Incremental */
     {"rebuild-map", 0, 0, RebuildMapOpt},
diff --git a/mdadm.c b/mdadm.c
index af182d09e50308c721006f529147c4d417e4aa29..ebf1c46eab78204fbd8a626cc43b3d1cf97d5e56 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -74,6 +74,7 @@ int main(int argc, char *argv[])
        int export = 0;
        int assume_clean = 0;
        char *symlinks = NULL;
+       int grow_continue = 0;
        /* autof indicates whether and how to create device node.
         * bottom 3 bits are style.  Rest (when shifted) are number of parts
         * 0  - unset
@@ -996,6 +997,11 @@ int main(int argc, char *argv[])
                        backup_file = optarg;
                        continue;
 
+               case O(GROW, Continue):
+                       /* Continue interrupted grow
+                        */
+                       grow_continue = 1;
+                       continue;
                case O(ASSEMBLE, InvalidBackup):
                        /* Acknowledge that the backupfile is invalid, but ask
                         * to continue anyway
@@ -1649,7 +1655,11 @@ int main(int argc, char *argv[])
                                delay = DEFAULT_BITMAP_DELAY;
                        rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
                                            bitmap_chunk, delay, write_behind, force);
-               } else if (size >= 0 || raiddisks != 0 || layout_str != NULL
+               } else if (grow_continue)
+                       rv = Grow_continue_command(devlist->devname,
+                                                  mdfd, backup_file,
+                                                  verbose);
+               else if (size >= 0 || raiddisks != 0 || layout_str != NULL
                           || chunk != 0 || level != UnSet) {
                        rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
                                          size, level, layout_str, chunk, raiddisks,
diff --git a/mdadm.h b/mdadm.h
index 4687a21040ee536ad0e0170dfcd1b0371bceb488..989d56385852a360642ce3d9fb78121db4ff4834 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -314,6 +314,7 @@ enum special_options {
        InvalidBackup,
        UdevRules,
        FreezeReshape,
+       Continue,
 };
 
 /* structures read from config file */
@@ -1041,6 +1042,8 @@ extern int restore_backup(struct supertype *st,
                          int spares,
                          char *backup_file,
                          int verbose);
+extern int Grow_continue_command(char *devname, int fd,
+                                char *backup_file, int verbose);
 
 extern int Assemble(struct supertype *st, char *mddev,
                    struct mddev_ident *ident,