X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=67d990027f523079e3ae5635f5ec605573bc9c20;hp=cec8e835e04881c20c65787c19a560bc19756c58;hb=8e319828707210e48a5f3e74495881594dba73e8;hpb=f28f9e449e13d6a3495408e5329514fa5ca7150e diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index cec8e835e..67d990027 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -49,6 +49,9 @@ #include #include #include +#include +#include +#include #include "lttng-sessiond.h" #include "buffer-registry.h" @@ -78,7 +81,7 @@ #include "agent.h" #include "ht-cleanup.h" #include "sessiond-config.h" -#include "sessiond-timer.h" +#include "timer.h" static const char *help_msg = #ifdef LTTNG_EMBED_HELP @@ -108,7 +111,6 @@ static struct consumer_data kconsumer_data = { .err_sock = -1, .cmd_sock = -1, .channel_monitor_pipe = -1, - .channel_rotate_pipe = -1, .pid_mutex = PTHREAD_MUTEX_INITIALIZER, .lock = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER, @@ -119,7 +121,6 @@ static struct consumer_data ustconsumer64_data = { .err_sock = -1, .cmd_sock = -1, .channel_monitor_pipe = -1, - .channel_rotate_pipe = -1, .pid_mutex = PTHREAD_MUTEX_INITIALIZER, .lock = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER, @@ -130,7 +131,6 @@ static struct consumer_data ustconsumer32_data = { .err_sock = -1, .cmd_sock = -1, .channel_monitor_pipe = -1, - .channel_rotate_pipe = -1, .pid_mutex = PTHREAD_MUTEX_INITIALIZER, .lock = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER, @@ -299,13 +299,41 @@ struct rotation_thread_handle *rotation_thread_handle; struct lttng_ht *agent_apps_ht_by_sock = NULL; /* - * Whether sessiond is ready for commands/notification channel/health check + * The initialization of the session daemon is done in multiple phases. + * + * While all threads are launched near-simultaneously, only some of them + * are needed to ensure the session daemon can start to respond to client * requests. - * NR_LTTNG_SESSIOND_READY must match the number of calls to - * sessiond_notify_ready(). + * + * There are two important guarantees that we wish to offer with respect + * to the initialisation of the session daemon: + * - When the daemonize/background launcher process exits, the sessiond + * is fully able to respond to client requests, + * - Auto-loaded sessions are visible to clients. + * + * In order to achieve this, a number of support threads have to be launched + * to allow the "client" thread to function properly. Moreover, since the + * "load session" thread needs the client thread, we must provide a way + * for the "load session" thread to know that the "client" thread is up + * and running. + * + * Hence, the support threads decrement the lttng_sessiond_ready counter + * while the "client" threads waits for it to reach 0. Once the "client" thread + * unblocks, it posts the message_thread_ready semaphore which allows the + * "load session" thread to progress. + * + * This implies that the "load session" thread is the last to be initialized + * and will explicitly call sessiond_signal_parents(), which signals the parents + * that the session daemon is fully initialized. + * + * The four (4) support threads are: + * - agent_thread + * - notification_thread + * - rotation_thread + * - health_thread */ -#define NR_LTTNG_SESSIOND_READY 6 -int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY; +#define NR_LTTNG_SESSIOND_SUPPORT_THREADS 4 +int lttng_sessiond_ready = NR_LTTNG_SESSIOND_SUPPORT_THREADS; int sessiond_check_thread_quit_pipe(int fd, uint32_t events) { @@ -314,28 +342,47 @@ int sessiond_check_thread_quit_pipe(int fd, uint32_t events) /* Notify parents that we are ready for cmd and health check */ LTTNG_HIDDEN -void sessiond_notify_ready(void) +void sessiond_signal_parents(void) { - if (uatomic_sub_return(<tng_sessiond_ready, 1) == 0) { - /* - * Notify parent pid that we are ready to accept command - * for client side. This ppid is the one from the - * external process that spawned us. - */ - if (config.sig_parent) { - kill(ppid, SIGUSR1); - } + /* + * Notify parent pid that we are ready to accept command + * for client side. This ppid is the one from the + * external process that spawned us. + */ + if (config.sig_parent) { + kill(ppid, SIGUSR1); + } - /* - * Notify the parent of the fork() process that we are - * ready. - */ - if (config.daemonize || config.background) { - kill(child_ppid, SIGUSR1); - } + /* + * Notify the parent of the fork() process that we are + * ready. + */ + if (config.daemonize || config.background) { + kill(child_ppid, SIGUSR1); } } +LTTNG_HIDDEN +void sessiond_notify_ready(void) +{ + /* + * This memory barrier is paired with the one performed by + * the client thread after it has seen that 'lttng_sessiond_ready' is 0. + * + * The purpose of these memory barriers is to ensure that all + * initialization operations of the various threads that call this + * function to signal that they are ready are commited/published + * before the client thread can see the 'lttng_sessiond_ready' counter + * reach 0. + * + * Note that this could be a 'write' memory barrier, but a full barrier + * is used in case the code using this utility changes. The performance + * implications of this choice are minimal since this is a slow path. + */ + cmm_smp_mb(); + uatomic_sub(<tng_sessiond_ready, 1); +} + static int __sessiond_set_thread_pollset(struct lttng_poll_event *events, size_t size, int *a_pipe) @@ -481,24 +528,6 @@ static void close_consumer_sockets(void) PERROR("UST consumerd64 channel monitor pipe close"); } } - if (kconsumer_data.channel_rotate_pipe >= 0) { - ret = close(kconsumer_data.channel_rotate_pipe); - if (ret < 0) { - PERROR("kernel consumer channel rotate pipe close"); - } - } - if (ustconsumer32_data.channel_rotate_pipe >= 0) { - ret = close(ustconsumer32_data.channel_rotate_pipe); - if (ret < 0) { - PERROR("UST consumerd32 channel rotate pipe close"); - } - } - if (ustconsumer64_data.channel_rotate_pipe >= 0) { - ret = close(ustconsumer64_data.channel_rotate_pipe); - if (ret < 0) { - PERROR("UST consumerd64 channel rotate pipe close"); - } - } } /* @@ -544,15 +573,9 @@ static void sessiond_cleanup(void) */ utils_close_pipe(thread_quit_pipe); - /* - * If config.pid_file_path.value is undefined, the default file will be - * wiped when removing the rundir. - */ - if (config.pid_file_path.value) { - ret = remove(config.pid_file_path.value); - if (ret < 0) { - PERROR("remove pidfile %s", config.pid_file_path.value); - } + ret = remove(config.pid_file_path.value); + if (ret < 0) { + PERROR("remove pidfile %s", config.pid_file_path.value); } DBG("Removing sessiond and consumerd content of directory %s", @@ -811,7 +834,7 @@ error: * * Useful for CPU hotplug feature. */ -static int update_kernel_stream(struct consumer_data *consumer_data, int fd) +static int update_kernel_stream(int fd) { int ret = 0; struct ltt_session *session; @@ -860,7 +883,7 @@ static int update_kernel_stream(struct consumer_data *consumer_data, int fd) cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter, socket, node.node) { pthread_mutex_lock(socket->lock); - ret = kernel_consumer_send_channel_stream(socket, + ret = kernel_consumer_send_channel_streams(socket, channel, ksess, session->output_traces ? 1 : 0); pthread_mutex_unlock(socket->lock); @@ -1045,7 +1068,7 @@ static void *thread_manage_kernel(void *data) * New CPU detected by the kernel. Adding kernel stream to * kernel session and updating the kernel consumer */ - ret = update_kernel_stream(&kconsumer_data, pollfd); + ret = update_kernel_stream(pollfd); if (ret < 0) { continue; } @@ -1281,8 +1304,7 @@ restart: /* * Transfer the write-end of the channel monitoring and rotate pipe - * to the consumer by issuing a SET_CHANNEL_MONITOR_PIPE and - * SET_CHANNEL_ROTATE_PIPE commands. + * to the consumer by issuing a SET_CHANNEL_MONITOR_PIPE command. */ cmd_socket_wrapper = consumer_allocate_socket(&consumer_data->cmd_sock); if (!cmd_socket_wrapper) { @@ -1296,12 +1318,6 @@ restart: goto error; } - ret = consumer_send_channel_rotate_pipe(cmd_socket_wrapper, - consumer_data->channel_rotate_pipe); - if (ret) { - goto error; - } - /* Discard the socket wrapper as it is no longer needed. */ consumer_destroy_socket(cmd_socket_wrapper); cmd_socket_wrapper = NULL; @@ -2458,7 +2474,8 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) } else if (stat(INSTALL_BIN_PATH "/" DEFAULT_CONSUMERD_FILE, &st) == 0) { DBG3("Found location #2"); consumer_to_use = INSTALL_BIN_PATH "/" DEFAULT_CONSUMERD_FILE; - } else if (stat(config.consumerd32_bin_path.value, &st) == 0) { + } else if (config.consumerd32_bin_path.value && + stat(config.consumerd32_bin_path.value, &st) == 0) { DBG3("Found location #3"); consumer_to_use = config.consumerd32_bin_path.value; } else { @@ -2889,6 +2906,112 @@ static unsigned int lttng_sessions_count(uid_t uid, gid_t gid) return i; } +static int receive_userspace_probe(struct command_ctx *cmd_ctx, int sock, + int *sock_error, struct lttng_event *event) +{ + int fd, ret; + struct lttng_userspace_probe_location *probe_location; + const struct lttng_userspace_probe_location_lookup_method *lookup = NULL; + struct lttng_dynamic_buffer probe_location_buffer; + struct lttng_buffer_view buffer_view; + + /* + * Create a buffer to store the serialized version of the probe + * location. + */ + lttng_dynamic_buffer_init(&probe_location_buffer); + ret = lttng_dynamic_buffer_set_size(&probe_location_buffer, + cmd_ctx->lsm->u.enable.userspace_probe_location_len); + if (ret) { + ret = LTTNG_ERR_NOMEM; + goto error; + } + + /* + * Receive the probe location. + */ + ret = lttcomm_recv_unix_sock(sock, probe_location_buffer.data, + probe_location_buffer.size); + if (ret <= 0) { + DBG("Nothing recv() from client var len data... continuing"); + *sock_error = 1; + lttng_dynamic_buffer_reset(&probe_location_buffer); + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + buffer_view = lttng_buffer_view_from_dynamic_buffer( + &probe_location_buffer, 0, probe_location_buffer.size); + + /* + * Extract the probe location from the serialized version. + */ + ret = lttng_userspace_probe_location_create_from_buffer( + &buffer_view, &probe_location); + if (ret < 0) { + WARN("Failed to create a userspace probe location from the received buffer"); + lttng_dynamic_buffer_reset( &probe_location_buffer); + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + /* + * Receive the file descriptor to the target binary from the client. + */ + DBG("Receiving userspace probe target FD from client ..."); + ret = lttcomm_recv_fds_unix_sock(sock, &fd, 1); + if (ret <= 0) { + DBG("Nothing recv() from client userspace probe fd... continuing"); + *sock_error = 1; + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + /* + * Set the file descriptor received from the client through the unix + * socket in the probe location. + */ + lookup = lttng_userspace_probe_location_get_lookup_method(probe_location); + if (!lookup) { + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + /* + * From the kernel tracer's perspective, all userspace probe event types + * are all the same: a file and an offset. + */ + switch (lttng_userspace_probe_location_lookup_method_get_type(lookup)) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + ret = lttng_userspace_probe_location_function_set_binary_fd( + probe_location, fd); + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + ret = lttng_userspace_probe_location_tracepoint_set_binary_fd( + probe_location, fd); + break; + default: + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + if (ret) { + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + /* Attach the probe location to the event. */ + ret = lttng_event_set_userspace_probe_location(event, probe_location); + if (ret) { + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + lttng_dynamic_buffer_reset(&probe_location_buffer); +error: + return ret; +} + /* * Check if the current kernel tracer supports the session rotation feature. * Return 1 if it does, 0 otherwise. @@ -2951,10 +3074,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_UNREGISTER_TRIGGER: case LTTNG_ROTATE_SESSION: case LTTNG_ROTATION_GET_INFO: - case LTTNG_SESSION_GET_CURRENT_OUTPUT: case LTTNG_ROTATION_SET_SCHEDULE: - case LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD: - case LTTNG_ROTATION_SCHEDULE_GET_SIZE: + case LTTNG_SESSION_LIST_ROTATION_SCHEDULES: need_domain = 0; break; default: @@ -2999,8 +3120,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_DATA_PENDING: case LTTNG_ROTATE_SESSION: case LTTNG_ROTATION_GET_INFO: - case LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD: - case LTTNG_ROTATION_SCHEDULE_GET_SIZE: + case LTTNG_SESSION_LIST_ROTATION_SCHEDULES: break; default: /* Setup lttng message with no payload */ @@ -3218,7 +3338,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, } /* - * Setup socket for consumer 64 bit. No need for atomic access + * Setup socket for consumer 32 bit. No need for atomic access * since it was set above and can ONLY be set in this thread. */ ret = consumer_create_socket(&ustconsumer32_data, @@ -3429,6 +3549,7 @@ error_add_context: } case LTTNG_ENABLE_EVENT: { + struct lttng_event *ev = NULL; struct lttng_event_exclusion *exclusion = NULL; struct lttng_filter_bytecode *bytecode = NULL; char *filter_expression = NULL; @@ -3480,7 +3601,7 @@ error_add_context: ret = lttcomm_recv_unix_sock(sock, filter_expression, expression_len); if (ret <= 0) { - DBG("Nothing recv() from client car len data... continuing"); + DBG("Nothing recv() from client var len data... continuing"); *sock_error = 1; free(filter_expression); free(exclusion); @@ -3512,7 +3633,7 @@ error_add_context: DBG("Receiving var len filter's bytecode from client ..."); ret = lttcomm_recv_unix_sock(sock, bytecode, bytecode_len); if (ret <= 0) { - DBG("Nothing recv() from client car len data... continuing"); + DBG("Nothing recv() from client var len data... continuing"); *sock_error = 1; free(filter_expression); free(bytecode); @@ -3530,11 +3651,36 @@ error_add_context: } } + ev = lttng_event_copy(&cmd_ctx->lsm->u.enable.event); + if (!ev) { + DBG("Failed to copy event: %s", + cmd_ctx->lsm->u.enable.event.name); + free(filter_expression); + free(bytecode); + free(exclusion); + ret = LTTNG_ERR_NOMEM; + goto error; + } + + + if (cmd_ctx->lsm->u.enable.userspace_probe_location_len > 0) { + /* Expect a userspace probe description. */ + ret = receive_userspace_probe(cmd_ctx, sock, sock_error, ev); + if (ret) { + free(filter_expression); + free(bytecode); + free(exclusion); + lttng_event_destroy(ev); + goto error; + } + } + ret = cmd_enable_event(cmd_ctx->session, &cmd_ctx->lsm->domain, cmd_ctx->lsm->u.enable.channel_name, - &cmd_ctx->lsm->u.enable.event, + ev, filter_expression, bytecode, exclusion, kernel_poll_pipe[1]); + lttng_event_destroy(ev); break; } case LTTNG_LIST_TRACEPOINTS: @@ -4155,39 +4301,26 @@ error_add_context: ret = LTTNG_OK; break; } - case LTTNG_SESSION_GET_CURRENT_OUTPUT: - { - struct lttng_session_get_current_output_return output_return; - - memset(&output_return, 0, sizeof(output_return)); - ret = cmd_session_get_current_output(cmd_ctx->session, - &output_return); - if (ret < 0) { - ret = -ret; - goto error; - } - - ret = setup_lttng_msg_no_cmd_header(cmd_ctx, &output_return, - sizeof(output_return)); - if (ret < 0) { - ret = -ret; - goto error; - } - - ret = LTTNG_OK; - break; - } case LTTNG_ROTATION_SET_SCHEDULE: { + bool set_schedule; + enum lttng_rotation_schedule_type schedule_type; + uint64_t value; + if (cmd_ctx->session->kernel_session && !check_rotate_compatible()) { DBG("Kernel tracer version does not support session rotations"); ret = LTTNG_ERR_ROTATION_WRONG_VERSION; goto error; } + set_schedule = cmd_ctx->lsm->u.rotation_set_schedule.set == 1; + schedule_type = (enum lttng_rotation_schedule_type) cmd_ctx->lsm->u.rotation_set_schedule.type; + value = cmd_ctx->lsm->u.rotation_set_schedule.value; + ret = cmd_rotation_set_schedule(cmd_ctx->session, - cmd_ctx->lsm->u.rotate_setup.timer_us, - cmd_ctx->lsm->u.rotate_setup.size, + set_schedule, + schedule_type, + value, notification_thread_handle); if (ret != LTTNG_OK) { goto error; @@ -4195,42 +4328,17 @@ error_add_context: break; } - case LTTNG_ROTATION_SCHEDULE_GET_TIMER_PERIOD: - { - struct lttng_rotation_schedule_get_timer_period *get_timer; - - get_timer = zmalloc(sizeof(struct lttng_rotation_schedule_get_timer_period)); - if (!get_timer) { - ret = ENOMEM; - goto error; - } - get_timer->rotate_timer = cmd_ctx->session->rotate_timer_period; - - ret = setup_lttng_msg_no_cmd_header(cmd_ctx, get_timer, - sizeof(struct lttng_rotation_schedule_get_timer_period)); - free(get_timer); - if (ret < 0) { - ret = -ret; - goto error; - } - - ret = LTTNG_OK; - break; - } - case LTTNG_ROTATION_SCHEDULE_GET_SIZE: + case LTTNG_SESSION_LIST_ROTATION_SCHEDULES: { - struct lttng_rotation_schedule_get_size *get_size; - - get_size = zmalloc(sizeof(struct lttng_rotation_schedule_get_size)); - if (!get_size) { - ret = ENOMEM; - goto error; - } - get_size->rotate_size = cmd_ctx->session->rotate_size; - - ret = setup_lttng_msg_no_cmd_header(cmd_ctx, get_size, - sizeof(struct lttng_rotation_schedule_get_size)); - free(get_size); + struct lttng_session_list_schedules_return schedules = { + .periodic.set = !!cmd_ctx->session->rotate_timer_period, + .periodic.value = cmd_ctx->session->rotate_timer_period, + .size.set = !!cmd_ctx->session->rotate_size, + .size.value = cmd_ctx->session->rotate_size, + }; + + ret = setup_lttng_msg_no_cmd_header(cmd_ctx, &schedules, + sizeof(schedules)); if (ret < 0) { ret = -ret; goto error; @@ -4495,8 +4603,6 @@ static void *thread_manage_clients(void *data) goto error; } - sessiond_notify_ready(); - ret = sem_post(&load_info->message_thread_ready); if (ret) { PERROR("sem_post message_thread_ready"); @@ -4530,6 +4636,16 @@ static void *thread_manage_clients(void *data) goto exit; } } + /* + * This barrier is paired with the one in sessiond_notify_ready() to + * ensure that loads accessing data initialized by the other threads, + * on which this thread was waiting, are not performed before this point. + * + * Note that this could be a 'read' memory barrier, but a full barrier + * is used in case the code changes. The performance implications of + * this choice are minimal since this is a slow path. + */ + cmm_smp_mb(); /* This testpoint is after we signal readiness to the parent. */ if (testpoint(sessiond_thread_manage_clients)) { @@ -4543,6 +4659,8 @@ static void *thread_manage_clients(void *data) health_code_update(); while (1) { + const struct cmd_completion_handler *cmd_completion_handler; + DBG("Accepting client command ..."); /* Inifinite blocking call, waiting for transmission */ @@ -4685,6 +4803,18 @@ static void *thread_manage_clients(void *data) continue; } + cmd_completion_handler = cmd_pop_completion_handler(); + if (cmd_completion_handler) { + enum lttng_error_code completion_code; + + completion_code = cmd_completion_handler->run( + cmd_completion_handler->data); + if (completion_code != LTTNG_OK) { + clean_command_ctx(&cmd_ctx); + continue; + } + } + health_code_update(); DBG("Sending response (size: %d, retcode: %s (%d))", @@ -5062,8 +5192,8 @@ static int set_option(int opt, const char *arg, const char *optname) ERR("Port overflow in --agent-tcp-port parameter: %s", arg); return -1; } - config.agent_tcp_port = (uint32_t) v; - DBG3("Agent TCP port set to non default: %u", config.agent_tcp_port); + config.agent_tcp_port.begin = config.agent_tcp_port.end = (int) v; + DBG3("Agent TCP port set to non default: %i", (int) v); } } else if (string_match(optname, "load") || opt == 'l') { if (!arg || *arg == '\0') { @@ -5655,15 +5785,6 @@ static int write_pidfile(void) return utils_create_pid_file(getpid(), config.pid_file_path.value); } -/* - * Write agent TCP port using the rundir. - */ -static int write_agent_port(void) -{ - return utils_create_pid_file(config.agent_tcp_port, - config.agent_port_file_path.value); -} - static int set_clock_plugin_env(void) { int ret = 0; @@ -5693,48 +5814,6 @@ end: return ret; } -static -struct rotation_thread_timer_queue *create_rotate_timer_queue(void) -{ - struct rotation_thread_timer_queue *queue = NULL; - - queue = zmalloc(sizeof(struct rotation_thread_timer_queue)); - if (!queue) { - PERROR("Failed to allocate timer rotate queue"); - goto end; - } - - queue->event_pipe = lttng_pipe_open(FD_CLOEXEC | O_NONBLOCK); - CDS_INIT_LIST_HEAD(&queue->list); - pthread_mutex_init(&queue->lock, NULL); - -end: - return queue; -} - -static -void destroy_rotate_timer_queue(struct rotation_thread_timer_queue *queue) -{ - struct sessiond_rotation_timer *node, *tmp_node; - - if (!queue) { - return; - } - - lttng_pipe_destroy(queue->event_pipe); - - pthread_mutex_lock(&queue->lock); - /* Empty wait queue. */ - cds_list_for_each_entry_safe(node, tmp_node, &queue->list, head) { - cds_list_del(&node->head); - free(node); - } - pthread_mutex_unlock(&queue->lock); - - pthread_mutex_destroy(&queue->lock); - free(queue); -} - /* * main */ @@ -5749,9 +5828,6 @@ int main(int argc, char **argv) bool notification_thread_launched = false; bool rotation_thread_launched = false; bool timer_thread_launched = false; - struct lttng_pipe *ust32_channel_rotate_pipe = NULL, - *ust64_channel_rotate_pipe = NULL, - *kernel_channel_rotate_pipe = NULL; struct timer_thread_parameters timer_thread_ctx; /* Queue of rotation jobs populated by the sessiond-timer. */ struct rotation_thread_timer_queue *rotation_timer_queue = NULL; @@ -5766,7 +5842,7 @@ int main(int argc, char **argv) goto exit_set_signal_handler; } - if (sessiond_timer_signal_init()) { + if (timer_signal_init()) { retval = -1; goto exit_set_signal_handler; } @@ -5784,6 +5860,12 @@ int main(int argc, char **argv) goto exit_set_signal_handler; } + /* + * Init config from environment variables. + * Command line option override env configuration per-doc. Do env first. + */ + sessiond_config_apply_env_config(&config); + /* * Parse arguments and load the daemon configuration file. * @@ -5798,9 +5880,6 @@ int main(int argc, char **argv) goto exit_options; } - /* Init config from environment variables. */ - sessiond_config_apply_env_config(&config); - /* * Resolve all paths received as arguments, configuration option, or * through environment variable as absolute paths. This is necessary @@ -5917,19 +5996,6 @@ int main(int argc, char **argv) retval = -1; goto exit_init_data; } - kernel_channel_rotate_pipe = lttng_pipe_open(0); - if (!kernel_channel_rotate_pipe) { - ERR("Failed to create kernel consumer channel rotate pipe"); - retval = -1; - goto exit_init_data; - } - kconsumer_data.channel_rotate_pipe = - lttng_pipe_release_writefd( - kernel_channel_rotate_pipe); - if (kconsumer_data.channel_rotate_pipe < 0) { - retval = -1; - goto exit_init_data; - } } /* Set consumer initial state */ @@ -5948,30 +6014,18 @@ int main(int argc, char **argv) retval = -1; goto exit_init_data; } - ust32_channel_rotate_pipe = lttng_pipe_open(0); - if (!ust32_channel_rotate_pipe) { - ERR("Failed to create 32-bit user space consumer channel rotate pipe"); - retval = -1; - goto exit_init_data; - } - ustconsumer32_data.channel_rotate_pipe = lttng_pipe_release_writefd( - ust32_channel_rotate_pipe); - if (ustconsumer32_data.channel_rotate_pipe < 0) { - retval = -1; - goto exit_init_data; - } /* - * The rotation_timer_queue structure is shared between the sessiond timer - * thread and the rotation thread. The main() keeps the ownership and - * destroys it when both threads have quit. + * The rotation_thread_timer_queue structure is shared between the + * sessiond timer thread and the rotation thread. The main thread keeps + * its ownership and destroys it when both threads have been joined. */ - rotation_timer_queue = create_rotate_timer_queue(); + rotation_timer_queue = rotation_thread_timer_queue_create(); if (!rotation_timer_queue) { retval = -1; goto exit_init_data; } - timer_thread_ctx.rotation_timer_queue = rotation_timer_queue; + timer_thread_ctx.rotation_thread_job_queue = rotation_timer_queue; ust64_channel_monitor_pipe = lttng_pipe_open(0); if (!ust64_channel_monitor_pipe) { @@ -5985,18 +6039,6 @@ int main(int argc, char **argv) retval = -1; goto exit_init_data; } - ust64_channel_rotate_pipe = lttng_pipe_open(0); - if (!ust64_channel_rotate_pipe) { - ERR("Failed to create 64-bit user space consumer channel rotate pipe"); - retval = -1; - goto exit_init_data; - } - ustconsumer64_data.channel_rotate_pipe = lttng_pipe_release_writefd( - ust64_channel_rotate_pipe); - if (ustconsumer64_data.channel_rotate_pipe < 0) { - retval = -1; - goto exit_init_data; - } /* * Init UST app hash table. Alloc hash table before this point since @@ -6125,12 +6167,6 @@ int main(int argc, char **argv) retval = -1; goto exit_init_data; } - ret = write_agent_port(); - if (ret) { - ERR("Error in write_agent_port"); - retval = -1; - goto exit_init_data; - } /* Initialize communication library */ lttcomm_init(); @@ -6187,7 +6223,7 @@ int main(int argc, char **argv) /* Create timer thread. */ ret = pthread_create(&timer_thread, default_pthread_attr(), - sessiond_timer_thread, &timer_thread_ctx); + timer_thread_func, &timer_thread_ctx); if (ret) { errno = ret; PERROR("pthread_create timer"); @@ -6199,9 +6235,6 @@ int main(int argc, char **argv) /* rotation_thread_data acquires the pipes' read side. */ rotation_thread_handle = rotation_thread_handle_create( - ust32_channel_rotate_pipe, - ust64_channel_rotate_pipe, - kernel_channel_rotate_pipe, thread_quit_pipe[0], rotation_timer_queue, notification_thread_handle, @@ -6455,7 +6488,7 @@ exit_init_data: } if (timer_thread_launched) { - kill(getpid(), LTTNG_SESSIOND_SIG_EXIT); + timer_exit(); ret = pthread_join(timer_thread, &status); if (ret) { errno = ret; @@ -6468,7 +6501,7 @@ exit_init_data: * After the rotation and timer thread have quit, we can safely destroy * the rotation_timer_queue. */ - destroy_rotate_timer_queue(rotation_timer_queue); + rotation_thread_timer_queue_destroy(rotation_timer_queue); rcu_thread_offline(); rcu_unregister_thread(); @@ -6480,9 +6513,6 @@ exit_init_data: lttng_pipe_destroy(ust32_channel_monitor_pipe); lttng_pipe_destroy(ust64_channel_monitor_pipe); lttng_pipe_destroy(kernel_channel_monitor_pipe); - lttng_pipe_destroy(ust32_channel_rotate_pipe); - lttng_pipe_destroy(ust64_channel_rotate_pipe); - lttng_pipe_destroy(kernel_channel_rotate_pipe); exit_ht_cleanup: health_app_destroy(health_sessiond);