From: Mathieu Desnoyers Date: Mon, 27 Jan 2014 04:23:36 +0000 (-0500) Subject: Fix: relayd: notify parent of readiness when all threads ready X-Git-Tag: v2.4.0-rc4~9 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=02a6bb53b6055047e86126a7b39154091d91f215;p=lttng-tools.git Fix: relayd: notify parent of readiness when all threads ready - relayd start using daemonize common lib, - wait for health check thread, listener and live listener threads to be ready before letting the parent know it is ready (in daemon and background modes). Signed-off-by: Mathieu Desnoyers Signed-off-by: David Goulet --- diff --git a/src/bin/lttng-relayd/health-relayd.c b/src/bin/lttng-relayd/health-relayd.c index 01e54d2ea..89b6402fa 100644 --- a/src/bin/lttng-relayd/health-relayd.c +++ b/src/bin/lttng-relayd/health-relayd.c @@ -300,6 +300,8 @@ void *thread_manage_health(void *data) goto error; } + lttng_relay_notify_ready(); + while (1) { DBG("Health check ready"); diff --git a/src/bin/lttng-relayd/live.c b/src/bin/lttng-relayd/live.c index e6f381df7..19322f4a0 100644 --- a/src/bin/lttng-relayd/live.c +++ b/src/bin/lttng-relayd/live.c @@ -259,6 +259,8 @@ void *thread_listener(void *data) goto error_poll_add; } + lttng_relay_notify_ready(); + while (1) { health_code_update(); diff --git a/src/bin/lttng-relayd/lttng-relayd.h b/src/bin/lttng-relayd/lttng-relayd.h index 43d25b331..f2efc9514 100644 --- a/src/bin/lttng-relayd/lttng-relayd.h +++ b/src/bin/lttng-relayd/lttng-relayd.h @@ -238,5 +238,6 @@ extern struct lttng_ht *indexes_ht; extern const char *tracing_group_name; struct relay_stream *relay_stream_find_by_id(uint64_t stream_id); +void lttng_relay_notify_ready(void); #endif /* LTTNG_RELAYD_H */ diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index f5d618abf..e44cfbd10 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,16 @@ /* command line options */ char *opt_output_path; static int opt_daemon, opt_background; + +/* + * We need to wait for listener and live listener threads, as well as + * health check thread, before being ready to signal readiness. + */ +#define NR_LTTNG_RELAY_READY 3 +static int lttng_relay_ready = NR_LTTNG_RELAY_READY; +static int recv_child_signal; /* Set to 1 when a SIGUSR1 signal is received. */ +static pid_t child_ppid; /* Internal parent PID use with daemonize. */ + static struct lttng_uri *control_uri; static struct lttng_uri *data_uri; static struct lttng_uri *live_uri; @@ -369,6 +380,9 @@ void sighandler(int sig) DBG("SIGTERM caught"); stop_threads(); break; + case SIGUSR1: + CMM_STORE_SHARED(recv_child_signal, 1); + break; default: break; } @@ -408,11 +422,26 @@ int set_signal_handler(void) return ret; } - DBG("Signal handler set for SIGTERM, SIGPIPE and SIGINT"); + if ((ret = sigaction(SIGUSR1, &sa, NULL)) < 0) { + PERROR("sigaction"); + return ret; + } + + DBG("Signal handler set for SIGTERM, SIGUSR1, SIGPIPE and SIGINT"); return ret; } +void lttng_relay_notify_ready(void) +{ + /* Notify the parent of the fork() process that we are ready. */ + if (opt_daemon || opt_background) { + if (uatomic_sub_return(<tng_relay_ready, 1) == 0) { + kill(child_ppid, SIGUSR1); + } + } +} + /* * Init thread quit pipe. * @@ -582,6 +611,8 @@ void *relay_thread_listener(void *data) goto error_poll_add; } + lttng_relay_notify_ready(); + while (1) { health_code_update(); @@ -2682,11 +2713,6 @@ int main(int argc, char **argv) void *status; struct relay_local_data *relay_ctx; - /* Create thread quit pipe */ - if ((ret = init_thread_quit_pipe()) < 0) { - goto error; - } - /* Parse arguments */ progname = argv[0]; if ((ret = parse_args(argc, argv)) < 0) { @@ -2713,11 +2739,27 @@ int main(int argc, char **argv) /* Daemonize */ if (opt_daemon || opt_background) { - ret = daemon(0, opt_background); + int i; + + ret = lttng_daemonize(&child_ppid, &recv_child_signal, + !opt_background); if (ret < 0) { - PERROR("daemon"); goto exit; } + + /* + * We are in the child. Make sure all other file + * descriptors are closed, in case we are called with + * more opened file descriptors than the standard ones. + */ + for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) { + (void) close(i); + } + } + + /* Create thread quit pipe */ + if ((ret = init_thread_quit_pipe()) < 0) { + goto error; } /* We need those values for the file/dir creation. */