X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=Manage.c;h=66d697803e2866923897e7a3af27b70749631432;hp=3361269dedc8d32ed5bcaff06e8965fc6651d7ad;hb=9e6d9291275267d3fd4b6d85d7232081f89cd8e2;hpb=eb0af52689656f6526540ee3a72b0647e7a7b20d diff --git a/Manage.c b/Manage.c index 3361269d..66d69780 100644 --- a/Manage.c +++ b/Manage.c @@ -224,7 +224,9 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet) close(fd); fprintf(stderr, Name ": Cannot get exclusive access to %s:" - " possibly it is still in use.\n", + "Perhaps a running " + "process, mounted filesystem " + "or active volume group?\n", devname); return 1; } @@ -232,14 +234,23 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet) if (mdi && mdi->array.level > 0 && is_subarray(mdi->text_version)) { + int err; /* 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)); + + count = 25; + while (count && + (err = sysfs_set_str(mdi, NULL, + "array_state", + "inactive")) < 0 + && errno == EBUSY) { + usleep(200000); + count--; + } + if (err && !quiet) { + fprintf(stderr, Name + ": failed to stop array %s: %s\n", + devname, strerror(errno)); return 1; } @@ -290,7 +301,7 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet) * which blocks STOP_ARRAY is probably a transient use, * so it is reasonable to retry for a while - 5 seconds. */ - count = 25; + count = 25; err = 0; while (count && fd >= 0 && (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) { @@ -427,19 +438,21 @@ int Manage_subdevs(char *devname, int fd, if (strcmp(dv->devname, "failed")==0 || strcmp(dv->devname, "faulty")==0) { + int remaining_disks = array.nr_disks; if (dv->disposition != 'r') { fprintf(stderr, Name ": %s only meaningful " "with -r, not -%c\n", dv->devname, dv->disposition); return 1; } - for (; j < array.raid_disks + array.nr_disks ; j++) { + for (; j < 1024 && remaining_disks > 0; j++) { unsigned dev; disc.number = j; if (ioctl(fd, GET_DISK_INFO, &disc)) continue; if (disc.major == 0 && disc.minor == 0) continue; + remaining_disks --; if ((disc.state & 1) == 0) /* faulty */ continue; dev = makedev(disc.major, disc.minor); @@ -458,13 +471,14 @@ int Manage_subdevs(char *devname, int fd, if (next != dv) continue; } else if (strcmp(dv->devname, "detached") == 0) { + int remaining_disks = array.nr_disks; if (dv->disposition != 'r' && dv->disposition != 'f') { fprintf(stderr, Name ": %s only meaningful " "with -r of -f, not -%c\n", dv->devname, dv->disposition); return 1; } - for (; j < array.raid_disks + array.nr_disks; j++) { + for (; j < 1024 && remaining_disks > 0; j++) { int sfd; unsigned dev; disc.number = j; @@ -472,6 +486,7 @@ int Manage_subdevs(char *devname, int fd, continue; if (disc.major == 0 && disc.minor == 0) continue; + remaining_disks --; sprintf(dvname,"%d:%d", disc.major, disc.minor); sfd = dev_open(dvname, O_RDONLY); if (sfd >= 0) { @@ -693,13 +708,7 @@ int Manage_subdevs(char *devname, int fd, */ tst->ss->uuid_from_super(tst, duuid); - /* re-add doesn't work for version-1 superblocks - * before 2.6.18 :-( - */ - if (array.major_version == 1 && - get_linux_version() <= 2006018) - ; - else if (st->sb) { + if (st->sb) { struct mdinfo mdi; st->ss->getinfo_super(st, &mdi, NULL); st->ss->uuid_from_super(st, ouuid); @@ -709,6 +718,12 @@ int Manage_subdevs(char *devname, int fd, /* look like it is worth a try. Need to * make sure kernel will accept it though. */ + /* re-add doesn't work for version-1 superblocks + * before 2.6.18 :-( + */ + if (array.major_version == 1 && + get_linux_version() <= 2006018) + goto skip_re_add; disc.number = mdi.disk.number; if (ioctl(fd, GET_DISK_INFO, &disc) != 0 || disc.major != 0 || disc.minor != 0 @@ -735,7 +750,7 @@ int Manage_subdevs(char *devname, int fd, st, NULL, update, devname, verbose, 0, NULL); if (rv == 0) - rv = tst->ss->store_super(st, tfd); + rv = st->ss->store_super(st, tfd); close(tfd); tfd = -1; if (rv != 0) { @@ -835,9 +850,6 @@ int Manage_subdevs(char *devname, int fd, if (dv->writemostly == 1) disc.state |= 1 << MD_DISK_WRITEMOSTLY; dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); - if (tst->ss->external && - mdmon_running(tst->container_dev)) - tst->update_tail = &tst->updates; if (tst->ss->add_to_super(tst, &disc, dfd, dv->devname)) { close(dfd); @@ -898,13 +910,18 @@ int Manage_subdevs(char *devname, int fd, } dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT); + if (mdmon_running(tst->container_dev)) + tst->update_tail = &tst->updates; if (tst->ss->add_to_super(tst, &disc, dfd, dv->devname)) { close(dfd); close(container_fd); return 1; } - close(dfd); + if (tst->update_tail) + flush_metadata_updates(tst); + else + tst->ss->sync_metadata(tst); sra = sysfs_read(container_fd, -1, 0); if (!sra) { @@ -930,7 +947,7 @@ int Manage_subdevs(char *devname, int fd, sysfs_free(sra); return 1; } - ping_monitor(devnum2devname(devnum)); + ping_monitor_by_id(devnum); sysfs_free(sra); close(container_fd); } else {