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);