mdmon: fork and run as a daemon.
authorNeilBrown <neilb@suse.de>
Fri, 18 Jul 2008 06:37:20 +0000 (16:37 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 18 Jul 2008 06:37:20 +0000 (16:37 +1000)
start_mdmon now waits for mdmon to complete initialisation and,
importantly, listen on the socket, before continuing.

Signed-off-by: Neil Brown <neilb@suse.de>
mdmon.c
util.c

diff --git a/mdmon.c b/mdmon.c
index c7d7f68..d35c05b 100644 (file)
--- a/mdmon.c
+++ b/mdmon.c
@@ -32,6 +32,7 @@
 #include       <sys/un.h>
 #include       <sys/mman.h>
 #include       <sys/syscall.h>
 #include       <sys/un.h>
 #include       <sys/mman.h>
 #include       <sys/syscall.h>
+#include       <sys/wait.h>
 #include       <stdio.h>
 #include       <errno.h>
 #include       <string.h>
 #include       <stdio.h>
 #include       <errno.h>
 #include       <string.h>
@@ -175,6 +176,8 @@ int main(int argc, char *argv[])
        struct supertype *container;
        sigset_t set;
        struct sigaction act;
        struct supertype *container;
        sigset_t set;
        struct sigaction act;
+       int pfd[2];
+       int status;
 
        if (argc != 2) {
                fprintf(stderr, "Usage: md-manage /device/name/for/container\n");
 
        if (argc != 2) {
                fprintf(stderr, "Usage: md-manage /device/name/for/container\n");
@@ -192,6 +195,24 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
                exit(1);
        }
 
+       /* Fork, and have the child tell us when they are ready */
+       pipe(pfd);
+       switch(fork()){
+       case -1:
+               fprintf(stderr, "mdmon: failed to fork: %s\n",
+                       strerror(errno));
+               exit(1);
+       case 0: /* child */
+               close(pfd[0]);
+               break;
+       default: /* parent */
+               close(pfd[1]);
+               if (read(pfd[0], &status, sizeof(status)) != sizeof(status)) {
+                       wait(&status);
+                       status = WEXITSTATUS(status);
+               }
+               exit(status);
+       }
        /* hopefully it is a container - we'll check later */
 
        container = malloc(sizeof(*container));
        /* hopefully it is a container - we'll check later */
 
        container = malloc(sizeof(*container));
@@ -268,6 +289,23 @@ int main(int argc, char *argv[])
                exit(3);
        }
 
                exit(3);
        }
 
+       /* Ok, this is close enough.  We can say goodbye to our parent now.
+        */
+       status = 0;
+       write(pfd[1], &status, sizeof(status));
+       close(pfd[1]);
+
+       chdir("/");
+       setsid();
+       close(0);
+       open("/dev/null", O_RDWR);
+       close(1);
+       dup(0);
+#ifndef DEBUG
+       close(2);
+       dup(0);
+#endif
+
        mlockall(MCL_FUTURE);
 
        /* SIGUSR is sent between parent and child.  So both block it
        mlockall(MCL_FUTURE);
 
        /* SIGUSR is sent between parent and child.  So both block it
diff --git a/util.c b/util.c
index fe46f3b..3bf4cbe 100644 (file)
--- a/util.c
+++ b/util.c
@@ -31,6 +31,7 @@
 #include       "md_p.h"
 #include       <sys/socket.h>
 #include       <sys/utsname.h>
 #include       "md_p.h"
 #include       <sys/socket.h>
 #include       <sys/utsname.h>
+#include       <sys/wait.h>
 #include       <sys/un.h>
 #include       <ctype.h>
 #include       <dirent.h>
 #include       <sys/un.h>
 #include       <ctype.h>
 #include       <dirent.h>
@@ -1078,6 +1079,8 @@ int start_mdmon(int devnum)
 {
        int i;
        int len;
 {
        int i;
        int len;
+       pid_t pid;      
+       int status;
        char pathbuf[1024];
        char *paths[4] = {
                pathbuf,
        char pathbuf[1024];
        char *paths[4] = {
                pathbuf,
@@ -1117,7 +1120,10 @@ int start_mdmon(int devnum)
        case -1: fprintf(stderr, Name ": cannot run mdmon. "
                         "Array remains readonly\n");
                return -1;
        case -1: fprintf(stderr, Name ": cannot run mdmon. "
                         "Array remains readonly\n");
                return -1;
-       default: ; /* parent - good */
+       default: /* parent - good */
+               pid = wait(&status);
+               if (pid < 0 || status != 0)
+                       return -1;
        }
        return 0;
 }
        }
        return 0;
 }