!conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
tst->ss->match_home(tst, c->homehost) == 1)) {
if (report_mismatch)
- pr_err("%s has metadata type %s for which "
- "auto-assembly is disabled\n",
+ pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
devname, tst->ss->name);
tmpdev->used = 2;
} else
!conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
tst->ss->match_home(tst, c->homehost) == 1)) {
if (report_mismatch)
- pr_err("%s has metadata type %s for which "
- "auto-assembly is disabled\n",
+ pr_err("%s has metadata type %s for which auto-assembly is disabled\n",
devname, tst->ss->name);
tmpdev->used = 2;
}
st = tst; tst = NULL;
if (!auto_assem && inargv && tmpdev->next != NULL) {
- pr_err("%s is a container, but is not "
- "only device given: confused and aborting\n",
+ pr_err("%s is a container, but is not only device given: confused and aborting\n",
devname);
st->ss->free_super(st);
dev_policy_free(pol);
tmpdev = NULL;
goto loop;
} else {
- int rv = 0;
- struct mddev_ident *match;
-
content = *contentp;
tst->ss->getinfo_super(tst, content, NULL);
report_mismatch ? devname : NULL))
goto loop;
- match = conf_match(tst, content, devname,
- report_mismatch ? c->verbose : -1,
- &rv);
- if (!match && rv == 2)
- goto loop;
- if (match && match->devname &&
- strcasecmp(match->devname, "<ignore>") == 0) {
- if (report_mismatch)
- pr_err("%s is a member of an explicitly ignored array\n",
- devname);
- goto loop;
- }
- if (match && !ident_matches(match, content, tst,
- c->homehost, c->update,
- report_mismatch ? devname : NULL))
- /* Array exists in mdadm.conf but some
- * details don't match, so reject it
+ if (auto_assem) {
+ /* Never auto-assemble things that conflict
+ * with mdadm.conf in some way
*/
- goto loop;
+ struct mddev_ident *match;
+ int rv = 0;
+
+ match = conf_match(tst, content, devname,
+ report_mismatch ? c->verbose : -1,
+ &rv);
+ if (!match && rv == 2)
+ goto loop;
+ if (match && match->devname &&
+ strcasecmp(match->devname, "<ignore>") == 0) {
+ if (report_mismatch)
+ pr_err("%s is a member of an explicitly ignored array\n",
+ devname);
+ goto loop;
+ }
+ if (match && !ident_matches(match, content, tst,
+ c->homehost, c->update,
+ report_mismatch ? devname : NULL))
+ /* Array exists in mdadm.conf but some
+ * details don't match, so reject it
+ */
+ goto loop;
+ }
/* should be safe to try an exclusive open now, we
* have rejected anything that some other mdadm might
struct stat stb;
struct supertype *tst;
int i;
+ int dfd;
if (tmpdev->used != 1)
continue;
/* looks like a good enough match to update the super block if needed */
#ifndef MDASSEMBLE
if (c->update) {
- int dfd;
/* prepare useful information in info structures */
struct stat stb2;
int err;
c->homehost);
if (err < 0) {
if (err == -1)
- pr_err("--update=%s not understood"
- " for %s metadata\n",
+ pr_err("--update=%s not understood for %s metadata\n",
c->update, tst->ss->name);
tst->ss->free_super(tst);
free(tst);
if (tst->ss->store_super(tst, dfd))
pr_err("Could not re-write superblock on %s.\n",
devname);
- close(dfd);
if (strcmp(c->update, "uuid")==0 &&
ident->bitmap_fd >= 0 && !bitmap_done) {
} else
#endif
{
- int dfd = dev_open(devname,
- tmpdev->disposition == 'I'
- ? O_RDWR : (O_RDWR|O_EXCL));
+ dfd = dev_open(devname,
+ tmpdev->disposition == 'I'
+ ? O_RDWR : (O_RDWR|O_EXCL));
tst = dup_super(st);
if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) {
return -1;
}
tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks);
- close(dfd);
}
- stat(devname, &stb);
+ fstat(dfd, &stb);
+ close(dfd);
if (c->verbose > 0)
pr_err("%s is identified as a member of %s, slot %d%s.\n",
* Could be a mis-detection caused by overlapping
* partitions. fail-safe.
*/
- pr_err("WARNING %s and %s appear"
- " to have very similar superblocks.\n"
- " If they are really different, "
- "please --zero the superblock on one\n"
- " If they are the same or overlap,"
- " please remove one from %s.\n",
+ pr_err("WARNING %s and %s appear to have very similar superblocks.\n"
+ " If they are really different, please --zero the superblock on one\n"
+ " If they are the same or overlap, please remove one from %s.\n",
devices[best[i]].devname, devname,
inargv ? "the list" :
"the\n DEVICE list in mdadm.conf"
i < content->array.raid_disks * 2 && i < bestcnt;
i += 2) {
int j = best[i];
- if (j>=0 &&
- !devices[j].uptodate &&
- devices[j].i.recovery_start == MaxSector &&
- (chosen_drive < 0 ||
+ if (j < 0)
+ continue;
+ if (devices[j].uptodate)
+ continue;
+ if (devices[j].i.recovery_start != MaxSector) {
+ int delta;
+ if (!devices[j].i.reshape_active ||
+ devices[j].i.delta_disks <= 0)
+ continue;
+ /* When increasing number of devices, an
+ * added device also appears to be
+ * recovering. It is safe to include it
+ * as long as it won't be a source of
+ * data.
+ * For now, just allow for last data
+ * devices in RAID4 or last devices in RAID4/5/6.
+ */
+ delta = devices[j].i.delta_disks;
+ if (devices[j].i.array.level >= 4 &&
+ devices[j].i.array.level <= 6 &&
+ i/2 >= content->array.raid_disks - delta)
+ /* OK */;
+ else if (devices[j].i.array.level == 4 &&
+ i/2 >= content->array.raid_disks - delta - 1)
+ /* OK */;
+ else
+ continue;
+ }
+ if (chosen_drive < 0 ||
devices[j].i.events
- > devices[chosen_drive].i.events))
+ > devices[chosen_drive].i.events)
chosen_drive = j;
}
if (chosen_drive < 0)
rv = add_disk(mdfd, st, content, &devices[j].i);
if (rv) {
- pr_err("failed to add "
- "%s to %s: %s\n",
+ pr_err("failed to add %s to %s: %s\n",
devices[j].devname,
mddev,
strerror(errno));
} else if (c->verbose > 0 && i < content->array.raid_disks*2
&& (i&1) == 0)
pr_err("no uptodate device for slot %d of %s\n",
- i, mddev);
+ i/2, mddev);
}
if (content->array.level == LEVEL_CONTAINER) {
if (c->verbose >= 0) {
- pr_err("Container %s has been "
- "assembled with %d drive%s",
+ pr_err("Container %s has been assembled with %d drive%s",
mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s");
if (okcnt < (unsigned)content->array.raid_disks)
fprintf(stderr, " (out of %d)",
if (!enough(content->array.level, content->array.raid_disks,
content->array.layout, 1, avail))
- pr_err("Not enough devices to "
- "start the array.\n");
+ pr_err("Not enough devices to start the array.\n");
else if (!enough(content->array.level,
content->array.raid_disks,
content->array.layout, clean,
avail))
- pr_err("Not enough devices to "
- "start the array while not clean "
- "- consider --force.\n");
+ pr_err("Not enough devices to start the array while not clean - consider --force.\n");
return 1;
}
content->array.raid_disks,
content->array.layout, clean,
avail))
- fprintf(stderr, " - not enough to start the "
- "array while not clean - consider "
- "--force.\n");
+ fprintf(stderr, " - not enough to start the array while not clean - consider --force.\n");
else {
if (req_cnt == (unsigned)content->array.raid_disks)
fprintf(stderr, " - need all %d to start it", req_cnt);
*/
if (map_lock(&map))
pr_err("failed to get exclusive lock on mapfile - continue anyway...\n");
- mp = map_by_uuid(&map, content->uuid);
+ if (c->update && strcmp(c->update,"uuid") == 0)
+ mp = NULL;
+ else
+ mp = map_by_uuid(&map, content->uuid);
if (mp) {
struct mdinfo *dv;
/* array already exists. */
if (i < content->array.raid_disks * 2) {
if (devices[j].i.recovery_start == MaxSector ||
(content->reshape_active &&
- ((i >= content->array.raid_disks - content->delta_disks) ||
- (i >= content->array.raid_disks - content->delta_disks - 1
- && content->array.level == 4)))) {
+ i >= content->array.raid_disks - content->delta_disks)) {
if (!avail[i/2]) {
okcnt++;
avail[i/2]=1;
int err = 0;
int *fdlist = xmalloc(sizeof(int)* bestcnt);
if (c->verbose > 0)
- pr_err(":%s has an active reshape - checking "
- "if critical section needs to be restored\n",
+ pr_err("%s has an active reshape - checking if critical section needs to be restored\n",
chosen_name);
if (!c->backup_file)
c->backup_file = locate_backup(content->sys_name);
c->backup_file, c->verbose > 0);
if (err && c->invalid_backup) {
if (c->verbose > 0)
- pr_err("continuing"
- " without restoring backup\n");
+ pr_err("continuing without restoring backup\n");
err = 0;
}
}