summaryrefslogtreecommitdiff
path: root/Manage.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-07-18 16:37:09 +1000
committerNeil Brown <neilb@suse.de>2008-07-18 16:37:09 +1000
commitdaf7a3ce96e517360b0456c3a9cca0771b94462d (patch)
treee1b396121c4b719f912919ada33fa207ec0ae3f3 /Manage.c
parent1eb252b8488bbdd62ad602561fe8a90ef9079271 (diff)
Stop managed arrays more carefully.
If an array is being managed by mdmon, then just write "inactive" to stop it, and let mdmon do the final "clear". This makes sure mdmon has a chance to read the final state and update the metadata properly. After writing "inactive" with use "ping_monitor" to synchronise with mdadm, then STOP the array just in case it is still running, else we will get into an infinite loop in "mdadm -Ss". Signed-off-by: Neil Brown <neilb@suse.de>
Diffstat (limited to 'Manage.c')
-rw-r--r--Manage.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/Manage.c b/Manage.c
index 90b58897..0c6b59cb 100644
--- a/Manage.c
+++ b/Manage.c
@@ -111,15 +111,49 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
} else if (runstop < 0){
struct map_ent *map = NULL;
struct stat stb;
- if (ioctl(fd, STOP_ARRAY, NULL)) {
+ 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
+ ": fail 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);
+ }
+ if (mdi)
+ sysfs_free(mdi);
+
+ if (fd >= 0 && ioctl(fd, STOP_ARRAY, NULL)) {
if (quiet==0)
- fprintf(stderr, Name ": fail to stop array %s: %s\n",
+ fprintf(stderr, Name
+ ": fail to stop array %s: %s\n",
devname, strerror(errno));
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);