X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fmain.c;h=4968ee2a937194d2f344fa6a2b232656eec6acc9;hp=489cc9d7646e5643634e04d27e71057beceee930;hb=6d9a9c6575be8bcf86f404236a0f4a78b4889881;hpb=d086f507d02078aed618ab291a0bc4a634958fa3 diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index 489cc9d76..4968ee2a9 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -595,7 +595,8 @@ static void sessiond_cleanup(void) /* Cleanup ALL session */ cds_list_for_each_entry_safe(sess, stmp, &session_list_ptr->head, list) { - cmd_destroy_session(sess, kernel_poll_pipe[1]); + cmd_destroy_session(sess, kernel_poll_pipe[1], + notification_thread_handle); } } @@ -2903,6 +2904,22 @@ static unsigned int lttng_sessions_count(uid_t uid, gid_t gid) return i; } +/* + * Check if the current kernel tracer supports the session rotation feature. + * Return 1 if it does, 0 otherwise. + */ +static int check_rotate_compatible(void) +{ + int ret = 1; + + if (kernel_tracer_version.major != 2 || kernel_tracer_version.minor < 11) { + DBG("Kernel tracer version is not compatible with the rotation feature"); + ret = 0; + } + + return ret; +} + /* * Process the command requested by the lttng client within the command * context structure. This function make sure that the return structure (llm) @@ -2947,6 +2964,12 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_REGENERATE_STATEDUMP: case LTTNG_REGISTER_TRIGGER: 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: need_domain = 0; break; default: @@ -2989,6 +3012,10 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock, case LTTNG_LIST_SYSCALLS: case LTTNG_LIST_TRACKER_PIDS: 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: break; default: /* Setup lttng message with no payload */ @@ -3680,6 +3707,20 @@ error_add_context: } case LTTNG_START_TRACE: { + /* + * On the first start, if we have a kernel session and we have + * enabled time or size-based rotations, we have to make sure + * the kernel tracer supports it. + */ + if (!cmd_ctx->session->has_been_started && \ + cmd_ctx->session->kernel_session && \ + (cmd_ctx->session->rotate_timer_period || \ + cmd_ctx->session->rotate_size) && \ + !check_rotate_compatible()) { + DBG("Kernel tracer version is not compatible with the rotation feature"); + ret = LTTNG_ERR_ROTATION_WRONG_VERSION; + goto error; + } ret = cmd_start_trace(cmd_ctx->session); break; } @@ -3731,7 +3772,8 @@ error_add_context: } case LTTNG_DESTROY_SESSION: { - ret = cmd_destroy_session(cmd_ctx->session, kernel_poll_pipe[1]); + ret = cmd_destroy_session(cmd_ctx->session, kernel_poll_pipe[1], + notification_thread_handle); /* Set session to NULL so we do not unlock it after free. */ cmd_ctx->session = NULL; @@ -4077,6 +4119,141 @@ error_add_context: notification_thread_handle); break; } + case LTTNG_ROTATE_SESSION: + { + struct lttng_rotate_session_return rotate_return; + + DBG("Client rotate session \"%s\"", cmd_ctx->session->name); + + memset(&rotate_return, 0, sizeof(rotate_return)); + if (cmd_ctx->session->kernel_session && !check_rotate_compatible()) { + DBG("Kernel tracer version is not compatible with the rotation feature"); + ret = LTTNG_ERR_ROTATION_WRONG_VERSION; + goto error; + } + + ret = cmd_rotate_session(cmd_ctx->session, &rotate_return); + if (ret < 0) { + ret = -ret; + goto error; + } + + ret = setup_lttng_msg_no_cmd_header(cmd_ctx, &rotate_return, + sizeof(rotate_return)); + if (ret < 0) { + ret = -ret; + goto error; + } + + ret = LTTNG_OK; + break; + } + case LTTNG_ROTATION_GET_INFO: + { + struct lttng_rotation_get_info_return get_info_return; + + memset(&get_info_return, 0, sizeof(get_info_return)); + ret = cmd_rotate_get_info(cmd_ctx->session, &get_info_return, + cmd_ctx->lsm->u.get_rotation_info.rotation_id); + if (ret < 0) { + ret = -ret; + goto error; + } + + ret = setup_lttng_msg_no_cmd_header(cmd_ctx, &get_info_return, + sizeof(get_info_return)); + if (ret < 0) { + ret = -ret; + goto error; + } + + 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: + { + 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; + } + + ret = cmd_rotation_set_schedule(cmd_ctx->session, + cmd_ctx->lsm->u.rotate_setup.timer_us, + cmd_ctx->lsm->u.rotate_setup.size, + notification_thread_handle); + if (ret != LTTNG_OK) { + goto error; + } + + 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: + { + 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); + if (ret < 0) { + ret = -ret; + goto error; + } + + ret = LTTNG_OK; + break; + } default: ret = LTTNG_ERR_UND; break; @@ -4752,7 +4929,7 @@ static int set_option(int opt, const char *arg, const char *optname) } else if (string_match(optname, "no-kernel")) { config.no_kernel = true; } else if (string_match(optname, "quiet") || opt == 'q') { - lttng_opt_quiet = true; + config.quiet = true; } else if (string_match(optname, "verbose") || opt == 'v') { /* Verbose level can increase using multiple -v */ if (arg) { @@ -5533,6 +5710,7 @@ int main(int argc, char **argv) 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; + sem_t notification_thread_ready; init_kernel_workarounds(); @@ -5940,11 +6118,19 @@ int main(int argc, char **argv) goto exit_health; } + /* + * The rotation thread needs the notification thread to be ready before + * creating the rotate_notification_channel, so we use this semaphore as + * a rendez-vous point. + */ + sem_init(¬ification_thread_ready, 0, 0); + /* notification_thread_data acquires the pipes' read side. */ notification_thread_handle = notification_thread_handle_create( ust32_channel_monitor_pipe, ust64_channel_monitor_pipe, - kernel_channel_monitor_pipe); + kernel_channel_monitor_pipe, + ¬ification_thread_ready); if (!notification_thread_handle) { retval = -1; ERR("Failed to create notification thread shared data"); @@ -5982,7 +6168,9 @@ int main(int argc, char **argv) ust64_channel_rotate_pipe, kernel_channel_rotate_pipe, thread_quit_pipe[0], - rotation_timer_queue); + rotation_timer_queue, + notification_thread_handle, + ¬ification_thread_ready); if (!rotation_thread_handle) { retval = -1; ERR("Failed to create rotation thread shared data"); @@ -6170,6 +6358,7 @@ exit_dispatch: exit_client: exit_rotation: exit_notification: + sem_destroy(¬ification_thread_ready); ret = pthread_join(health_thread, &status); if (ret) { errno = ret;