diff options
author | NeilBrown <neilb@suse.de> | 2010-12-01 01:47:32 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2010-12-01 01:47:32 +0100 |
commit | 87f26d14f75cf565a5885b2a3426499a48987ac3 (patch) | |
tree | b68e93ac398edf4fc31ea5e2152155e1258391c2 | |
parent | fix: assemble for external metadata generates segfault if invalid device found (diff) | |
download | mdadm-87f26d14f75cf565a5885b2a3426499a48987ac3.tar.xz mdadm-87f26d14f75cf565a5885b2a3426499a48987ac3.zip |
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 <neilb@suse.de>
-rw-r--r-- | Assemble.c | 15 | ||||
-rw-r--r-- | Grow.c | 5 | ||||
-rw-r--r-- | ReadMe.c | 1 | ||||
-rw-r--r-- | mdadm.8.in | 15 | ||||
-rw-r--r-- | mdadm.c | 33 | ||||
-rw-r--r-- | mdadm.h | 4 |
6 files changed, 56 insertions, 17 deletions
@@ -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]); @@ -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])); @@ -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 */ @@ -884,14 +884,25 @@ 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 argument given to this flag can be one of @@ -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++; @@ -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); |