summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--support/include/nfslib.h5
-rw-r--r--support/nfs/mydaemon.c92
-rw-r--r--utils/gssd/gssd.c4
-rw-r--r--utils/gssd/gssd.h1
-rw-r--r--utils/gssd/gssd_main_loop.c3
-rw-r--r--utils/gssd/svcgssd.c8
-rw-r--r--utils/idmapd/idmapd.c6
-rw-r--r--utils/statd/statd.c66
8 files changed, 67 insertions, 118 deletions
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index c5dc6f8..c9a13cb 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -17,6 +17,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
+#include <stdbool.h>
#include <paths.h>
#include <rpcsvc/nfs_prot.h>
#include <nfs/nfs.h>
@@ -129,8 +130,8 @@ void fendrmtabent(FILE *fp);
void frewindrmtabent(FILE *fp);
/* mydaemon */
-void mydaemon(int nochdir, int noclose, int *pipefds);
-void release_parent(int *pipefds);
+void daemon_init(bool fg);
+void daemon_ready(void);
/*
* wildmat borrowed from INN
diff --git a/support/nfs/mydaemon.c b/support/nfs/mydaemon.c
index e885d60..3391eff 100644
--- a/support/nfs/mydaemon.c
+++ b/support/nfs/mydaemon.c
@@ -46,56 +46,61 @@
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <xlog.h>
+#include "nfslib.h"
+
+static int pipefds[2] = { -1, -1};
+
/**
- * mydaemon - daemonize, but have parent wait to exit
- * @nochdir: skip chdir()'ing the child to / after forking if true
- * @noclose: skip closing stdin/stdout/stderr if true
- * @pipefds: pointer to 2 element array of pipefds
+ * daemon_init - initial daemon setup
+ * @fg: whether to run in the foreground
*
* This function is like daemon(), but with our own special sauce to delay
* the exit of the parent until the child is set up properly. A pipe is created
* between parent and child. The parent process will wait to exit until the
- * child dies or writes a '1' on the pipe signaling that it started
- * successfully.
+ * child dies or writes an int on the pipe signaling its status.
*/
void
-mydaemon(int nochdir, int noclose, int *pipefds)
+daemon_init(bool fg)
{
int pid, status, tempfd;
+ if (fg)
+ return;
+
if (pipe(pipefds) < 0) {
xlog_err("mydaemon: pipe() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
- if ((pid = fork ()) < 0) {
+
+ pid = fork();
+ if (pid < 0) {
xlog_err("mydaemon: fork() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
- if (pid != 0) {
- /*
- * Parent. Wait for status from child.
- */
+ if (pid > 0) {
+ /* Parent */
close(pipefds[1]);
- if (read(pipefds[0], &status, 1) != 1)
- exit(1);
- exit (0);
+ if (read(pipefds[0], &status, sizeof(status)) != sizeof(status))
+ exit(EXIT_FAILURE);
+ exit(status);
}
- /* Child. */
+
+ /* Child */
close(pipefds[0]);
setsid ();
- if (nochdir == 0) {
- if (chdir ("/") == -1) {
- xlog_err("mydaemon: chdir() failed: errno %d (%s)\n",
- errno, strerror(errno));
- exit(1);
- }
+
+ if (chdir ("/")) {
+ xlog_err("mydaemon: chdir() failed: errno %d (%s)\n",
+ errno, strerror(errno));
+ exit(EXIT_FAILURE);
}
while (pipefds[1] <= 2) {
@@ -103,41 +108,38 @@ mydaemon(int nochdir, int noclose, int *pipefds)
if (pipefds[1] < 0) {
xlog_err("mydaemon: dup() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
}
- if (noclose == 0) {
- tempfd = open("/dev/null", O_RDWR);
- if (tempfd >= 0) {
- dup2(tempfd, 0);
- dup2(tempfd, 1);
- dup2(tempfd, 2);
- close(tempfd);
- } else {
- xlog_err("mydaemon: can't open /dev/null: errno %d "
- "(%s)\n", errno, strerror(errno));
- exit(1);
- }
+ tempfd = open("/dev/null", O_RDWR);
+ if (tempfd < 0) {
+ xlog_err("mydaemon: can't open /dev/null: errno %d "
+ "(%s)\n", errno, strerror(errno));
+ exit(EXIT_FAILURE);
}
- return;
+ dup2(tempfd, 0);
+ dup2(tempfd, 1);
+ dup2(tempfd, 2);
+ dup2(pipefds[1], 3);
+ pipefds[1] = 3;
+ closeall(4);
}
/**
- * release_parent - tell the parent that it can exit now
- * @pipefds: pipefd array that was previously passed to mydaemon()
+ * daemon_ready - tell interested parties that the daemon is ready
*
- * This function tells the parent process of mydaemon() that it's now clear
- * to exit(0).
+ * This function tells e.g. the parent process that the daemon is up
+ * and running.
*/
void
-release_parent(int *pipefds)
+daemon_ready(void)
{
- int status;
+ int status = 0;
if (pipefds[1] > 0) {
- if (write(pipefds[1], &status, 1) != 1) {
+ if (write(pipefds[1], &status, sizeof(status)) != sizeof(status)) {
xlog_err("WARN: writing to parent pipe failed: errno "
"%d (%s)\n", errno, strerror(errno));
}
diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c
index 6b8b863..dc84b3e 100644
--- a/utils/gssd/gssd.c
+++ b/utils/gssd/gssd.c
@@ -66,7 +66,6 @@ int root_uses_machine_creds = 1;
unsigned int context_timeout = 0;
unsigned int rpc_timeout = 5;
char *preferred_realm = NULL;
-int pipefds[2] = { -1, -1 };
void
sig_die(int signal)
@@ -206,8 +205,7 @@ main(int argc, char *argv[])
if (gssd_check_mechs() != 0)
errx(1, "Problem with gssapi library");
- if (!fg)
- mydaemon(0, 0, pipefds);
+ daemon_init(fg);
signal(SIGINT, sig_die);
signal(SIGTERM, sig_die);
diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h
index 48f4ad8..84479e8 100644
--- a/utils/gssd/gssd.h
+++ b/utils/gssd/gssd.h
@@ -68,7 +68,6 @@ extern int root_uses_machine_creds;
extern unsigned int context_timeout;
extern unsigned int rpc_timeout;
extern char *preferred_realm;
-extern int pipefds[2];
TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
diff --git a/utils/gssd/gssd_main_loop.c b/utils/gssd/gssd_main_loop.c
index 6946ab6..9787883 100644
--- a/utils/gssd/gssd_main_loop.c
+++ b/utils/gssd/gssd_main_loop.c
@@ -252,8 +252,7 @@ gssd_run()
exit(1);
}
- /* release the parent after the initial dir scan */
- release_parent(pipefds);
+ daemon_ready();
}
gssd_poll(pollarray, pollsize);
}
diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c
index 0385725..f1b4347 100644
--- a/utils/gssd/svcgssd.c
+++ b/utils/gssd/svcgssd.c
@@ -62,8 +62,6 @@
#include "gss_util.h"
#include "err_util.h"
-static int pipefds[2] = { -1, -1 };
-
void
sig_die(int signal)
{
@@ -157,8 +155,7 @@ main(int argc, char *argv[])
exit(1);
}
- if (!fg)
- mydaemon(0, 0, pipefds);
+ daemon_init(fg);
signal(SIGINT, sig_die);
signal(SIGTERM, sig_die);
@@ -187,8 +184,7 @@ main(int argc, char *argv[])
}
}
- if (!fg)
- release_parent(pipefds);
+ daemon_ready();
nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
gssd_run();
diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c
index 4246466..689608a 100644
--- a/utils/idmapd/idmapd.c
+++ b/utils/idmapd/idmapd.c
@@ -164,7 +164,6 @@ static char pipefsdir[PATH_MAX];
static char *nobodyuser, *nobodygroup;
static uid_t nobodyuid;
static gid_t nobodygid;
-static int pipefds[2] = { -1, -1 };
/* Used by conffile.c in libnfs.a */
char *conf_path;
@@ -302,8 +301,7 @@ main(int argc, char **argv)
if (nfs4_init_name_mapping(conf_path))
errx(1, "Unable to create name to user id mappings.");
- if (!fg)
- mydaemon(0, 0, pipefds);
+ daemon_init(fg);
event_init();
@@ -380,7 +378,7 @@ main(int argc, char **argv)
if (nfsdret != 0 && fd == 0)
xlog_err("main: Neither NFS client nor NFSd found");
- release_parent(pipefds);
+ daemon_ready();
if (event_dispatch() < 0)
xlog_err("main: event_dispatch returns errno %d (%s)",
diff --git a/utils/statd/statd.c b/utils/statd/statd.c
index 51a016e..60ce6d1 100644
--- a/utils/statd/statd.c
+++ b/utils/statd/statd.c
@@ -248,13 +248,12 @@ int main (int argc, char **argv)
int nlm_udp = 0, nlm_tcp = 0;
struct rlimit rlim;
- int pipefds[2] = { -1, -1};
- char status;
-
/* Default: daemon mode, no other options */
run_mode = 0;
- xlog_stderr(0);
- xlog_syslog(1);
+
+ /* Log to stderr if there's an error during startup */
+ xlog_stderr(1);
+ xlog_syslog(0);
/* Set the basename */
if ((name_p = strrchr(argv[0],'/')) != NULL) {
@@ -394,52 +393,17 @@ int main (int argc, char **argv)
simulator (--argc, ++argv); /* simulator() does exit() */
#endif
- if (!(run_mode & MODE_NODAEMON)) {
- int tempfd;
-
- if (pipe(pipefds)<0) {
- perror("statd: unable to create pipe");
- exit(1);
- }
- if ((pid = fork ()) < 0) {
- perror ("statd: Could not fork");
- exit (1);
- } else if (pid != 0) {
- /* Parent.
- * Wait for status from child.
- */
- close(pipefds[1]);
- if (read(pipefds[0], &status, 1) != 1)
- exit(1);
- exit (0);
- }
- /* Child. */
- close(pipefds[0]);
- setsid ();
-
- while (pipefds[1] <= 2) {
- pipefds[1] = dup(pipefds[1]);
- if (pipefds[1]<0) {
- perror("statd: dup");
- exit(1);
- }
- }
- tempfd = open("/dev/null", O_RDWR);
- dup2(tempfd, 0);
- dup2(tempfd, 1);
- dup2(tempfd, 2);
- dup2(pipefds[1], 3);
- pipefds[1] = 3;
- closeall(4);
- }
-
- /* Child. */
+ daemon_init(!(run_mode & MODE_NODAEMON));
if (run_mode & MODE_LOG_STDERR) {
xlog_syslog(0);
xlog_stderr(1);
xlog_config(D_ALL, 1);
+ } else {
+ xlog_syslog(1);
+ xlog_stderr(0);
}
+
xlog_open(name_p);
xlog(L_NOTICE, "Version " VERSION " starting");
@@ -512,16 +476,8 @@ int main (int argc, char **argv)
}
atexit(statd_unregister);
- /* If we got this far, we have successfully started, so notify parent */
- if (pipefds[1] > 0) {
- status = 0;
- if (write(pipefds[1], &status, 1) != 1) {
- xlog_warn("writing to parent pipe failed: errno %d (%s)\n",
- errno, strerror(errno));
- }
- close(pipefds[1]);
- pipefds[1] = -1;
- }
+ /* If we got this far, we have successfully started */
+ daemon_ready();
for (;;) {
/*