summaryrefslogtreecommitdiff
path: root/Manage.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-03-07 15:25:57 +1100
committerNeilBrown <neilb@suse.de>2012-03-07 15:25:57 +1100
commitc69ffac0d6a068823a1365c3b155ff72f8c4686f (patch)
treef875037176aa676b8140714d01e67272076451a0 /Manage.c
parentb720636a5849397dbc6dc1b0f0b671d17034a28b (diff)
Manage: allow --re-add to failed array.
If both "legs" of a RAID1 (or equivalent in RAID10) fail, then one of the becomes available again it maybe appropriate to re-add the failed device(s). So remove the restriction that an array must has 'enough' devices before being re-added, and if there is no-where to read a superblock from for matching, then assume the kernel will do necessary checks. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r--Manage.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/Manage.c b/Manage.c
index d9775ded..4cf6e587 100644
--- a/Manage.c
+++ b/Manage.c
@@ -723,7 +723,13 @@ int Manage_subdevs(char *devname, int fd,
break;
}
/* FIXME this is a bad test to be using */
- if (!tst->sb) {
+ if (!tst->sb &&
+ dv->re_add) {
+ /* we are re-adding a device to a
+ * completely dead array - have to depend
+ * on kernel to check
+ */
+ } else if (!tst->sb) {
close(tfd);
st->ss->free_super(st);
fprintf(stderr, Name ": cannot load array metadata from %s\n", devname);
@@ -747,12 +753,16 @@ int Manage_subdevs(char *devname, int fd,
* and was temporarily removed, and is now being re-added.
* If so, we can simply re-add it.
*/
- tst->ss->uuid_from_super(tst, duuid);
if (st->sb) {
struct mdinfo mdi;
st->ss->getinfo_super(st, &mdi, NULL);
st->ss->uuid_from_super(st, ouuid);
+ if (tst->sb)
+ tst->ss->uuid_from_super(tst, duuid);
+ else
+ /* Assume uuid matches: kernel will check */
+ memcpy(duuid, ouuid, sizeof(ouuid));
if ((mdi.disk.state & (1<<MD_DISK_ACTIVE)) &&
!(mdi.disk.state & (1<<MD_DISK_FAULTY)) &&
memcmp(duuid, ouuid, sizeof(ouuid))==0) {
@@ -768,7 +778,7 @@ int Manage_subdevs(char *devname, int fd,
disc.number = mdi.disk.number;
if (ioctl(fd, GET_DISK_INFO, &disc) != 0
|| disc.major != 0 || disc.minor != 0
- || !enough_fd(fd))
+ )
goto skip_re_add;
disc.major = major(stb.st_rdev);
disc.minor = minor(stb.st_rdev);