]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add ping_monitor() to mdadm --wait
authorDan Williams <dan.j.williams@intel.com>
Tue, 16 Sep 2008 03:58:42 +0000 (20:58 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 16 Sep 2008 03:58:42 +0000 (20:58 -0700)
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 <dan.j.williams@intel.com>
Manage.c
Monitor.c
mdadm.h
msg.c
util.c

index 56bc2c3188af1dec8ebcbf6bb866d5584be201f5..76447edacd2be231229cee95ff7d061d1af769dd 100644 (file)
--- 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 &&
index abc2dbd684b24cc578932bcef8bfbedc4e6c458b..b02ab3cedb71b135524300a585227c5dcec09725 100644 (file)
--- 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 3eee61a5adad7de5fc7e32d313c0421a5d911a78..2eaaffd6dff2daad481745d588763a93b0f03410 100644 (file)
--- 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 78fd7f7e26380c9c05e6392438fa2a93ce01b3ad..013bcb99e71fa7e4c2a6bb21f012444507478517 100644 (file)
--- 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 60fe6c0a0c2f9f1d97727da18a9de7f449f41793..7fe835a412411c9cc88e00cad86988af85a09ef1 100644 (file)
--- 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)