summaryrefslogtreecommitdiffstats
path: root/mdmon.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-07-18 16:37:20 +1000
committerNeilBrown <neilb@suse.de>2008-07-18 16:37:20 +1000
commit9fe32043178f221526b6d59f3bbce58f777089da (patch)
tree6dc16f33e5fefbd801484f51ef0605af5d22eefb /mdmon.c
parent8dfb8619f928d58ac7369c42e9f94dd0dabfed4b (diff)
downloadmdadm-9fe32043178f221526b6d59f3bbce58f777089da.tar.gz
mdadm-9fe32043178f221526b6d59f3bbce58f777089da.tar.xz
mdadm-9fe32043178f221526b6d59f3bbce58f777089da.zip
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 <neilb@suse.de>
Diffstat (limited to 'mdmon.c')
-rw-r--r--mdmon.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/mdmon.c b/mdmon.c
index c7d7f68..d35c05b 100644
--- 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>
@@ -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