summaryrefslogtreecommitdiffstats
path: root/Assemble.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-12-14 17:31:41 +1100
committerNeil Brown <neilb@suse.de>2006-12-14 17:31:41 +1100
commitc5a6f9a61d166512f237fa88bd5867dfa4e81a70 (patch)
tree8cf27e3eb09320e06eaffb2c4ed4cb0f9418b7bf /Assemble.c
parentbf4fb153a4431ad3f91c3e72eebbd661b0455ed7 (diff)
downloadmdadm-c5a6f9a61d166512f237fa88bd5867dfa4e81a70.tar.gz
mdadm-c5a6f9a61d166512f237fa88bd5867dfa4e81a70.tar.xz
mdadm-c5a6f9a61d166512f237fa88bd5867dfa4e81a70.zip
Change handling for "--assemble --force" when two drives disappeared at once.
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.
Diffstat (limited to 'Assemble.c')
-rw-r--r--Assemble.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/Assemble.c b/Assemble.c
index 2adf08d..c731105 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -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);