From: NeilBrown Date: Fri, 18 Jul 2008 06:37:20 +0000 (+1000) Subject: mdmon: fork and run as a daemon. X-Git-Tag: mdadm-3.0-devel1~98 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=9fe32043178f221526b6d59f3bbce58f777089da mdmon: fork and run as a daemon. start_mdmon now waits for mdmon to complete initialisation and, importantly, listen on the socket, before continuing. Signed-off-by: Neil Brown --- diff --git a/mdmon.c b/mdmon.c index c7d7f680..d35c05b2 100644 --- a/mdmon.c +++ b/mdmon.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,8 @@ int main(int argc, char *argv[]) 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"); @@ -192,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)); @@ -268,6 +289,23 @@ int main(int argc, char *argv[]) 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 diff --git a/util.c b/util.c index fe46f3b0..3bf4cbe3 100644 --- a/util.c +++ b/util.c @@ -31,6 +31,7 @@ #include "md_p.h" #include #include +#include #include #include #include @@ -1078,6 +1079,8 @@ int start_mdmon(int devnum) { int i; int len; + pid_t pid; + int status; 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; - default: ; /* parent - good */ + default: /* parent - good */ + pid = wait(&status); + if (pid < 0 || status != 0) + return -1; } return 0; }