From: Dan Williams Date: Tue, 16 Sep 2008 03:58:42 +0000 (-0700) Subject: Add ping_monitor() to mdadm --wait X-Git-Tag: mdadm-3.0-devel1~27 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=c94709e83f662c4780aa9c6917b03c774747eca5;hp=0c0c44db5ae98452c9c69bffc35b031c9fd7acea Add ping_monitor() to mdadm --wait The action we are waiting for may not be complete until the monitor has had a chance to take action on the result. The following script can now remove the device on the first attempt, versus a few attempts with the original Wait(): #!/bin/bash #export MDADM_NO_MDMON=1 export IMSM_DEVNAME_AS_SERIAL=1 ./mdadm -Ss ./mdadm --zero-superblock /dev/loop[0-3] echo 2 > /proc/sys/dev/raid/speed_limit_max ./mdadm --create /dev/imsm /dev/loop[0-3] -n 4 -e imsm -a md ./mdadm --create /dev/md/r1 /dev/loop[0-3] -n 4 -l 5 --force -a mdp ./mdadm --fail /dev/md/r1 /dev/loop3 ./mdadm --wait /dev/md/r1 x=0 while ! ./mdadm --remove /dev/imsm /dev/loop3 > /dev/null 2>&1 do x=$((x+1)) done echo "removed after $x attempts" ./mdadm --add /dev/imsm /dev/loop3 Include 2 small cleanups: * remove the almost open coded fd2devnum() in Wait() by introducing a new utility routine stat2devnum() * teach connect_monitor() to parse the container device from a subarray string Signed-off-by: Dan Williams --- diff --git a/Manage.c b/Manage.c index 56bc2c31..76447eda 100644 --- a/Manage.c +++ b/Manage.c @@ -167,8 +167,6 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet) if (mdi && mdi->array.level > 0 && is_subarray(mdi->text_version)) { - char *cp; - /* This is mdmon managed. */ close(fd); if (sysfs_set_str(mdi, NULL, @@ -181,10 +179,7 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet) } /* Give monitor a chance to act */ - cp = strchr(mdi->text_version+1, '/'); - if (*cp) - *cp = 0; - ping_monitor(mdi->text_version+1); + ping_monitor(mdi->text_version); fd = open(devname, O_RDONLY); } else if (mdi && diff --git a/Monitor.c b/Monitor.c index abc2dbd6..b02ab3ce 100644 --- a/Monitor.c +++ b/Monitor.c @@ -602,10 +602,7 @@ int Wait(char *dev) strerror(errno)); return 2; } - if (major(stb.st_rdev) == MD_MAJOR) - devnum = minor(stb.st_rdev); - else - devnum = -1-(minor(stb.st_rdev)/64); + devnum = stat2devnum(&stb); while(1) { struct mdstat_ent *ms = mdstat_read(1, 0); @@ -616,6 +613,13 @@ int Wait(char *dev) break; if (!e || e->percent < 0) { + if (e && + strncmp(e->metadata_version, "external:", 9) == 0) { + if (is_subarray(&e->metadata_version[9])) + ping_monitor(&e->metadata_version[9]); + else + ping_monitor(devnum2devname(devnum)); + } free_mdstat(ms); return rv; } diff --git a/mdadm.h b/mdadm.h index 3eee61a5..2eaaffd6 100644 --- a/mdadm.h +++ b/mdadm.h @@ -785,6 +785,7 @@ extern int start_mdmon(int devnum); extern char *devnum2devname(int num); extern int devname2devnum(char *name); +extern int stat2devnum(struct stat *st); extern int fd2devnum(int fd); static inline int dev2major(int d) diff --git a/msg.c b/msg.c index 78fd7f7e..013bcb99 100644 --- a/msg.c +++ b/msg.c @@ -144,8 +144,21 @@ int connect_monitor(char *devname) int sfd; long fl; struct sockaddr_un addr; + int pos; + char *c; + + pos = sprintf(path, "/var/run/mdadm/"); + if (is_subarray(devname)) { + devname++; + c = strchr(devname, '/'); + if (!c) + return -1; + snprintf(&path[pos], c - devname + 1, "%s", devname); + pos += c - devname; + } else + pos += sprintf(&path[pos], "%s", devname); + sprintf(&path[pos], ".sock"); - sprintf(path, "/var/run/mdadm/%s.sock", devname); sfd = socket(PF_LOCAL, SOCK_STREAM, 0); if (sfd < 0) return -1; diff --git a/util.c b/util.c index 60fe6c0a..7fe835a4 100644 --- a/util.c +++ b/util.c @@ -1022,17 +1022,24 @@ int devname2devnum(char *name) return num; } -int fd2devnum(int fd) +int stat2devnum(struct stat *st) { - struct stat stb; - if (fstat(fd, &stb) == 0 && - (S_IFMT&stb.st_mode)==S_IFBLK) { - if (major(stb.st_rdev) == MD_MAJOR) - return minor(stb.st_rdev); + if ((S_IFMT & st->st_mode) == S_IFBLK) { + if (major(st->st_rdev) == MD_MAJOR) + return minor(st->st_rdev); else - return -1- (minor(stb.st_rdev)>>6); + return -1- (minor(st->st_rdev)>>6); } return -1; + +} + +int fd2devnum(int fd) +{ + struct stat stb; + if (fstat(fd, &stb) == 0) + return stat2devnum(&stb); + return -1; } int mdmon_running(int devnum)