]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdmon.c
mdmon: fork and run as a daemon.
[thirdparty/mdadm.git] / mdmon.c
diff --git a/mdmon.c b/mdmon.c
index 08f4445519af9cb8720b5b15ca43178554654516..d35c05b2d7a9ac779610b3cc932627d318ccdec2 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/wait.h>
 #include       <stdio.h>
 #include       <errno.h>
 #include       <string.h>
@@ -52,7 +53,6 @@ int run_child(void *v)
 {
        struct supertype *c = v;
 
-       mon_tid = syscall(SYS_gettid);
        do_monitor(c);
        return 0;
 }
@@ -60,16 +60,14 @@ int run_child(void *v)
 int clone_monitor(struct supertype *container)
 {
        static char stack[4096];
-       int rv;
 
-
-       rv = clone(run_child, stack+4096-64,
+       mon_tid = clone(run_child, stack+4096-64,
                   CLONE_FS|CLONE_FILES|CLONE_VM|CLONE_SIGHAND|CLONE_THREAD,
                   container);
 
        mgr_tid = syscall(SYS_gettid);
-       
-       return rv;
+
+       return mon_tid;
 }
 
 static struct superswitch *find_metadata_methods(char *vers)
@@ -177,6 +175,9 @@ int main(int argc, char *argv[])
        struct mdinfo *mdi, *di;
        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");
@@ -194,6 +195,24 @@ int main(int argc, char *argv[])
                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));
@@ -269,8 +288,23 @@ int main(int argc, char *argv[])
                        argv[1]);
                exit(3);
        }
-       close(mdfd);
-       close(mdfd);
+
+       /* 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);
 
@@ -280,7 +314,11 @@ int main(int argc, char *argv[])
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);
        sigprocmask(SIG_BLOCK, &set, NULL);
-       signal(SIGUSR1, wake_me);
+       act.sa_handler = wake_me;
+       act.sa_flags = 0;
+       sigaction(SIGUSR1, &act, NULL);
+       act.sa_handler = SIG_IGN;
+       sigaction(SIGPIPE, &act, NULL);
 
        if (clone_monitor(container) < 0) {
                fprintf(stderr, "md-manage: failed to start monitor process: %s\n",