if (md_get_version(fd) < 9000) {
if (ioctl(fd, STOP_MD, 0) == 0)
return 0;
- pr_err("stopping device %s "
- "failed: %s\n",
+ pr_err("stopping device %s failed: %s\n",
devname, strerror(errno));
return 1;
}
if (fd >= 0)
close(fd);
if (verbose >= 0)
- pr_err("Cannot get exclusive access to %s:"
- "Perhaps a running "
- "process, mounted filesystem "
- "or active volume group?\n",
+ pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
devname);
return 1;
}
fd = open_dev_excl(devnm);
if (fd < 0) {
if (verbose >= 0)
- pr_err("failed to completely stop %s"
- ": Device is busy\n",
+ pr_err("failed to completely stop %s: Device is busy\n",
devname);
rv = 1;
goto out;
metadata_container_matches(m->metadata_version+9,
devnm)) {
if (verbose >= 0)
- pr_err("Cannot stop container %s: "
- "member %s still active\n",
+ pr_err("Cannot stop container %s: member %s still active\n",
devname, m->dev);
free_mdstat(mds);
rv = 1;
pr_err("failed to stop array %s: %s\n",
devname, strerror(errno));
if (errno == EBUSY)
- cont_err("Perhaps a running "
- "process, mounted filesystem "
- "or active volume group?\n");
+ cont_err("Perhaps a running process, mounted filesystem or active volume group?\n");
}
rv = 1;
goto out;
int rv = -1;
tfd = dev_open(dv->devname, O_RDWR);
if (tfd < 0) {
- pr_err("failed to open %s for"
- " superblock update during re-add\n", dv->devname);
+ pr_err("failed to open %s for superblock update during re-add\n", dv->devname);
return -1;
}
rv = dev_st->ss->store_super(dev_st, tfd);
close(tfd);
if (rv != 0) {
- pr_err("failed to update"
- " superblock during re-add\n");
+ pr_err("failed to update superblock during re-add\n");
return -1;
}
}
int Manage_add(int fd, int tfd, struct mddev_dev *dv,
struct supertype *tst, mdu_array_info_t *array,
int force, int verbose, char *devname,
- char *update, unsigned long rdev, unsigned long long array_size)
+ char *update, unsigned long rdev, unsigned long long array_size,
+ int raid_slot)
{
unsigned long long ldsize;
struct supertype *dev_st = NULL;
if (tst->ss == &super0 && ldsize > 4ULL*1024*1024*1024*1024) {
/* More than 4TB is wasted on v0.90 */
if (!force) {
- pr_err("%s is larger than %s can "
- "effectively use.\n"
- " Add --force is you "
- "really want to add this device.\n",
+ pr_err("%s is larger than %s can effectively use.\n"
+ " Add --force is you really want to add this device.\n",
dv->devname, devname);
return -1;
}
- pr_err("%s is larger than %s can "
- "effectively use.\n"
- " Adding anyway as --force "
- "was given.\n",
+ pr_err("%s is larger than %s can effectively use.\n"
+ " Adding anyway as --force was given.\n",
dv->devname, devname);
}
if (!tst->ss->external &&
}
/* Make sure device is large enough */
- if (tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) <
+ if (tst->sb &&
+ tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) <
array_size) {
if (dv->disposition == 'M')
return 0;
int d;
int found = 0;
- for (d = 0; d < MAX_DISKS && found < array->active_disks; d++) {
+ for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) {
disc.number = d;
if (ioctl(fd, GET_DISK_INFO, &disc))
continue;
}
disc.major = major(rdev);
disc.minor = minor(rdev);
- disc.number =j;
+ if (raid_slot < 0)
+ disc.number = j;
+ else
+ disc.number = raid_slot;
disc.state = 0;
if (array->not_persistent==0) {
int dfd;
}
free(used);
}
+
+ if (array->state & (1 << MD_SB_CLUSTERED)) {
+ if (dv->disposition == 'c')
+ disc.state |= (1 << MD_DISK_CANDIDATE);
+ else
+ disc.state |= (1 << MD_DISK_CLUSTER_ADD);
+ }
+
if (dv->writemostly == 1)
disc.state |= (1 << MD_DISK_WRITEMOSTLY);
if (tst->ss->external) {
container_fd = open_dev_excl(devnm);
if (container_fd < 0) {
- pr_err("add failed for %s:"
- " could not get exclusive access to container\n",
+ pr_err("add failed for %s: could not get exclusive access to container\n",
dv->devname);
tst->ss->free_super(tst);
return -1;
* would block add_disk */
tst->ss->free_super(tst);
if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
- pr_err("add new device to external metadata"
- " failed for %s\n", dv->devname);
+ pr_err("add new device to external metadata failed for %s\n", dv->devname);
close(container_fd);
sysfs_free(sra);
return -1;
strcpy(devnm, fd2devnm(fd));
lfd = open_dev_excl(devnm);
if (lfd < 0) {
- pr_err("Cannot get exclusive access "
- " to container - odd\n");
+ pr_err("Cannot get exclusive access to container - odd\n");
return -1;
}
/* We may not be able to check on holders in
}
}
if (err) {
- pr_err("hot remove failed "
- "for %s: %s\n", dv->devname,
+ pr_err("hot remove failed for %s: %s\n", dv->devname,
strerror(errno));
if (lfd >= 0)
close(lfd);
* variant on 'A'
* 'F' - Another variant of 'A', where the device was faulty
* so must be removed from the array first.
+ * 'c' - confirm the device as found (for clustered environments)
*
* For 'f' and 'r', the device can also be a kernel-internal
* name such as 'sdb'.
struct mdinfo info;
int frozen = 0;
int busy = 0;
+ int raid_slot = -1;
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
pr_err("Cannot get array info for %s\n",
for (dv = devlist; dv; dv = dv->next) {
unsigned long rdev = 0; /* device to add/remove etc */
int rv;
+ int mj,mn;
+
+ raid_slot = -1;
+ if (dv->disposition == 'c') {
+ rv = parse_cluster_confirm_arg(dv->devname,
+ &dv->devname,
+ &raid_slot);
+ if (!rv) {
+ pr_err("Could not get the devname of cluster\n");
+ goto abort;
+ }
+ }
if (strcmp(dv->devname, "failed") == 0 ||
strcmp(dv->devname, "faulty") == 0) {
if (dv->disposition != 'A'
&& dv->disposition != 'r') {
- pr_err("%s only meaningful "
- "with -r or --re-add, not -%c\n",
+ pr_err("%s only meaningful with -r or --re-add, not -%c\n",
dv->devname, dv->disposition);
goto abort;
}
}
if (strcmp(dv->devname, "detached") == 0) {
if (dv->disposition != 'r' && dv->disposition != 'f') {
- pr_err("%s only meaningful "
- "with -r of -f, not -%c\n",
+ pr_err("%s only meaningful with -r of -f, not -%c\n",
dv->devname, dv->disposition);
goto abort;
}
if (strcmp(dv->devname, "missing") == 0) {
struct mddev_dev *add_devlist = NULL;
struct mddev_dev **dp;
+ if (dv->disposition == 'c') {
+ rv = ioctl(fd, CLUSTERED_DISK_NACK, NULL);
+ break;
+ }
+
if (dv->disposition != 'A') {
- pr_err("'missing' only meaningful "
- "with --re-add\n");
+ pr_err("'missing' only meaningful with --re-add\n");
goto abort;
}
add_devlist = conf_get_devs();
int found = 0;
char dname[55];
if (dv->disposition != 'r' && dv->disposition != 'f') {
- pr_err("%s only meaningful "
- "with -r or -f, not -%c\n",
+ pr_err("%s only meaningful with -r or -f, not -%c\n",
dv->devname, dv->disposition);
goto abort;
}
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
if (sysfd >= 0) {
char dn[20];
- int mj,mn;
if (sysfs_fd_get_str(sysfd, dn, 20) > 0 &&
sscanf(dn, "%d:%d", &mj,&mn) == 2) {
rdev = makedev(mj,mn);
if (!found) {
sysfd = sysfs_open(fd2devnm(fd), dname, "state");
if (sysfd < 0) {
- pr_err("%s does not appear "
- "to be a component of %s\n",
+ pr_err("%s does not appear to be a component of %s\n",
dv->devname, devname);
goto abort;
}
}
+ } else if ((dv->disposition == 'r' || dv->disposition == 'f')
+ && get_maj_min(dv->devname, &mj, &mn)) {
+ /* for 'fail' and 'remove', the device might
+ * not exist.
+ */
+ rdev = makedev(mj, mn);
} else {
struct stat stb;
tfd = dev_open(dv->devname, O_RDONLY);
case 'A':
case 'M': /* --re-add missing */
case 'F': /* --re-add faulty */
+ case 'c': /* --cluster-confirm */
/* add the device */
if (subarray) {
- pr_err("Cannot add disks to a"
- " \'member\' array, perform this"
- " operation on the parent container\n");
+ pr_err("Cannot add disks to a \'member\' array, perform this operation on the parent container\n");
goto abort;
}
if (dv->disposition == 'F')
}
rv = Manage_add(fd, tfd, dv, tst, &array,
force, verbose, devname, update,
- rdev, array_size);
+ rdev, array_size, raid_slot);
close(tfd);
tfd = -1;
if (rv < 0)
case 'r':
/* hot remove */
if (subarray) {
- pr_err("Cannot remove disks from a"
- " \'member\' array, perform this"
- " operation on the parent container\n");
+ pr_err("Cannot remove disks from a \'member\' array, perform this operation on the parent container\n");
rv = -1;
} else
rv = Manage_remove(tst, fd, dv, sysfd,
break;
case 'R': /* Mark as replaceable */
if (subarray) {
- pr_err("Cannot replace disks in a"
- " \'member\' array, perform this"
- " operation on the parent container\n");
+ pr_err("Cannot replace disks in a \'member\' array, perform this operation on the parent container\n");
rv = -1;
} else {
if (!frozen) {