From 87f26d14f75cf565a5885b2a3426499a48987ac3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 1 Dec 2010 11:47:32 +1100 Subject: [PATCH] Assemble: allow an array undergoing reshape to be started without backup file Though not having the proper backup file can cause data corruption, it is not enough to justify not being able to start the array at all. So allow "--invalid-backup" to be specified which says "just continue even if a backup cannot be restored". Signed-off-by: NeilBrown --- Assemble.c | 15 ++++++++++++--- Grow.c | 5 +++++ ReadMe.c | 1 + mdadm.8.in | 15 +++++++++++++-- mdadm.c | 33 ++++++++++++++++++++++----------- mdadm.h | 4 +++- 6 files changed, 56 insertions(+), 17 deletions(-) diff --git a/Assemble.c b/Assemble.c index dc5ddd5..ac489e8 100644 --- a/Assemble.c +++ b/Assemble.c @@ -133,7 +133,8 @@ static int ident_matches(struct mddev_ident *ident, int Assemble(struct supertype *st, char *mddev, struct mddev_ident *ident, - struct mddev_dev *devlist, char *backup_file, + struct mddev_dev *devlist, + char *backup_file, int invalid_backup, int readonly, int runstop, char *update, char *homehost, int require_homehost, int verbose, int force) @@ -1097,8 +1098,16 @@ int Assemble(struct supertype *st, char *mddev, } else fdlist[i] = -1; } - if (!err) - err = Grow_restart(st, content, fdlist, bestcnt, backup_file, verbose > 0); + if (!err) { + err = Grow_restart(st, content, fdlist, bestcnt, + backup_file, verbose > 0); + if (err && invalid_backup) { + if (verbose > 0) + fprintf(stderr, Name ": continuing" + " without restoring backup\n"); + err = 0; + } + } while (i>0) { i--; if (fdlist[i]>=0) close(fdlist[i]); diff --git a/Grow.c b/Grow.c index 13c6028..0515cfa 100644 --- a/Grow.c +++ b/Grow.c @@ -2665,6 +2665,11 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, bsb.devstart2 = blocks; backup_fd = open(backup_file, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR); + if (backup_fd < 0) { + fprintf(stderr, Name ": Cannot open backup file %s\n", + backup_file ?: "- no backup-file given"); + return 1; + } backup_list[0] = backup_fd; backup_offsets[0] = 8 * 512; fds = malloc(odisks * sizeof(fds[0])); diff --git a/ReadMe.c b/ReadMe.c index 5dae87a..5714849 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -190,6 +190,7 @@ struct option long_options[] = { /* For Grow */ {"backup-file", 1,0, BackupFile}, + {"invalid-backup",0,0,InvalidBackup}, {"array-size", 1, 0, 'Z'}, /* For Incremental */ diff --git a/mdadm.8.in b/mdadm.8.in index 4fc9439..8a75e25 100644 --- a/mdadm.8.in +++ b/mdadm.8.in @@ -884,13 +884,24 @@ bitmap, there is no need to specify this when assembling the array. .BR \-\-backup\-file= If .B \-\-backup\-file -was used to grow the number of raid-devices in a RAID5, and the system -crashed during the critical section, then the same +was used while reshaping an array (e.g. changing number of devices or +chunk size) and the system crashed during the critical section, then the same .B \-\-backup\-file must be presented to .B \-\-assemble to allow possibly corrupted data to be restored. +.TP +.BR \-\-invalid\-backup +If the file needed for the above option is not available for any +reason an empty file can be given together with this option to +indicate that the backup file is invalid. In this case the data that +was being rearranged at the time of the crash could be irrecoverably +lost, but the rest of the array may still be recoverable. This option +should only be used as a last resort if there is no way to recover the +backup file. + + .TP .BR \-U ", " \-\-update= Update the superblock on each device while assembling the array. The diff --git a/mdadm.c b/mdadm.c index ea518f1..c5acd43 100644 --- a/mdadm.c +++ b/mdadm.c @@ -60,6 +60,7 @@ int main(int argc, char *argv[]) int bitmap_fd = -1; char *bitmap_file = NULL; char *backup_file = NULL; + int invalid_backup = 0; int bitmap_chunk = UnSet; int SparcAdjust = 0; struct mddev_dev *devlist = NULL; @@ -945,6 +946,13 @@ int main(int argc, char *argv[]) backup_file = optarg; continue; + case O(ASSEMBLE, InvalidBackup): + /* Acknowledge that the backupfile is invalid, but ask + * to continue anyway + */ + invalid_backup = 1; + continue; + case O(BUILD,'b'): case O(BUILD,Bitmap): case O(CREATE,'b'): @@ -1180,14 +1188,14 @@ int main(int argc, char *argv[]) if (array_ident->autof == 0) array_ident->autof = autof; rv |= Assemble(ss, devlist->devname, array_ident, - NULL, backup_file, + NULL, backup_file, invalid_backup, readonly, runstop, update, homehost, require_homehost, verbose-quiet, force); } } else if (!scan) rv = Assemble(ss, devlist->devname, &ident, - devlist->next, backup_file, + devlist->next, backup_file, invalid_backup, readonly, runstop, update, homehost, require_homehost, verbose-quiet, force); @@ -1211,7 +1219,7 @@ int main(int argc, char *argv[]) if (array_ident->autof == 0) array_ident->autof = autof; rv |= Assemble(ss, dv->devname, array_ident, - NULL, backup_file, + NULL, backup_file, invalid_backup, readonly, runstop, update, homehost, require_homehost, verbose-quiet, force); @@ -1252,7 +1260,7 @@ int main(int argc, char *argv[]) r = Assemble(ss, a->devname, a, - NULL, NULL, + NULL, NULL, 0, readonly, runstop, NULL, homehost, require_homehost, verbose-quiet, force); @@ -1279,7 +1287,7 @@ int main(int argc, char *argv[]) do { rv2 = Assemble(ss, NULL, &ident, - devlist, NULL, + devlist, NULL, 0, readonly, runstop, NULL, homehost, require_homehost, verbose-quiet, force); @@ -1301,12 +1309,15 @@ int main(int argc, char *argv[]) do { acnt = 0; do { - rv2 = Assemble(ss, NULL, - &ident, - NULL, NULL, - readonly, runstop, "homehost", - homehost, require_homehost, - verbose-quiet, force); + rv2 = Assemble( + ss, NULL, + &ident, + NULL, NULL, 0, + readonly, runstop, + "homehost", + homehost, + require_homehost, + verbose-quiet, force); if (rv2==0) { cnt++; acnt++; diff --git a/mdadm.h b/mdadm.h index 91afe16..a0126eb 100644 --- a/mdadm.h +++ b/mdadm.h @@ -310,6 +310,7 @@ enum special_options { Fork, Bitmap, RebuildMapOpt, + InvalidBackup, }; /* structures read from config file */ @@ -967,7 +968,8 @@ extern int Grow_continue(int mdfd, struct supertype *st, extern int Assemble(struct supertype *st, char *mddev, struct mddev_ident *ident, - struct mddev_dev *devlist, char *backup_file, + struct mddev_dev *devlist, + char *backup_file, int invalid_backup, int readonly, int runstop, char *update, char *homehost, int require_homehost, int verbose, int force);