]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: store a link to current backup file in /run/mdadm or similar.
authorNeilBrown <neilb@suse.de>
Thu, 15 May 2014 04:23:16 +0000 (14:23 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 15 May 2014 04:23:16 +0000 (14:23 +1000)
Subsequent patch will allow the background part of "mdadm --grow" to
be run from systemd.  This can require the passing of a backup file
name.
To do this, store that name as a symlink in /run/mdadm (or MAP_DIR)
and look for it when appropriate.

It might be useful to also store the name across reboot, but that
would be a different patch.  We would need to use the uuid to identify
it, and store it in stable storage.

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

index 05ace561fb507bb6a557b3d15e6d35f18517400b..8977928534b6efb884b68824510caeac243eac17 100644 (file)
@@ -1680,6 +1680,8 @@ try_again:
                        pr_err(":%s has an active reshape - checking "
                               "if critical section needs to be restored\n",
                               chosen_name);
+               if (!c->backup_file)
+                       c->backup_file = locate_backup(content->sys_name);
                enable_fds(bestcnt/2);
                for (i = 0; i < bestcnt/2; i++) {
                        int j = best[i*2];
@@ -1892,7 +1894,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
                int spare = content->array.raid_disks + expansion;
                if (restore_backup(st, content,
                                   working,
-                                  spare, c->backup_file, c->verbose) == 1)
+                                  spare, &c->backup_file, c->verbose) == 1)
                        return 1;
 
                err = sysfs_set_str(content, NULL,
diff --git a/Grow.c b/Grow.c
index 6f556f65af78749c70c7287c298342ec42806c92..710c4c112b13d10829dad1111bbc0aada67527a0 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -41,7 +41,7 @@ int restore_backup(struct supertype *st,
                   struct mdinfo *content,
                   int working_disks,
                   int next_spare,
-                  char *backup_file,
+                  char **backup_filep,
                   int verbose)
 {
        int i;
@@ -49,6 +49,7 @@ int restore_backup(struct supertype *st,
        struct mdinfo *dev;
        int err;
        int disk_count = next_spare + working_disks;
+       char *backup_file = *backup_filep;
 
        dprintf("Called restore_backup()\n");
        fdlist = xmalloc(sizeof(int) * disk_count);
@@ -70,6 +71,11 @@ int restore_backup(struct supertype *st,
                        fdlist[next_spare++] = fd;
        }
 
+       if (!backup_file) {
+               backup_file = locate_backup(content->sys_name);
+               *backup_filep = backup_file;
+       }
+
        if (st->ss->external && st->ss->recover_backup)
                err = st->ss->recover_backup(st, content);
        else
@@ -886,6 +892,7 @@ int reshape_open_backup_file(char *backup_file,
                             long blocks,
                             int *fdlist,
                             unsigned long long *offsets,
+                            char *sys_name,
                             int restart)
 {
        /* Return 1 on success, 0 on any form of failure */
@@ -933,6 +940,12 @@ int reshape_open_backup_file(char *backup_file,
                return 0;
        }
 
+       if (!restart && strncmp(backup_file, MAP_DIR, strlen(MAP_DIR)) != 0) {
+               char *bu = make_backup(sys_name);
+               symlink(backup_file, bu);
+               free(bu);
+       }
+
        return 1;
 }
 
@@ -2843,6 +2856,10 @@ static int reshape_array(char *container, int fd, char *devname,
                               devname);
                        goto release;
                }
+
+               if (!backup_file)
+                       backup_file = locate_backup(sra->sys_name);
+
                goto started;
        }
        /* The container is frozen but the array may not be.
@@ -3172,6 +3189,7 @@ started:
                        if (!reshape_open_backup_file(backup_file, fd, devname,
                                                      (signed)blocks,
                                                      fdlist+d, offsets+d,
+                                                     sra->sys_name,
                                                      restart)) {
                                goto release;
                        }
@@ -3292,8 +3310,15 @@ started:
        free(fdlist);
        free(offsets);
 
-       if (backup_file && done)
+       if (backup_file && done) {
+               char *bul;
                unlink(backup_file);
+               bul = make_backup(sra->sys_name);
+               if (bul) {
+                       unlink(bul);
+                       free(bul);
+               }
+       }
        if (!done) {
                abort_reshape(sra);
                goto out;
@@ -4879,3 +4904,28 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
 
        return ret_val;
 }
+
+char *make_backup(char *name)
+{
+       char *base = "backup_file-";
+       int len;
+       char *fname;
+
+       len = strlen(MAP_DIR) + 1 + strlen(base) + strlen(name)+1;
+       fname = xmalloc(len);
+       sprintf(fname, "%s/%s%s", MAP_DIR, base, name);
+       return fname;
+}
+
+char *locate_backup(char *name)
+{
+       char *fl = make_backup(name);
+       struct stat stb;
+
+       if (stat(fl, &stb) == 0 &&
+           S_ISREG(stb.st_mode))
+               return fl;
+
+       free(fl);
+       return NULL;
+}
diff --git a/mdadm.h b/mdadm.h
index f6a614e193166262c0f6e38a9d4af8c0f360aa3e..a73d42a9407ded8a1a6c476410243a410f621905 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -585,9 +585,12 @@ extern int reshape_open_backup_file(char *backup,
                                    long blocks,
                                    int *fdlist,
                                    unsigned long long *offsets,
+                                   char *sysfs_name,
                                    int restart);
 extern unsigned long compute_backup_blocks(int nchunk, int ochunk,
                                           unsigned int ndata, unsigned int odata);
+extern char *locate_backup(char *name);
+extern char *make_backup(char *name);
 
 extern int save_stripes(int *source, unsigned long long *offsets,
                        int raid_disks, int chunk_size, int level, int layout,
@@ -1196,7 +1199,7 @@ extern int restore_backup(struct supertype *st,
                          struct mdinfo *content,
                          int working_disks,
                          int spares,
-                         char *backup_file,
+                         char **backup_filep,
                          int verbose);
 extern int Grow_continue_command(char *devname, int fd,
                                 char *backup_file, int verbose);