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.
This commit is contained in:
Neil Brown 2006-12-14 17:31:41 +11:00
parent bf4fb153a4
commit c5a6f9a61d
2 changed files with 24 additions and 1 deletions

View File

@ -630,6 +630,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
* and add it. * and add it.
*/ */
int fd; int fd;
long long current_events;
chosen_drive = -1; chosen_drive = -1;
for (i=0; i<info.array.raid_disks && i < bestcnt; i++) { for (i=0; i<info.array.raid_disks && i < bestcnt; i++) {
int j = best[i]; int j = best[i];
@ -642,6 +643,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
} }
if (chosen_drive < 0) if (chosen_drive < 0)
break; break;
current_events = devices[chosen_drive].events;
add_another:
if (verbose >= 0) if (verbose >= 0)
fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n", fprintf(stderr, Name ": forcing event count in %s(%d) from %d upto %d\n",
devices[chosen_drive].devname, devices[chosen_drive].raid_disk, 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; avail[chosen_drive] = 1;
okcnt++; okcnt++;
free(super); 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 /* 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 #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", change += st->ss->update_super(&info, super, "force-array",
devices[chosen_drive].devname, verbose, devices[chosen_drive].devname, verbose,
0, NULL); 0, NULL);

View File

@ -20,6 +20,9 @@ Changes Prior to this release
- --wait or -W will wait for resync activity to finish on the given - --wait or -W will wait for resync activity to finish on the given
devices. devices.
- Fix some problems with --update=uuid and add a test. - 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 Changes Prior to 2.5.6 release
- Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled - Fix bug which meant "bitmap=xxx" in mdadm.conf was not handled