]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdmon: preserve socket over chroot
authorDan Williams <dan.j.williams@intel.com>
Wed, 14 Oct 2009 00:37:02 +0000 (17:37 -0700)
committerDan Williams <dan.j.williams@intel.com>
Wed, 14 Oct 2009 00:41:58 +0000 (17:41 -0700)
Connect to the monitor in the old namespace and use that connection for
WaitClean requests when stopping the victim mdmon instance.  This allows
ping_monitor() to work post chroot().

Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
mdadm.c
mdadm.h
mdmon.c
msg.c
msg.h
sysfs.c

diff --git a/mdadm.c b/mdadm.c
index bb3e5bb1821827d246ef88f542b2e873cd3c91b4..6f43dc316d3d432f96d628af0461c90987d2a53d 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[])
                                                                     export, test,
                                                                     homehost);
                                                else
-                                                       rv |= WaitClean(name, v);
+                                                       rv |= WaitClean(name, -1, v);
                                                put_md_name(name);
                                        }
                                        free_mdstat(ms);
@@ -1337,7 +1337,7 @@ int main(int argc, char *argv[])
                                case 'W':
                                        rv |= Wait(dv->devname); continue;
                                case Waitclean:
-                                       rv |= WaitClean(dv->devname, verbose-quiet); continue;
+                                       rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
                                }
                                mdfd = open_mddev(dv->devname, 1);
                                if (mdfd>=0) {
diff --git a/mdadm.h b/mdadm.h
index 8212a2c46f060215800d78cc693bc5dd7ea90009..ffa5f5390678548b5f76f0c17973417ff66328e7 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -753,7 +753,7 @@ extern int Monitor(mddev_dev_t devlist,
 
 extern int Kill(char *dev, int force, int quiet, int noexcl);
 extern int Wait(char *dev);
-extern int WaitClean(char *dev, int verbose);
+extern int WaitClean(char *dev, int sock, int verbose);
 
 extern int Incremental(char *devname, int verbose, int runstop,
                       struct supertype *st, char *homehost, int require_homehost,
diff --git a/mdmon.c b/mdmon.c
index d3e8be56259466d59773ada93630dd722a0990b3..50c7be6dfbd20a2ac3278e90a8389f00ef3615c0 100644 (file)
--- a/mdmon.c
+++ b/mdmon.c
@@ -175,7 +175,7 @@ pid_t devname2mdmon(char *devname)
        return pid;
 }
 
-static void try_kill_monitor(pid_t pid, char *devname)
+static void try_kill_monitor(pid_t pid, char *devname, int sock)
 {
        char buf[100];
        int fd;
@@ -205,7 +205,7 @@ static void try_kill_monitor(pid_t pid, char *devname)
        for ( ; mdstat; mdstat = mdstat->next)
                if (is_container_member(mdstat, devname)) {
                        sprintf(buf, "/dev/%s", mdstat->dev);
-                       WaitClean(buf, 0);
+                       WaitClean(buf, sock, 0);
                }
        free_mdstat(mdstat);
 }
@@ -366,6 +366,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
        int status;
        int ignore;
        pid_t victim = -1;
+       int victim_sock = -1;
 
        dprintf("starting mdmon for %s in %s\n",
                devname, switchroot ? : "/");
@@ -502,6 +503,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
                 * the new root
                 */
                victim = devname2mdmon(container->devname);
+               victim_sock = connect_monitor(container->devname);
                if (chroot(switchroot) != 0) {
                        fprintf(stderr, "mdmon: failed to chroot to '%s': %s\n",
                                switchroot, strerror(errno));
@@ -551,8 +553,10 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
                exit(2);
        }
 
-       if (victim > -1)
-               try_kill_monitor(victim, container->devname);
+       if (victim > -1) {
+               try_kill_monitor(victim, container->devname, victim_sock);
+               close(victim_sock);
+       }
        do_manager(container);
 
        exit(0);
diff --git a/msg.c b/msg.c
index 5a4839fad7bf40e6fadd745b7228e15b3df1204e..8d52b948fa639ce4ae02d1a8768cd675b1363d58 100644 (file)
--- a/msg.c
+++ b/msg.c
@@ -177,10 +177,8 @@ int connect_monitor(char *devname)
        return sfd;
 }
 
-/* give the monitor a chance to update the metadata */
-int ping_monitor(char *devname)
+int fping_monitor(int sfd)
 {
-       int sfd = connect_monitor(devname);
        int err = 0;
 
        if (sfd < 0)
@@ -194,6 +192,16 @@ int ping_monitor(char *devname)
        if (!err && wait_reply(sfd, 20) != 0)
                err = -1;
 
+       return err;
+}
+
+
+/* give the monitor a chance to update the metadata */
+int ping_monitor(char *devname)
+{
+       int sfd = connect_monitor(devname);
+       int err = fping_monitor(sfd);
+
        close(sfd);
        return err;
 }
diff --git a/msg.h b/msg.h
index b9bd205d66387bcb5d523cd997a6968cbeb9b7af..f8e89fdccc989a29923026127d8cfdbba8a4ec3d 100644 (file)
--- a/msg.h
+++ b/msg.h
@@ -27,6 +27,7 @@ extern int ack(int fd, int tmo);
 extern int wait_reply(int fd, int tmo);
 extern int connect_monitor(char *devname);
 extern int ping_monitor(char *devname);
+extern int fping_monitor(int sock);
 extern int ping_manager(char *devname);
 
 #define MSG_MAX_LEN (4*1024*1024)
diff --git a/sysfs.c b/sysfs.c
index 81ccb53fe5d23bfd64a60ebb74c753c58e547e40..d327e3df27d954903a1ea57598e1c5423262beeb 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -764,7 +764,7 @@ int sysfs_unique_holder(int devnum, long rdev)
 static char *clean_states[] = {
        "clear", "inactive", "readonly", "read-auto", "clean", NULL };
 
-int WaitClean(char *dev, int verbose)
+int WaitClean(char *dev, int sock, int verbose)
 {
        int fd;
        struct mdinfo *mdi;
@@ -840,7 +840,8 @@ int WaitClean(char *dev, int verbose)
                }
                if (rv < 0)
                        rv = 1;
-               else if (ping_monitor(mdi->text_version) == 0) {
+               else if (fping_monitor(sock) == 0 ||
+                        ping_monitor(mdi->text_version) == 0) {
                        /* we need to ping to close the window between array
                         * state transitioning to clean and the metadata being
                         * marked clean