X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=b1229e7214828af2fcb260c3983d0e4d7e3cd1be;hb=db66e57489e5014289dc1d831e1eac90ac4fc0da;hp=76d087a1e5c90c1198afa870f19be9a4ae526d49;hpb=b723c447e99a0aa57fd3d5313273c05bb416a517;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 76d087a1e..b1229e721 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -73,6 +73,7 @@ #include "load-session-thread.h" #include "notification-thread.h" #include "notification-thread-commands.h" +#include "rotation-thread.h" #include "syscall.h" #include "agent.h" #include "ht-cleanup.h" @@ -94,6 +95,9 @@ static int lockfile_fd = -1; /* Set to 1 when a SIGUSR1 signal is received. */ static int recv_child_signal; +static struct lttng_kernel_tracer_version kernel_tracer_version; +static struct lttng_kernel_tracer_abi_version kernel_tracer_abi_version; + /* * Consumer daemon specific control data. Every value not initialized here is * set to 0 by the static definition. @@ -103,6 +107,7 @@ 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, @@ -113,6 +118,7 @@ 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, @@ -123,6 +129,7 @@ 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, @@ -202,6 +209,7 @@ static pthread_t ht_cleanup_thread; static pthread_t agent_reg_thread; static pthread_t load_session_thread; static pthread_t notification_thread; +static pthread_t rotation_thread; /* * UST registration command queue. This queue is tied with a futex and uses a N @@ -282,6 +290,9 @@ struct load_session_thread_data *load_info; /* Notification thread handle. */ struct notification_thread_handle *notification_thread_handle; +/* Rotation thread handle. */ +struct rotation_thread_handle *rotation_thread_handle; + /* Global hash tables */ struct lttng_ht *agent_apps_ht_by_sock = NULL; @@ -291,7 +302,7 @@ struct lttng_ht *agent_apps_ht_by_sock = NULL; * NR_LTTNG_SESSIOND_READY must match the number of calls to * sessiond_notify_ready(). */ -#define NR_LTTNG_SESSIOND_READY 4 +#define NR_LTTNG_SESSIOND_READY 5 int lttng_sessiond_ready = NR_LTTNG_SESSIOND_READY; int sessiond_check_thread_quit_pipe(int fd, uint32_t events) @@ -468,6 +479,24 @@ 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"); + } + } } /* @@ -1263,19 +1292,28 @@ restart: health_code_update(); /* - * Transfer the write-end of the channel monitoring pipe to the - * by issuing a SET_CHANNEL_MONITOR_PIPE command. + * 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. */ cmd_socket_wrapper = consumer_allocate_socket(&consumer_data->cmd_sock); if (!cmd_socket_wrapper) { goto error; } + cmd_socket_wrapper->lock = &consumer_data->lock; ret = consumer_send_channel_monitor_pipe(cmd_socket_wrapper, consumer_data->channel_monitor_pipe); if (ret) { 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; @@ -1445,7 +1483,17 @@ error_poll: } /* - * This thread manage application communication. + * This thread receives application command sockets (FDs) on the + * apps_cmd_pipe and waits (polls) on them until they are closed + * or an error occurs. + * + * At that point, it flushes the data (tracing and metadata) associated + * with this application and tears down ust app sessions and other + * associated data structures through ust_app_unregister(). + * + * Note that this thread never sends commands to the applications + * through the command sockets; it merely listens for hang-ups + * and errors on those sockets and cleans-up as they occur. */ static void *thread_manage_apps(void *data) { @@ -2413,9 +2461,9 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) * fallback on the 32-bit one, */ DBG3("Looking for a kernel consumer at these locations:"); - DBG3(" 1) %s", config.consumerd64_bin_path.value); + DBG3(" 1) %s", config.consumerd64_bin_path.value ? : "NULL"); DBG3(" 2) %s/%s", INSTALL_BIN_PATH, DEFAULT_CONSUMERD_FILE); - DBG3(" 3) %s", config.consumerd32_bin_path.value); + DBG3(" 3) %s", config.consumerd32_bin_path.value ? : "NULL"); if (stat(config.consumerd64_bin_path.value, &st) == 0) { DBG3("Found location #1"); consumer_to_use = config.consumerd64_bin_path.value; @@ -2440,33 +2488,30 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) break; case LTTNG_CONSUMER64_UST: { - char *tmpnew = NULL; - - if (config.consumerd64_lib_dir.value[0] != '\0') { + if (config.consumerd64_lib_dir.value) { char *tmp; size_t tmplen; + char *tmpnew; tmp = lttng_secure_getenv("LD_LIBRARY_PATH"); if (!tmp) { tmp = ""; } - tmplen = strlen("LD_LIBRARY_PATH=") - + strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp); + tmplen = strlen(config.consumerd64_lib_dir.value) + 1 /* : */ + strlen(tmp); tmpnew = zmalloc(tmplen + 1 /* \0 */); if (!tmpnew) { ret = -ENOMEM; goto error; } - strcpy(tmpnew, "LD_LIBRARY_PATH="); strcat(tmpnew, config.consumerd64_lib_dir.value); if (tmp[0] != '\0') { strcat(tmpnew, ":"); strcat(tmpnew, tmp); } - ret = putenv(tmpnew); + ret = setenv("LD_LIBRARY_PATH", tmpnew, 1); + free(tmpnew); if (ret) { ret = -errno; - free(tmpnew); goto error; } } @@ -2476,40 +2521,34 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) "--consumerd-err-sock", consumer_data->err_unix_sock_path, "--group", config.tracing_group_name.value, NULL); - if (config.consumerd64_lib_dir.value[0] != '\0') { - free(tmpnew); - } break; } case LTTNG_CONSUMER32_UST: { - char *tmpnew = NULL; - - if (config.consumerd32_lib_dir.value[0] != '\0') { + if (config.consumerd32_lib_dir.value) { char *tmp; size_t tmplen; + char *tmpnew; tmp = lttng_secure_getenv("LD_LIBRARY_PATH"); if (!tmp) { tmp = ""; } - tmplen = strlen("LD_LIBRARY_PATH=") - + strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp); + tmplen = strlen(config.consumerd32_lib_dir.value) + 1 /* : */ + strlen(tmp); tmpnew = zmalloc(tmplen + 1 /* \0 */); if (!tmpnew) { ret = -ENOMEM; goto error; } - strcpy(tmpnew, "LD_LIBRARY_PATH="); strcat(tmpnew, config.consumerd32_lib_dir.value); if (tmp[0] != '\0') { strcat(tmpnew, ":"); strcat(tmpnew, tmp); } - ret = putenv(tmpnew); + ret = setenv("LD_LIBRARY_PATH", tmpnew, 1); + free(tmpnew); if (ret) { ret = -errno; - free(tmpnew); goto error; } } @@ -2519,14 +2558,11 @@ static pid_t spawn_consumerd(struct consumer_data *consumer_data) "--consumerd-err-sock", consumer_data->err_unix_sock_path, "--group", config.tracing_group_name.value, NULL); - if (config.consumerd32_lib_dir.value[0] != '\0') { - free(tmpnew); - } break; } default: - PERROR("unknown consumer type"); - exit(EXIT_FAILURE); + ERR("unknown consumer type"); + errno = 0; } if (errno != 0) { PERROR("Consumer execl()"); @@ -2622,7 +2658,8 @@ static int init_kernel_tracer(void) } /* Validate kernel version */ - ret = kernel_validate_version(kernel_tracer_fd); + ret = kernel_validate_version(kernel_tracer_fd, &kernel_tracer_version, + &kernel_tracer_abi_version); if (ret < 0) { goto error_version; } @@ -2829,20 +2866,6 @@ static int create_kernel_session(struct ltt_session *session) goto error; } - /* Create directory(ies) on local filesystem. */ - if (session->kernel_session->consumer->type == CONSUMER_DST_LOCAL && - strlen(session->kernel_session->consumer->dst.trace_path) > 0) { - ret = run_as_mkdir_recursive( - session->kernel_session->consumer->dst.trace_path, - S_IRWXU | S_IRWXG, session->uid, session->gid); - if (ret < 0) { - if (errno != EEXIST) { - ERR("Trace directory creation error"); - goto error; - } - } - } - session->kernel_session->uid = session->uid; session->kernel_session->gid = session->gid; session->kernel_session->output_traces = session->output_traces; @@ -5458,6 +5481,10 @@ int main(int argc, char **argv) *ust64_channel_monitor_pipe = NULL, *kernel_channel_monitor_pipe = NULL; bool notification_thread_running = false; + bool rotation_thread_running = false; + struct lttng_pipe *ust32_channel_rotate_pipe = NULL, + *ust64_channel_rotate_pipe = NULL, + *kernel_channel_rotate_pipe = NULL; init_kernel_workarounds(); @@ -5605,6 +5632,19 @@ 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; + } } lockfile_fd = create_lockfile(); @@ -5629,6 +5669,19 @@ 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; + } + ust64_channel_monitor_pipe = lttng_pipe_open(0); if (!ust64_channel_monitor_pipe) { @@ -5642,6 +5695,18 @@ 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; + } /* * See if daemon already exist. @@ -5835,6 +5900,31 @@ int main(int argc, char **argv) } notification_thread_running = true; + /* 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]); + if (!rotation_thread_handle) { + retval = -1; + ERR("Failed to create rotation thread shared data"); + stop_threads(); + goto exit_rotation; + } + rotation_thread_running = true; + + /* Create rotation thread. */ + ret = pthread_create(&rotation_thread, default_pthread_attr(), + thread_rotation, rotation_thread_handle); + if (ret) { + errno = ret; + PERROR("pthread_create rotation"); + retval = -1; + stop_threads(); + goto exit_rotation; + } + /* Create thread to manage the client socket */ ret = pthread_create(&client_thread, default_pthread_attr(), thread_manage_clients, (void *) NULL); @@ -6001,6 +6091,7 @@ exit_dispatch: } exit_client: +exit_rotation: exit_notification: ret = pthread_join(health_thread, &status); if (ret) { @@ -6050,6 +6141,18 @@ exit_init_data: notification_thread_handle_destroy(notification_thread_handle); } + if (rotation_thread_handle) { + if (rotation_thread_running) { + ret = pthread_join(rotation_thread, &status); + if (ret) { + errno = ret; + PERROR("pthread_join rotation thread"); + retval = -1; + } + } + rotation_thread_handle_destroy(rotation_thread_handle); + } + rcu_thread_offline(); rcu_unregister_thread(); @@ -6060,6 +6163,9 @@ 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);