summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Assemble.c15
-rw-r--r--Grow.c5
-rw-r--r--ReadMe.c1
-rw-r--r--mdadm.8.in15
-rw-r--r--mdadm.c33
-rw-r--r--mdadm.h4
6 files changed, 56 insertions, 17 deletions
diff --git a/Assemble.c b/Assemble.c
index dc5ddd5c..ac489e87 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 13c60288..0515cfa1 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 5dae87aa..57148492 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 4fc94396..8a75e256 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -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
diff --git a/mdadm.c b/mdadm.c
index ea518f15..c5acd43e 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 91afe160..a0126eb5 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);