X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fmain.c;h=62e149ed2cbdaf574968cbbe93659c48c8907db3;hb=c7759e6a503ebd197dd6a84de0eeaa52fbd0e81f;hp=7e5733ec8c3253432bd61dbac17b0968fefef21a;hpb=a4baae1b0463bc4ce65c2a458c4a941e7fabc594;p=lttng-tools.git diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 7e5733ec8..62e149ed2 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +64,17 @@ /* command line options */ char *opt_output_path; -static int opt_daemon; +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; @@ -131,6 +142,7 @@ static struct option long_options[] = { { "data-port", 1, 0, 'D', }, { "live-port", 1, 0, 'L', }, { "daemonize", 0, 0, 'd', }, + { "background", 0, 0, 'b', }, { "group", 1, 0, 'g', }, { "help", 0, 0, 'h', }, { "output", 1, 0, 'o', }, @@ -150,6 +162,7 @@ void usage(void) fprintf(stderr, "Usage: %s OPTIONS\n\nOptions:\n", progname); fprintf(stderr, " -h, --help Display this usage.\n"); fprintf(stderr, " -d, --daemonize Start as a daemon.\n"); + fprintf(stderr, " -b, --background Start as a daemon, keeping console open.\n"); fprintf(stderr, " -C, --control-port URL Control port listening.\n"); fprintf(stderr, " -D, --data-port URL Data port listening.\n"); fprintf(stderr, " -L, --live-port URL Live view port listening.\n"); @@ -210,6 +223,9 @@ int set_option(int opt, const char *arg, const char *optname) case 'd': opt_daemon = 1; break; + case 'b': + opt_background = 1; + break; case 'g': tracing_group_name = strdup(arg); tracing_group_name_override = 1; @@ -504,6 +520,9 @@ void sighandler(int sig) DBG("SIGTERM caught"); stop_threads(); break; + case SIGUSR1: + CMM_STORE_SHARED(recv_child_signal, 1); + break; default: break; } @@ -543,11 +562,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,7 +616,7 @@ int create_thread_poll_set(struct lttng_poll_event *events, int size) } /* Add quit pipe */ - ret = lttng_poll_add(events, thread_quit_pipe[0], LPOLLIN); + ret = lttng_poll_add(events, thread_quit_pipe[0], LPOLLIN | LPOLLERR); if (ret < 0) { goto error; } @@ -717,6 +751,8 @@ void *relay_thread_listener(void *data) goto error_poll_add; } + lttng_relay_notify_ready(); + while (1) { health_code_update(); @@ -1166,18 +1202,10 @@ void set_viewer_ready_flag(struct relay_command *cmd) * Stream is most probably being cleaned up by the data thread thus * simply continue to the next one. */ + rcu_read_unlock(); continue; } - /* - * If any of the streams in the list doesn't have a ctf_trace assigned, - * it means that we never received the metadata stream, so we have to - * wait until it arrives to make the streams available to the viewer. - */ - if (!stream->ctf_trace) { - goto end; - } - stream->viewer_ready = 1; rcu_read_unlock(); @@ -1186,7 +1214,6 @@ void set_viewer_ready_flag(struct relay_command *cmd) free(node); } -end: return; } @@ -1308,7 +1335,11 @@ int relay_add_stream(struct lttcomm_relayd_hdr *recv_hdr, * stream message is received, this list is emptied and streams are set * with the viewer ready flag. */ - queue_stream_handle(stream->stream_handle, cmd); + if (stream->metadata_flag) { + stream->viewer_ready = 1; + } else { + queue_stream_handle(stream->stream_handle, cmd); + } lttng_ht_node_init_ulong(&stream->stream_n, (unsigned long) stream->stream_handle); @@ -2822,11 +2853,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 = set_options(argc, argv)) < 0) { @@ -2852,12 +2878,28 @@ int main(int argc, char **argv) } /* Daemonize */ - if (opt_daemon) { - ret = daemon(0, 0); + if (opt_daemon || 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. */ @@ -2886,6 +2928,7 @@ int main(int argc, char **argv) /* Initialize communication library */ lttcomm_init(); + lttcomm_inet_init(); relay_ctx = zmalloc(sizeof(struct relay_local_data)); if (!relay_ctx) {