]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assemble: allow an array undergoing reshape to be started without backup file
authorNeilBrown <neilb@suse.de>
Wed, 1 Dec 2010 00:47:32 +0000 (11:47 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 1 Dec 2010 00:47:32 +0000 (11:47 +1100)
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>
Assemble.c
Grow.c
ReadMe.c
mdadm.8.in
mdadm.c
mdadm.h

index dc5ddd5c6af2d4d502dca5d10685a7b0d445e14b..ac489e8741c82af3c3f7fe36361a1cc81a3161ef 100644 (file)
@@ -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 13c60288112c57a91956dff9a4ad74b62e78f8b1..0515cfa13cd3141d0e7c92919e61e44a48462692 100644 (file)
--- 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]));
index 5dae87aae7c719ab2985345d6faa59975da337de..5714849293a766b18d2ef26242f02dadbb7a9c18 100644 (file)
--- 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 */
index 4fc943963fc1f8ef68c3ca838ceba60371200457..8a75e256662f2d4fc144655f5976506913ec542a 100644 (file)
@@ -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 ea518f1520f76c29328f285e03e8df94a7986441..c5acd43e29043f29b84c0bd827789e8207fd41ae 100644 (file)
--- 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 91afe160c32a5b1871c15ce1b688eb2489295225..a0126eb5cc3993c87144daf99a96b483fa4a1831 100644 (file)
--- 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);