Fix: relayd: notify parent of readiness when all threads ready
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 27 Jan 2014 04:23:36 +0000 (23:23 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Tue, 28 Jan 2014 21:20:45 +0000 (16:20 -0500)
- 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 <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-relayd/health-relayd.c
src/bin/lttng-relayd/live.c
src/bin/lttng-relayd/lttng-relayd.h
src/bin/lttng-relayd/main.c

index 01e54d2eae795a35e87d94dd6f06b51ef96be3ac..89b6402fabad3e62ff69c5e9e8b62e5c15d0d0b8 100644 (file)
@@ -300,6 +300,8 @@ void *thread_manage_health(void *data)
                goto error;
        }
 
+       lttng_relay_notify_ready();
+
        while (1) {
                DBG("Health check ready");
 
index e6f381df7678b274f28b5924b73d6133839f501e..19322f4a07bd718feba6d95167715da2d3612e62 100644 (file)
@@ -259,6 +259,8 @@ void *thread_listener(void *data)
                goto error_poll_add;
        }
 
+       lttng_relay_notify_ready();
+
        while (1) {
                health_code_update();
 
index 43d25b331bc6dfbbe31328077f3511228c2f4ed5..f2efc95144cfe8813b61f75e0338d3d23c86440c 100644 (file)
@@ -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 */
index f5d618abf0bc43ce9a1d2f105d88d46e41e1446d..e44cfbd102b63c31a2a386eb291a9e883299058c 100644 (file)
@@ -44,6 +44,7 @@
 #include <common/compat/poll.h>
 #include <common/compat/socket.h>
 #include <common/defaults.h>
+#include <common/daemonize.h>
 #include <common/futex.h>
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/sessiond-comm/inet.h>
 /* 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(&lttng_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. */
This page took 0.031974 seconds and 4 git commands to generate.