/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2012 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
static int is_member_busy(char *metadata_version)
{
/* check if the given member array is active */
- struct mdstat_ent *mdstat = mdstat_read(1, 0);
+ struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *ent;
int busy = 0;
return 0;
}
if (ident->raid_disks != UnSet &&
+ content->array.raid_disks != 0 && /* metadata doesn't know how many to expect */
ident->raid_disks!= content->array.raid_disks) {
if (devname)
pr_err("%s requires wrong number of drives.\n",
if (tmpdev->used > 1)
continue;
- if (ident->devices &&
- !match_oneof(ident->devices, devname)) {
+ if (ident->container) {
+ if (ident->container[0] == '/' &&
+ !same_dev(ident->container, devname)) {
+ if (report_mismatch)
+ pr_err("%s is not the container required (%s)\n",
+ devname, ident->container);
+ continue;
+ }
+ } else if (ident->devices &&
+ !match_oneof(ident->devices, devname)) {
+ /* Note that we ignore the "device=" identifier if a
+ * "container=" is given. Checking both is unnecessarily
+ * complicated.
+ */
if (report_mismatch)
pr_err("%s is not one of %s\n", devname, ident->devices);
continue;
}
close(dfd);
- if (ident->container) {
- if (ident->container[0] == '/' &&
- !same_dev(ident->container, devname)) {
+ if (ident->container && ident->container[0] != '/') {
+ /* we have a uuid */
+ int uuid[4];
+
+ content = *contentp;
+ tst->ss->getinfo_super(tst, content, NULL);
+
+ if (!parse_uuid(ident->container, uuid) ||
+ !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
if (report_mismatch)
- pr_err("%s is not the container required (%s)\n",
- devname, ident->container);
+ pr_err("%s has wrong UUID to be required container\n",
+ devname);
goto loop;
}
- if (ident->container[0] != '/') {
- /* we have a uuid */
- int uuid[4];
-
- content = *contentp;
- tst->ss->getinfo_super(tst, content, NULL);
-
- if (!parse_uuid(ident->container, uuid) ||
- !same_uuid(content->uuid, uuid, tst->ss->swapuuid)) {
- if (report_mismatch)
- pr_err("%s has wrong UUID to be required container\n",
- devname);
- goto loop;
- }
- }
}
/* It is worth looking inside this container.
*/
#ifndef MDASSEMBLE
int bitmap_done = 0;
#endif
- int most_recent = 0;
+ int most_recent = -1;
int bestcnt = 0;
int *best = *bestp;
devices[devcnt].i.disk.major = major(stb.st_rdev);
devices[devcnt].i.disk.minor = minor(stb.st_rdev);
- if (devices[devcnt].i.events
- > devices[most_recent].i.events &&
- devices[devcnt].i.disk.state == 6)
+ if (devices[devcnt].i.disk.state == 6) {
+ if (most_recent < 0 ||
+ devices[devcnt].i.events
+ > devices[most_recent].i.events)
most_recent = devcnt;
+ }
if (content->array.level == LEVEL_MULTIPATH)
/* with multipath, the raid_disk from the superblock is meaningless */
}
devcnt++;
}
- *most_recentp = most_recent;
+ if (most_recent >= 0)
+ *most_recentp = most_recent;
*bestcntp = bestcnt;
*bestp = best;
return devcnt;
if (content->reshape_active &&
!(content->reshape_active & RESHAPE_NO_BACKUP) &&
content->delta_disks <= 0) {
+ if (!c->backup_file) {
+ pr_err("%s: Need a backup file to complete reshape of this array.\n",
+ mddev);
+ pr_err("Please provided one with \"--backup-file=...\"\n");
+ if (c->update &&
+ strcmp(c->update, "revert-reshape") == 0)
+ pr_err("(Don't specify --update=revert-reshape again, that part succeeded.)\n");
+ return 1;
+ }
rv = sysfs_set_str(content, NULL,
"array_state", "readonly");
if (rv == 0)
}
}
}
- printf("l=%d o=%d r=%d w=%d\n",content->array.level,
- okcnt, content->array.raid_disks, was_forced);
if (content->array.level == 6 &&
okcnt + 1 == (unsigned)content->array.raid_disks &&
was_forced) {
/* If this device thinks that 'most_recent' has failed, then
* we must reject this device.
*/
- if (j != most_recent &&
+ if (j != most_recent && !c->force &&
content->array.raid_disks > 0 &&
devices[most_recent].i.disk.raid_disk >= 0 &&
devmap[j * content->array.raid_disks + devices[most_recent].i.disk.raid_disk] == 0) {
working++;
} else if (errno == EEXIST)
preexist++;
- if (working + expansion == 0)
+ if (working + expansion == 0 && c->runstop <= 0)
return 1;/* Nothing new, don't try to start */
map_update(&map, fd2devnm(mdfd),