diff options
author | NeilBrown <neilb@suse.de> | 2013-04-22 17:05:33 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-04-22 17:05:33 +1000 |
commit | 2fdf559d74a48806900b63f1b4504a18dec048a9 (patch) | |
tree | 77816a7444808c6ce12041d5e6bf36edfd80e695 /Manage.c | |
parent | 79b68f1b48b0967da999945e310aef628c9bca4c (diff) |
Manage_runstop: call flush_mdmon if O_EXCL fails on stopping mdmon array.
When stopping an mdmon array, at reshape might be being aborted
which inhibets O_EXCL. So if that is possible, call flush_mdmon
to make sure mdmon isn't still busy.
Reported-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r-- | Manage.c | 29 |
1 files changed, 24 insertions, 5 deletions
@@ -212,6 +212,7 @@ int Manage_runstop(char *devname, int fd, int runstop, struct stat stb; struct mdinfo *mdi; char devnm[32]; + char container[32]; int err; int count; /* If this is an mdmon managed array, just write 'inactive' @@ -221,11 +222,30 @@ int Manage_runstop(char *devname, int fd, int runstop, /* Get EXCL access first. If this fails, then attempting * to stop is probably a bad idea. */ + mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION); + if (mdi && is_subarray(mdi->text_version)) { + char *sl; + strncpy(container, mdi->text_version+1, sizeof(container)); + container[sizeof(container)-1] = 0; + sl = strchr(container, '/'); + if (sl) + *sl = 0; + } else + container[0] = 0; close(fd); - if (devnm[0] == '/') - fd = open(devname, O_RDONLY|O_EXCL); - else - fd = open_dev_flags(devnm, O_RDONLY|O_EXCL); + count = 5; + while (((fd = ((devnm[0] == '/') + ?open(devname, O_RDONLY|O_EXCL) + :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 + || strcmp(fd2devnm(fd), devnm) != 0) + && container[0] + && mdmon_running(container) + && count) { + if (fd >= 0) + close(fd); + flush_mdmon(container); + count--; + } if (fd < 0 || strcmp(fd2devnm(fd), devnm) != 0) { if (fd >= 0) close(fd); @@ -237,7 +257,6 @@ int Manage_runstop(char *devname, int fd, int runstop, devname); return 1; } - mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION); if (mdi && mdi->array.level > 0 && is_subarray(mdi->text_version)) { |