}
if (dfd >= 0) close(dfd);
if (tmpdev->used == 2) {
- if (auto_assem)
+ if (auto_assem || !inargv)
/* Ignore unrecognised devices during auto-assembly */
goto loop;
if (ident->uuid_set || ident->name[0] ||
homehost, update,
report_missmatch ? devname : NULL))
goto loop;
-
- if (!memcmp(content->uuid, uuid_zero, sizeof(int[4]))) {
- /* this is imsm_spare - do not set st */
- tmpdev->used = 3;
- goto loop;
- }
if (st == NULL)
st = dup_super(tst);
if (st->minor_version == -1)
st->minor_version = tst->minor_version;
+
+ if (memcmp(content->uuid, uuid_zero,
+ sizeof(int[4])) == 0) {
+ /* this is a floating spare. It cannot define
+ * an array unless there are no more arrays of
+ * this type to be found. It can be included
+ * in an array of this type though.
+ */
+ tmpdev->used = 3;
+ goto loop;
+ }
+
if (st->ss != tst->ss ||
st->minor_version != tst->minor_version ||
st->ss->compare_super(st, tst) != 0) {
}
loop:
/* Collect domain information from members only */
- if (tmpdev && tmpdev->used == 1)
+ if (tmpdev && tmpdev->used == 1) {
+ if (!pol)
+ pol = devnum_policy(stb.st_rdev);
domain_merge(&domains, pol, tst?tst->ss->name:NULL);
+ }
dev_policy_free(pol);
pol = NULL;
if (tst)
tst->ss->free_super(tst);
}
+ /* Check if we found some imsm spares but no members */
+ if ((auto_assem ||
+ (ident->uuid_set &&
+ memcmp(uuid_zero, ident->uuid,sizeof(uuid_zero)) == 0)) &&
+ (!st || !st->sb))
+ for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
+ if (tmpdev->used != 3)
+ continue;
+ tmpdev->used = 1;
+ content = &info;
+
+ if (!st->sb) {
+ /* we need sb from one of the spares */
+ int dfd = dev_open(tmpdev->devname, O_RDONLY);
+ if (dfd < 0 ||
+ st->ss->load_super(st, dfd, NULL))
+ tmpdev->used = 2;
+ if (dfd > 0)
+ close(dfd);
+ }
+ }
+
/* Now reject spares that don't match domains of identified members */
for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
struct stat stb;
} else {
struct dev_policy *pol = NULL;
pol = devnum_policy(stb.st_rdev);
- if (domain_test(domains, pol, NULL))
+ if (domain_test(domains, pol, NULL) == 1)
/* take this spare if domains match */
tmpdev->used = 1;
else
if (content->array.level != LEVEL_MULTIPATH)
if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
if (!(devices[j].i.disk.state
- & (1<<MD_DISK_FAULTY)))
+ & (1<<MD_DISK_FAULTY))) {
+ devices[j].uptodate = 1;
sparecnt++;
+ }
continue;
}
/* If this devices thinks that 'most_recent' has failed, then
content->array.raid_disks);
fprintf(stderr, "\n");
}
+ st->ss->free_super(st);
sysfs_uevent(content, "change");
wait_for(chosen_name, mdfd);
close(mdfd);