From: Philippe Proulx Date: Thu, 27 Aug 2015 15:52:33 +0000 (-0400) Subject: Daemonize sessiond on `lttng create` X-Git-Tag: v2.7.0-rc2~59 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=550b3e4b614b8ac4d9d90c6216a937861e8fe883;p=lttng-tools.git Daemonize sessiond on `lttng create` Since the session daemon forked by `lttng create` shares its standard output/error FDs when not using `--daemonize`, redirecting the standard output/error of this command to another program "hangs" because the session daemon never terminates. Example that's not working (when sessiond is not running): lttng create | wc or: lttng 2>&1 | wc Using sessiond's `--daemonize` option makes it close its FDs. This option also ensures that when the sessiond process exits, it has forked itself as a daemon and is ready to accept commands. Therefore we don't need to catch SIGCHLD and SIGUSR1; just waitpid() on sessiond's PID and make sure it exited normally and with an exit status of 0 to continue. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng/commands/create.c b/src/bin/lttng/commands/create.c index 94c1c6183..3b679ca71 100644 --- a/src/bin/lttng/commands/create.c +++ b/src/bin/lttng/commands/create.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -562,14 +563,13 @@ static int spawn_sessiond(char *pathname) pid_t pid; MSG("Spawning a session daemon"); - recv_child_signal = 0; pid = fork(); if (pid == 0) { /* - * Spawn session daemon and tell - * it to signal us when ready. + * Spawn session daemon in daemon mode. */ - execlp(pathname, "lttng-sessiond", "--sig-parent", "--quiet", NULL); + execlp(pathname, "lttng-sessiond", + "--daemonize", NULL); /* execlp only returns if error happened */ if (errno == ENOENT) { ERR("No session daemon found. Use --sessiond-path."); @@ -579,25 +579,34 @@ static int spawn_sessiond(char *pathname) kill(getppid(), SIGTERM); /* wake parent */ exit(EXIT_FAILURE); } else if (pid > 0) { - sessiond_pid = pid; - /* - * Wait for lttng-sessiond to start. We need to use a flag to check if - * the signal has been sent to us, because the child can be scheduled - * before the parent, and thus send the signal before this check. In - * the signal handler, we set the recv_child_signal flag, so anytime we - * check it after the fork is fine. Note that sleep() is interrupted - * before the 1 second delay as soon as the signal is received, so it - * will not cause visible delay for the user. - */ - while (!recv_child_signal) { - sleep(1); - } + int status; + /* - * The signal handler will nullify sessiond_pid on SIGCHLD + * In daemon mode (--daemonize), sessiond only exits when + * it's ready to accept commands. */ - if (!sessiond_pid) { - exit(EXIT_FAILURE); + for (;;) { + waitpid(pid, &status, 0); + + if (WIFSIGNALED(status)) { + ERR("Session daemon was killed by signal %d", + WTERMSIG(status)); + ret = -1; + goto end; + } else if (WIFEXITED(status)) { + DBG("Session daemon terminated normally (exit status: %d)", + WEXITSTATUS(status)); + + if (WEXITSTATUS(status) != 0) { + ERR("Session daemon terminated with an error (exit status: %d)", + WEXITSTATUS(status)); + ret = -1; + goto end; + } + break; + } } + goto end; } else { PERROR("fork"); diff --git a/src/bin/lttng/lttng.c b/src/bin/lttng/lttng.c index 4d2df2deb..bf07c83b7 100644 --- a/src/bin/lttng/lttng.c +++ b/src/bin/lttng/lttng.c @@ -38,8 +38,6 @@ static char *progname; int opt_no_sessiond; char *opt_sessiond_path; -pid_t sessiond_pid; -volatile int recv_child_signal; char *opt_relayd_path; @@ -203,26 +201,11 @@ static void clean_exit(int code) */ static void sighandler(int sig) { - int status; - switch (sig) { case SIGTERM: DBG("SIGTERM caught"); clean_exit(EXIT_FAILURE); break; - case SIGCHLD: - DBG("SIGCHLD caught"); - waitpid(sessiond_pid, &status, 0); - recv_child_signal = 1; - /* Indicate that the session daemon died */ - sessiond_pid = 0; - ERR("Session daemon died (exit status %d)", WEXITSTATUS(status)); - break; - case SIGUSR1: - /* Notify is done */ - recv_child_signal = 1; - DBG("SIGUSR1 caught"); - break; default: DBG("Unknown signal %d caught", sig); break; @@ -250,21 +233,12 @@ static int set_signal_handler(void) sa.sa_handler = sighandler; sa.sa_mask = sigset; sa.sa_flags = 0; - if ((ret = sigaction(SIGUSR1, &sa, NULL)) < 0) { - PERROR("sigaction"); - goto end; - } if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) { PERROR("sigaction"); goto end; } - if ((ret = sigaction(SIGCHLD, &sa, NULL)) < 0) { - PERROR("sigaction"); - goto end; - } - end: return ret; } diff --git a/src/bin/lttng/utils.h b/src/bin/lttng/utils.h index 075573193..b0e44f66e 100644 --- a/src/bin/lttng/utils.h +++ b/src/bin/lttng/utils.h @@ -26,7 +26,6 @@ extern char *opt_relayd_path; extern int opt_no_sessiond; extern char * opt_sessiond_path; -extern volatile int recv_child_signal; extern pid_t sessiond_pid; struct cmd_struct;