diff --git a/Assemble.c b/Assemble.c index 05ace56..8977928 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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 6f556f6..710c4c1 100644 --- 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 f6a614e..a73d42a 100644 --- 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);