Name ": This level does not support spare devices\n");
return 1;
}
- fd = open(devlist->devname, O_RDONLY, 0);
+
+ if (subdevs == 1 && strcmp(devlist->devname, "missing") != 0) {
+ /* If given a single device, it might be a container, and we can
+ * extract a device list from there
+ */
+ mdu_array_info_t inf;
+ int fd;
+
+ memset(&inf, 0, sizeof(inf));
++ fd = open(devlist->devname, O_RDONLY);
+ if (fd >= 0 &&
+ ioctl(fd, GET_ARRAY_INFO, &inf) == 0 &&
+ inf.raid_disks == 0) {
+ /* yep, looks like a container */
+ if (st) {
+ rv = st->ss->load_super(st, fd,
+ devlist->devname);
+ if (rv == 0)
+ have_container = 1;
+ } else {
+ st = guess_super(fd);
+ if (st && !(rv = st->ss->
+ load_super(st, fd,
+ devlist->devname)))
+ have_container = 1;
+ else
+ st = NULL;
+ }
+ }
+ if (fd >= 0)
+ close(fd);
+ if (have_container) {
+ subdevs = 0;
+ devlist = NULL;
+ }
+ }
if (subdevs > raiddisks+sparedisks) {
fprintf(stderr, Name ": You have listed more devices (%d) than are in the array(%d)!\n", subdevs, raiddisks+sparedisks);
return 1;
minsize = freesize;
}
if (runstop != 1 || verbose >= 0) {
- int fd = open(dname, O_RDONLY, 0);
++ int fd = open(dname, O_RDONLY);
+ if (fd <0 ) {
+ fprintf(stderr, Name ": Cannot open %s: %s\n",
+ dname, strerror(errno));
+ fail=1;
+ continue;
+ }
warn |= check_ext2(fd, dname);
warn |= check_reiser(fd, dname);
warn |= check_raid(fd, dname);
if (dnum == insert_point) {
moved_disk = dv;
}
- info.disk.raid_disk = info.disk.number;
- if (info.disk.raid_disk < raiddisks)
- info.disk.state = (1<<MD_DISK_ACTIVE) |
+ if (dnum == insert_point ||
+ strcasecmp(dv->devname, "missing")==0)
+ continue;
+
+ switch(pass) {
+ case 1:
+ *inf = info;
+
+ inf->disk.number = dnum;
+ inf->disk.raid_disk = dnum;
+ if (inf->disk.raid_disk < raiddisks)
+ inf->disk.state = (1<<MD_DISK_ACTIVE) |
(1<<MD_DISK_SYNC);
- else
- info.disk.state = 0;
- if (dv->writemostly)
- info.disk.state |= (1<<MD_DISK_WRITEMOSTLY);
+ else
+ inf->disk.state = 0;
+
+ if (dv->writemostly)
+ inf->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
+
+ if (st->ss->external && st->subarray[0])
- fd = open(dv->devname, O_RDWR, 0);
++ fd = open(dv->devname, O_RDWR);
+ else
- fd = open(dv->devname, O_RDWR|O_EXCL,0);
++ fd = open(dv->devname, O_RDWR|O_EXCL);
- if (dnum == insert_point ||
- strcasecmp(dv->devname, "missing")==0) {
- info.disk.major = 0;
- info.disk.minor = 0;
- info.disk.state = (1<<MD_DISK_FAULTY);
- } else {
- fd = open(dv->devname, O_RDONLY|O_EXCL);
if (fd < 0) {
- fprintf(stderr, Name ": failed to open %s after earlier success - aborting\n",
+ fprintf(stderr, Name ": failed to open %s "
+ "after earlier success - aborting\n",
dv->devname);
return 1;
}
} else if (runstop < 0){
struct map_ent *map = NULL;
struct stat stb;
- if (ioctl(fd, STOP_ARRAY, NULL)) {
- if (quiet==0) {
- fprintf(stderr, Name ": fail to stop array %s: %s\n",
+ struct mdinfo *mdi;
+ /* If this is an mdmon managed array, just write 'inactive'
+ * to the array state and let mdmon clear up.
+ */
+ mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
+ if (mdi &&
+ mdi->array.level > 0 &&
+ mdi->text_version[0] == '/') {
+ char *cp;
+
+ /* This is mdmon managed. */
+ close(fd);
+ if (sysfs_set_str(mdi, NULL,
+ "array_state", "inactive") < 0) {
+ if (quiet == 0)
+ fprintf(stderr, Name
+ ": failed to stop array %s: %s\n",
+ devname, strerror(errno));
+ return 1;
+ }
+
+ /* Give monitor a chance to act */
+ cp = strchr(mdi->text_version+1, '/');
+ if (*cp)
+ *cp = 0;
+ ping_monitor(mdi->text_version+1);
+
+ fd = open(devname, O_RDONLY);
+ } else if (mdi &&
+ mdi->array.major_version == -1 &&
+ mdi->array.minor_version == -2 &&
+ mdi->text_version[0] != '/') {
+ /* container, possibly mdmon-managed.
+ * Make sure mdmon isn't opening it, which
+ * would interfere with the 'stop'
+ */
+ ping_monitor(mdi->sys_name);
+ }
+ if (mdi)
+ sysfs_free(mdi);
+
+ if (fd >= 0 && ioctl(fd, STOP_ARRAY, NULL)) {
- if (quiet == 0)
++ if (quiet == 0) {
+ fprintf(stderr, Name
+ ": failed to stop array %s: %s\n",
devname, strerror(errno));
+ if (errno == EBUSY)
+ fprintf(stderr, "Perhaps a running "
+ "process, mounted filesystem "
+ "or active volume group?\n");
+ }
return 1;
}
+
if (quiet <= 0)
fprintf(stderr, Name ": stopped %s\n", devname);
- if (fstat(fd, &stb) == 0) {
+ if (fd >= 0 && fstat(fd, &stb) == 0) {
int devnum;
if (major(stb.st_rdev) == MD_MAJOR)
devnum = minor(stb.st_rdev);