diff options
author | NeilBrown <neilb@suse.de> | 2012-03-07 15:25:57 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-03-07 15:25:57 +1100 |
commit | c69ffac0d6a068823a1365c3b155ff72f8c4686f (patch) | |
tree | f875037176aa676b8140714d01e67272076451a0 /Manage.c | |
parent | b720636a5849397dbc6dc1b0f0b671d17034a28b (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.c | 16 |
1 files changed, 13 insertions, 3 deletions
@@ -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); |