X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fmain.c;h=36dfc7fb4b88eeee96741178a2d72b87fcfcf720;hb=ae0a0b54ba7b9dc874ec9166aa52a3fbd85d5070;hp=7cb0140c6e40205cdb33cda92fc65016ecffc84d;hpb=a2cc5ee8e8caf1e77cae0d5e25fde03dc20fe199;p=deliverable%2Flttng-tools.git diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 7cb0140c6..36dfc7fb4 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include "version.h" @@ -165,6 +166,9 @@ struct lttng_ht *sessions_ht; /* Relayd health monitoring */ struct health_app *health_relayd; +/* Global fd tracker. */ +struct fd_tracker *the_fd_tracker; + static struct option long_options[] = { { "control-port", 1, 0, 'C', }, { "data-port", 1, 0, 'D', }, @@ -592,13 +596,9 @@ exit: static void print_global_objects(void) { - rcu_register_thread(); - print_viewer_streams(); print_relay_streams(); print_sessions(); - - rcu_unregister_thread(); } /* @@ -621,7 +621,7 @@ static void relayd_cleanup(void) free(opt_output_path); /* Close thread quit pipes */ - utils_close_pipe(thread_quit_pipe); + (void) fd_tracker_util_pipe_close(the_fd_tracker, thread_quit_pipe); uri_free(control_uri); uri_free(data_uri); @@ -783,17 +783,26 @@ void lttng_relay_notify_ready(void) */ static int init_thread_quit_pipe(void) { - int ret; - - ret = utils_create_pipe_cloexec(thread_quit_pipe); + return fd_tracker_util_pipe_open_cloexec(the_fd_tracker, + "Quit pipe", thread_quit_pipe); +} - return ret; +/* + * Init health quit pipe. + * + * Return -1 on error or 0 if all pipes are created. + */ +static int init_health_quit_pipe(void) +{ + return fd_tracker_util_pipe_open_cloexec(the_fd_tracker, + "Health quit pipe", health_quit_pipe); } /* * Create a poll set with O_CLOEXEC and add the thread quit pipe to the set. */ -static int create_thread_poll_set(struct lttng_poll_event *events, int size) +static int create_named_thread_poll_set(struct lttng_poll_event *events, + int size, const char *name) { int ret; @@ -802,10 +811,8 @@ static int create_thread_poll_set(struct lttng_poll_event *events, int size) goto error; } - ret = lttng_poll_create(events, size, LTTNG_CLOEXEC); - if (ret < 0) { - goto error; - } + ret = fd_tracker_util_poll_create(the_fd_tracker, + name, events, 1, LTTNG_CLOEXEC); /* Add quit pipe */ ret = lttng_poll_add(events, thread_quit_pipe[0], LPOLLIN | LPOLLERR); @@ -903,7 +910,7 @@ static void *relay_thread_listener(void *data) * Pass 3 as size here for the thread quit pipe, control and * data socket. */ - ret = create_thread_poll_set(&events, 3); + ret = create_named_thread_poll_set(&events, 3, "Listener thread epoll"); if (ret < 0) { goto error_create_poll; } @@ -1045,7 +1052,7 @@ exit: error: error_poll_add: error_testpoint: - lttng_poll_clean(&events); + (void) fd_tracker_util_poll_clean(the_fd_tracker, &events); error_create_poll: if (data_sock->fd >= 0) { ret = data_sock->ops->close(data_sock); @@ -2936,7 +2943,7 @@ static void *relay_thread_worker(void *data) goto relay_connections_ht_error; } - ret = create_thread_poll_set(&events, 2); + ret = create_named_thread_poll_set(&events, 2, "Worker thread epoll"); if (ret < 0) { goto error_poll_create; } @@ -3208,12 +3215,13 @@ error: } rcu_read_unlock(); - lttng_poll_clean(&events); + (void) fd_tracker_util_poll_clean(the_fd_tracker, &events); error_poll_create: lttng_ht_destroy(relay_connections_ht); relay_connections_ht_error: /* Close relay conn pipes */ - utils_close_pipe(relay_conn_pipe); + (void) fd_tracker_util_pipe_close(the_fd_tracker, + relay_conn_pipe); if (err) { DBG("Thread exited with error"); } @@ -3235,11 +3243,45 @@ error_testpoint: */ static int create_relay_conn_pipe(void) { - int ret; + return fd_tracker_util_pipe_open_cloexec(the_fd_tracker, + "Relayd connection pipe", relay_conn_pipe); +} - ret = utils_create_pipe_cloexec(relay_conn_pipe); +static +int stdio_open(void *data, int *fds) +{ + fds[0] = fileno(stdout); + fds[1] = fileno(stderr); + return 0; +} - return ret; +static +int noop_close(void *data, int *fds) +{ + return 0; +} + +static +int track_stdio(void) +{ + int fds[2]; + const char *names[] = { "stdout", "stderr" }; + + return fd_tracker_open_unsuspendable_fd(the_fd_tracker, fds, + names, 2, stdio_open, NULL); +} + +static +void untrack_stdio(void) +{ + int fds[] = { fileno(stdout), fileno(stderr) }; + + /* + * noop_close is used since we don't really want to close + * the stdio output fds; we merely want to stop tracking them. + */ + (void) fd_tracker_close_unsuspendable_fd(the_fd_tracker, + fds, 2, noop_close, NULL); } /* @@ -3276,6 +3318,11 @@ int main(int argc, char **argv) goto exit_options; } + ret = fclose(stdin); + if (ret) { + PERROR("Failed to close stdin"); + goto exit_options; + } /* Try to create directory if -o, --output is specified. */ if (opt_output_path) { if (*opt_output_path != '/') { @@ -3295,26 +3342,14 @@ int main(int argc, char **argv) /* Daemonize */ if (opt_daemon || opt_background) { - int i; - ret = lttng_daemonize(&child_ppid, &recv_child_signal, !opt_background); if (ret < 0) { retval = -1; goto exit_options; } - - /* - * 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); - } } - if (opt_working_directory) { ret = utils_change_working_dir(opt_working_directory); if (ret) { @@ -3322,6 +3357,25 @@ int main(int argc, char **argv) goto exit_options; } } + /* + * The RCU thread registration (and use, through the fd-tracker's + * creation) is done after the daemonization to allow us to not + * deal with liburcu's fork() management as the call RCU needs to + * be restored. + */ + rcu_register_thread(); + + the_fd_tracker = fd_tracker_create(lttng_opt_fd_cap); + if (!the_fd_tracker) { + retval = -1; + goto exit_options; + } + + ret = track_stdio(); + if (ret) { + retval = -1; + goto exit_options; + } /* Initialize thread health monitoring */ health_relayd = health_app_create(NR_HEALTH_RELAYD_TYPES); @@ -3371,7 +3425,7 @@ int main(int argc, char **argv) goto exit_init_data; } - ret = utils_create_pipe(health_quit_pipe); + ret = init_health_quit_pipe(); if (ret) { retval = -1; goto exit_health_quit_pipe; @@ -3467,7 +3521,7 @@ exit_dispatcher_thread: } exit_health_thread: - utils_close_pipe(health_quit_pipe); + (void) fd_tracker_util_pipe_close(the_fd_tracker, health_quit_pipe); exit_health_quit_pipe: exit_init_data: @@ -3485,6 +3539,14 @@ exit_options: /* Ensure all prior call_rcu are done. */ rcu_barrier(); + untrack_stdio(); + /* + * fd_tracker_destroy() will log the contents of the fd-tracker + * if a leak is detected. + */ + fd_tracker_destroy(the_fd_tracker); + rcu_unregister_thread(); + if (!retval) { exit(EXIT_SUCCESS); } else {