From: NeilBrown Date: Thu, 7 Aug 2008 04:12:25 +0000 (+1000) Subject: Merge branch 'master' into from-stable X-Git-Tag: mdadm-3.0-devel1~76 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=37ea3936a696c2b102963ba5117165ef6be8d4b4 Merge branch 'master' into from-stable Conflicts: Create.c Manage.c --- 37ea3936a696c2b102963ba5117165ef6be8d4b4 diff --cc Create.c index 692a74cc,7b1836a3..69192abb --- a/Create.c +++ b/Create.c @@@ -130,42 -116,6 +130,42 @@@ int Create(struct supertype *st, char * Name ": This level does not support spare devices\n"); return 1; } + + 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, 0); ++ 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; @@@ -333,13 -282,6 +333,13 @@@ 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); @@@ -665,33 -528,24 +665,33 @@@ if (dnum == insert_point) { moved_disk = dv; } - info.disk.raid_disk = info.disk.number; - if (info.disk.raid_disk < raiddisks) - info.disk.state = (1<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<writemostly) - info.disk.state |= (1<disk.state = 0; + + if (dv->writemostly) + inf->disk.state |= (1<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<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; } diff --cc Manage.c index 1a86a859,8297708d..714a33b0 --- a/Manage.c +++ b/Manage.c @@@ -116,58 -111,20 +116,63 @@@ int Manage_runstop(char *devname, int f } 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);