]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Change handling for "--assemble --force" when two drives disappeared at once.
authorNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:41 +0000 (17:31 +1100)
committerNeil Brown <neilb@suse.de>
Thu, 14 Dec 2006 06:31:41 +0000 (17:31 +1100)
If two drives in a raid5 disappear at the same time, then "-Af"
will add them both in rather than just one and forcing the array
to 'clean'.  This is slightly safer in some cases.

Assemble.c
ChangeLog

index 2adf08d34bb0de843d81309bf2c1937ceaac06f5..c731105dfab28351ff2718df5066616a30106850 100644 (file)
@@ -630,6 +630,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                 * and add it.
                 */
                int fd;
+               long long current_events;
                chosen_drive = -1;
                for (i=0; i<info.array.raid_disks && i < bestcnt; i++) {
                        int j = best[i];
@@ -642,6 +643,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
                if (chosen_drive < 0)
                        break;
+               current_events = devices[chosen_drive].events;
+       add_another:
                if (verbose >= 0)
                        fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
                                devices[chosen_drive].devname, devices[chosen_drive].raid_disk,
@@ -680,6 +683,20 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                avail[chosen_drive] = 1;
                okcnt++;
                free(super);
+
+               /* If there are any other drives of the same vintage,
+                * add them in as well.  We can't lose and we might gain
+                */
+               for (i=0; i<info.array.raid_disks && i < bestcnt ; i++) {
+                       int j = best[i];
+                       if (j >= 0 &&
+                           !devices[j].uptodate &&
+                           devices[j].events > 0 &&
+                           devices[j].events == current_events) {
+                               chosen_drive = j;
+                               goto add_another;
+                       }
+               }
        }
 
        /* Now we want to look at the superblock which the kernel will base things on
@@ -760,7 +777,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
 #endif
        }
-       if (force && okcnt < info.array.raid_disks) {
+       if (force && !clean &&
+           !enough(info.array.level, info.array.raid_disks,
+                   info.array.layout, clean,
+                   avail, okcnt)) {
                change += st->ss->update_super(&info, super, "force-array",
                                        devices[chosen_drive].devname, verbose,
                                               0, NULL);
index ebd83fbc5495c58f4046530bcb30566834568115..45efef2ae0e84f094798d6dc3306b67ffdde678a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,9 @@ Changes Prior to this release
     -   --wait or -W will wait for resync activity to finish on the given
        devices.
     -   Fix some problems with --update=uuid and add a test.
+    -   If two drives in a raid5 disappear at the same time, then "-Af"
+        will add them both in rather than just one and forcing the array
+       to 'clean'.  This is slightly safer in some cases.
 
 Changes Prior to 2.5.6 release
     -   Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled