From 4968025884885c078336e231f8f117e7e50618ba Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 8 Mar 2011 17:14:00 +1100 Subject: [PATCH] Run Grow_restart/Grow_continue when assembling the content of a container. 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 --- Assemble.c | 51 ++++++++++++++++++++++++++++++++++++++------------- Incremental.c | 2 +- mdadm.h | 3 ++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/Assemble.c b/Assemble.c index ee5fcec4..20c27eb7 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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; idevs; 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: diff --git a/Incremental.c b/Incremental.c index 91359f4e..300bdca7 100644 --- a/Incremental.c +++ b/Incremental.c @@ -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 a1be8560..db151753 100644 --- 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, -- 2.47.2