X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=3bb3aced586edbb2f07da3c117ae5428942a2356;hb=3b16476a9b2015e59bb869cdeb07975b8d1ec6c5;hp=d26d8de0bf661b7714914645558edcb2922e2f1d;hpb=1e791a74976525f287944e5dbb65208a3b9edf42;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index d26d8de0b..3bb3aced5 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1039,7 +1039,8 @@ static enum lttng_error_code send_consumer_relayd_socket( struct consumer_socket *consumer_sock, const char *session_name, const char *hostname, int session_live_timer, - const uint64_t *current_chunk_id) + const uint64_t *current_chunk_id, + time_t session_creation_time) { int ret; struct lttcomm_relayd_sock *rsock = NULL; @@ -1068,7 +1069,7 @@ static enum lttng_error_code send_consumer_relayd_socket( ret = consumer_send_relayd_socket(consumer_sock, rsock, consumer, relayd_uri->stype, session_id, session_name, hostname, session_live_timer, - current_chunk_id); + current_chunk_id, session_creation_time); if (ret < 0) { status = LTTNG_ERR_ENABLE_CONSUMER_FAIL; goto close_sock; @@ -1116,7 +1117,7 @@ static enum lttng_error_code send_consumer_relayd_sockets( unsigned int session_id, struct consumer_output *consumer, struct consumer_socket *sock, const char *session_name, const char *hostname, int session_live_timer, - const uint64_t *current_chunk_id) + const uint64_t *current_chunk_id, time_t session_creation_time) { enum lttng_error_code status = LTTNG_OK; @@ -1128,7 +1129,7 @@ static enum lttng_error_code send_consumer_relayd_sockets( status = send_consumer_relayd_socket(session_id, &consumer->dst.net.control, consumer, sock, session_name, hostname, session_live_timer, - current_chunk_id); + current_chunk_id, session_creation_time); if (status != LTTNG_OK) { goto error; } @@ -1139,7 +1140,7 @@ static enum lttng_error_code send_consumer_relayd_sockets( status = send_consumer_relayd_socket(session_id, &consumer->dst.net.data, consumer, sock, session_name, hostname, session_live_timer, - current_chunk_id); + current_chunk_id, session_creation_time); if (status != LTTNG_OK) { goto error; } @@ -1195,7 +1196,8 @@ int cmd_setup_relayd(struct ltt_session *session) usess->consumer, socket, session->name, session->hostname, session->live_timer, - current_chunk_id.is_set ? ¤t_chunk_id.value : NULL); + current_chunk_id.is_set ? ¤t_chunk_id.value : NULL, + session->creation_time); pthread_mutex_unlock(socket->lock); if (ret != LTTNG_OK) { goto error; @@ -1218,7 +1220,8 @@ int cmd_setup_relayd(struct ltt_session *session) ksess->consumer, socket, session->name, session->hostname, session->live_timer, - current_chunk_id.is_set ? ¤t_chunk_id.value : NULL); + current_chunk_id.is_set ? ¤t_chunk_id.value : NULL, + session->creation_time); pthread_mutex_unlock(socket->lock); if (ret != LTTNG_OK) { goto error; @@ -2580,7 +2583,7 @@ int cmd_start_trace(struct ltt_session *session) struct lttng_trace_chunk *trace_chunk; trace_chunk = session_create_new_trace_chunk( - session, NULL, NULL); + session, NULL, NULL, NULL); if (!trace_chunk) { ret = LTTNG_ERR_CREATE_DIR_FAIL; goto error; @@ -4198,8 +4201,7 @@ end: * Return LTTNG_OK on success or a LTTNG_ERR code. */ static enum lttng_error_code set_relayd_for_snapshot( - struct consumer_output *consumer, - const struct snapshot_output *snap_output, + struct consumer_output *output, const struct ltt_session *session) { enum lttng_error_code status = LTTNG_OK; @@ -4207,17 +4209,18 @@ static enum lttng_error_code set_relayd_for_snapshot( struct consumer_socket *socket; LTTNG_OPTIONAL(uint64_t) current_chunk_id = {}; - assert(consumer); - assert(snap_output); + assert(output); assert(session); DBG2("Set relayd object from snapshot output"); if (session->current_trace_chunk) { - enum lttng_trace_chunk_status status = lttng_trace_chunk_get_id( - session->current_trace_chunk, ¤t_chunk_id.value); + enum lttng_trace_chunk_status chunk_status = + lttng_trace_chunk_get_id( + session->current_trace_chunk, + ¤t_chunk_id.value); - if (status == LTTNG_TRACE_CHUNK_STATUS_OK) { + if (chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK) { current_chunk_id.is_set = true; } else { ERR("Failed to get current trace chunk id"); @@ -4227,7 +4230,7 @@ static enum lttng_error_code set_relayd_for_snapshot( } /* Ignore if snapshot consumer output is not network. */ - if (snap_output->consumer->type != CONSUMER_DST_NET) { + if (output->type != CONSUMER_DST_NET) { goto error; } @@ -4236,14 +4239,15 @@ static enum lttng_error_code set_relayd_for_snapshot( * snapshot output. */ rcu_read_lock(); - cds_lfht_for_each_entry(snap_output->consumer->socks->ht, &iter.iter, + cds_lfht_for_each_entry(output->socks->ht, &iter.iter, socket, node.node) { pthread_mutex_lock(socket->lock); status = send_consumer_relayd_sockets(0, session->id, - snap_output->consumer, socket, + output, socket, session->name, session->hostname, session->live_timer, - current_chunk_id.is_set ? ¤t_chunk_id.value : NULL); + current_chunk_id.is_set ? ¤t_chunk_id.value : NULL, + session->creation_time); pthread_mutex_unlock(socket->lock); if (status != LTTNG_OK) { rcu_read_unlock(); @@ -4263,44 +4267,18 @@ error: */ static enum lttng_error_code record_kernel_snapshot( struct ltt_kernel_session *ksess, - const struct snapshot_output *output, + const struct consumer_output *output, const struct ltt_session *session, int wait, uint64_t nb_packets_per_stream) { - int ret; enum lttng_error_code status; assert(ksess); assert(output); assert(session); - /* - * Copy kernel session sockets so we can communicate with the right - * consumer for the snapshot record command. - */ - ret = consumer_copy_sockets(output->consumer, ksess->consumer); - if (ret < 0) { - status = LTTNG_ERR_NOMEM; - goto error; - } - - status = set_relayd_for_snapshot(ksess->consumer, output, session); - if (status != LTTNG_OK) { - goto error_snapshot; - } - - status = kernel_snapshot_record(ksess, output, wait, nb_packets_per_stream); - if (status != LTTNG_OK) { - goto error_snapshot; - } - - goto end; - -error_snapshot: - /* Clean up copied sockets so this output can use some other later on. */ - consumer_destroy_output_sockets(output->consumer); -error: -end: + status = kernel_snapshot_record( + ksess, output, wait, nb_packets_per_stream); return status; } @@ -4310,45 +4288,18 @@ end: * Returns LTTNG_OK on success or a LTTNG_ERR error code. */ static enum lttng_error_code record_ust_snapshot(struct ltt_ust_session *usess, - const struct snapshot_output *output, - const struct ltt_session *session, int wait, - uint64_t nb_packets_per_stream) + const struct consumer_output *output, + const struct ltt_session *session, + int wait, uint64_t nb_packets_per_stream) { - int ret; enum lttng_error_code status; assert(usess); assert(output); assert(session); - /* - * Copy UST session sockets so we can communicate with the right - * consumer for the snapshot record command. - */ - ret = consumer_copy_sockets(output->consumer, usess->consumer); - if (ret < 0) { - status = LTTNG_ERR_NOMEM; - goto error; - } - - status = set_relayd_for_snapshot(usess->consumer, output, session); - if (status != LTTNG_OK) { - goto error_snapshot; - } - - status = ust_app_snapshot_record(usess, output, wait, - nb_packets_per_stream); - if (status != LTTNG_OK) { - goto error_snapshot; - } - - goto end; - -error_snapshot: - /* Clean up copied sockets so this output can use some other later on. */ - consumer_destroy_output_sockets(output->consumer); -error: -end: + status = ust_app_snapshot_record( + usess, output, wait, nb_packets_per_stream); return status; } @@ -4444,82 +4395,151 @@ static enum lttng_error_code snapshot_record(struct ltt_session *session, const struct snapshot_output *snapshot_output, int wait) { - int fmt_ret; int64_t nb_packets_per_stream; char snapshot_chunk_name[LTTNG_NAME_MAX]; - enum lttng_error_code ret = LTTNG_OK; + int ret; + enum lttng_error_code ret_code = LTTNG_OK; struct lttng_trace_chunk *snapshot_trace_chunk; + struct consumer_output *original_ust_consumer_output = NULL; + struct consumer_output *original_kernel_consumer_output = NULL; + struct consumer_output *snapshot_ust_consumer_output = NULL; + struct consumer_output *snapshot_kernel_consumer_output = NULL; - fmt_ret = snprintf(snapshot_chunk_name, sizeof(snapshot_chunk_name), + ret = snprintf(snapshot_chunk_name, sizeof(snapshot_chunk_name), "%s-%s-%" PRIu64, snapshot_output->name, snapshot_output->datetime, snapshot_output->nb_snapshot); - if (fmt_ret < 0 || fmt_ret >= sizeof(snapshot_chunk_name)) { + if (ret < 0 || ret >= sizeof(snapshot_chunk_name)) { ERR("Failed to format snapshot name"); - ret = LTTNG_ERR_INVALID; - goto end; + ret_code = LTTNG_ERR_INVALID; + goto error; } DBG("Recording snapshot \"%s\" for session \"%s\" with chunk name \"%s\"", snapshot_output->name, session->name, snapshot_chunk_name); + if (!session->kernel_session && !session->ust_session) { + ERR("Failed to record snapshot as no channels exist"); + ret_code = LTTNG_ERR_NO_CHANNEL; + goto error; + } + + if (session->kernel_session) { + original_kernel_consumer_output = + session->kernel_session->consumer; + snapshot_kernel_consumer_output = + consumer_copy_output(snapshot_output->consumer); + ret = consumer_copy_sockets(snapshot_kernel_consumer_output, + original_kernel_consumer_output); + if (ret < 0) { + ERR("Failed to copy consumer sockets from snapshot output configuration"); + ret_code = LTTNG_ERR_NOMEM; + goto error; + } + ret_code = set_relayd_for_snapshot( + snapshot_kernel_consumer_output, session); + if (ret_code != LTTNG_OK) { + ERR("Failed to setup relay daemon for kernel tracer snapshot"); + goto error; + } + session->kernel_session->consumer = + snapshot_kernel_consumer_output; + } + if (session->ust_session) { + original_ust_consumer_output = session->ust_session->consumer; + snapshot_ust_consumer_output = + consumer_copy_output(snapshot_output->consumer); + ret = consumer_copy_sockets(snapshot_ust_consumer_output, + original_ust_consumer_output); + if (ret < 0) { + ERR("Failed to copy consumer sockets from snapshot output configuration"); + ret_code = LTTNG_ERR_NOMEM; + goto error; + } + ret_code = set_relayd_for_snapshot( + snapshot_ust_consumer_output, session); + if (ret_code != LTTNG_OK) { + ERR("Failed to setup relay daemon for userspace tracer snapshot"); + goto error; + } + session->ust_session->consumer = + snapshot_ust_consumer_output; + } + snapshot_trace_chunk = session_create_new_trace_chunk(session, - snapshot_output_get_base_path(snapshot_output), + snapshot_kernel_consumer_output ?: + snapshot_ust_consumer_output, + consumer_output_get_base_path( + snapshot_output->consumer), snapshot_chunk_name); if (!snapshot_trace_chunk) { - ret = LTTNG_ERR_CREATE_DIR_FAIL; - goto end; + ERR("Failed to create temporary trace chunk to record a snapshot of session \"%s\"", + session->name); + ret_code = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; } assert(!session->current_trace_chunk); ret = session_set_trace_chunk(session, snapshot_trace_chunk, NULL); lttng_trace_chunk_put(snapshot_trace_chunk); snapshot_trace_chunk = NULL; if (ret) { - ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; - goto end; + ERR("Failed to set temporary trace chunk to record a snapshot of session \"%s\"", + session->name); + ret_code = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; + goto error; } nb_packets_per_stream = get_session_nb_packets_per_stream(session, snapshot_output->max_size); if (nb_packets_per_stream < 0) { - ret = LTTNG_ERR_MAX_SIZE_INVALID; - goto end; + ret_code = LTTNG_ERR_MAX_SIZE_INVALID; + goto error; } if (session->kernel_session) { - ret = record_kernel_snapshot(session->kernel_session, - snapshot_output, session, + ret_code = record_kernel_snapshot(session->kernel_session, + snapshot_kernel_consumer_output, session, wait, nb_packets_per_stream); - if (ret != LTTNG_OK) { - goto end; + if (ret_code != LTTNG_OK) { + goto error; } } if (session->ust_session) { - ret = record_ust_snapshot(session->ust_session, - snapshot_output, session, + ret_code = record_ust_snapshot(session->ust_session, + snapshot_ust_consumer_output, session, wait, nb_packets_per_stream); - if (ret != LTTNG_OK) { - goto end; + if (ret_code != LTTNG_OK) { + goto error; } } - if (session_close_trace_chunk(session, session->current_trace_chunk)) { + if (session_close_trace_chunk( + session, session->current_trace_chunk, NULL)) { /* * Don't goto end; make sure the chunk is closed for the session * to allow future snapshots. */ ERR("Failed to close snapshot trace chunk of session \"%s\"", session->name); - ret = -1; + ret_code = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER; } if (session_set_trace_chunk(session, NULL, NULL)) { ERR("Failed to release the current trace chunk of session \"%s\"", session->name); - ret = -1; + ret_code = LTTNG_ERR_UNK; } -end: - return ret; +error: + if (original_ust_consumer_output) { + session->ust_session->consumer = original_ust_consumer_output; + } + if (original_kernel_consumer_output) { + session->kernel_session->consumer = + original_kernel_consumer_output; + } + consumer_output_put(snapshot_ust_consumer_output); + consumer_output_put(snapshot_kernel_consumer_output); + return ret_code; } /* @@ -4535,10 +4555,9 @@ int cmd_snapshot_record(struct ltt_session *session, { enum lttng_error_code cmd_ret = LTTNG_OK; int ret; - unsigned int use_tmp_output = 0; - struct snapshot_output tmp_output; unsigned int snapshot_success = 0; char datetime[16]; + struct snapshot_output *tmp_output = NULL; assert(session); assert(output); @@ -4570,11 +4589,17 @@ int cmd_snapshot_record(struct ltt_session *session, /* Use temporary output for the session. */ if (*output->ctrl_url != '\0') { + tmp_output = snapshot_output_alloc(); + if (!tmp_output) { + cmd_ret = LTTNG_ERR_NOMEM; + goto error; + } + ret = snapshot_output_init(session, output->max_size, output->name, output->ctrl_url, output->data_url, session->consumer, - &tmp_output, NULL); + tmp_output, NULL); if (ret < 0) { if (ret == -ENOMEM) { cmd_ret = LTTNG_ERR_NOMEM; @@ -4584,15 +4609,11 @@ int cmd_snapshot_record(struct ltt_session *session, goto error; } /* Use the global session count for the temporary snapshot. */ - tmp_output.nb_snapshot = session->snapshot.nb_snapshot; + tmp_output->nb_snapshot = session->snapshot.nb_snapshot; /* Use the global datetime */ - memcpy(tmp_output.datetime, datetime, sizeof(datetime)); - use_tmp_output = 1; - } - - if (use_tmp_output) { - cmd_ret = snapshot_record(session, &tmp_output, wait); + memcpy(tmp_output->datetime, datetime, sizeof(datetime)); + cmd_ret = snapshot_record(session, tmp_output, wait); if (cmd_ret != LTTNG_OK) { goto error; } @@ -4604,30 +4625,35 @@ int cmd_snapshot_record(struct ltt_session *session, rcu_read_lock(); cds_lfht_for_each_entry(session->snapshot.output_ht->ht, &iter.iter, sout, node.node) { + struct snapshot_output output_copy; + /* - * Make a local copy of the output and assign the - * possible temporary value given by the caller. + * Make a local copy of the output and override output + * parameters with those provided as part of the + * command. */ - memcpy(&tmp_output, sout, sizeof(tmp_output)); + memcpy(&output_copy, sout, sizeof(output_copy)); if (output->max_size != (uint64_t) -1ULL) { - tmp_output.max_size = output->max_size; + output_copy.max_size = output->max_size; } - tmp_output.nb_snapshot = session->snapshot.nb_snapshot; - memcpy(tmp_output.datetime, datetime, sizeof(datetime)); + output_copy.nb_snapshot = session->snapshot.nb_snapshot; + memcpy(output_copy.datetime, datetime, + sizeof(datetime)); /* Use temporary name. */ if (*output->name != '\0') { - if (lttng_strncpy(tmp_output.name, output->name, - sizeof(tmp_output.name))) { + if (lttng_strncpy(output_copy.name, + output->name, + sizeof(output_copy.name))) { cmd_ret = LTTNG_ERR_INVALID; rcu_read_unlock(); goto error; } } - cmd_ret = snapshot_record(session, &tmp_output, wait); + cmd_ret = snapshot_record(session, &output_copy, wait); if (cmd_ret != LTTNG_OK) { rcu_read_unlock(); goto error; @@ -4644,6 +4670,9 @@ int cmd_snapshot_record(struct ltt_session *session, } error: + if (tmp_output) { + snapshot_output_destroy(tmp_output); + } return cmd_ret; } @@ -4729,7 +4758,7 @@ int cmd_rotate_session(struct ltt_session *session, session->rotation_state = LTTNG_ROTATION_STATE_ONGOING; if (session->active) { - new_trace_chunk = session_create_new_trace_chunk(session, + new_trace_chunk = session_create_new_trace_chunk(session, NULL, NULL, NULL); if (!new_trace_chunk) { cmd_ret = LTTNG_ERR_CREATE_DIR_FAIL; @@ -4750,14 +4779,6 @@ int cmd_rotate_session(struct ltt_session *session, &ongoing_rotation_chunk_id); assert(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK); - chunk_status = lttng_trace_chunk_set_close_command( - chunk_being_archived, - LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED); - if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { - cmd_ret = LTTNG_ERR_FATAL; - goto error; - } - if (session->kernel_session) { cmd_ret = kernel_rotate_session(session); if (cmd_ret != LTTNG_OK) { @@ -4771,7 +4792,9 @@ int cmd_rotate_session(struct ltt_session *session, } } - ret = session_close_trace_chunk(session, chunk_being_archived); + ret = session_close_trace_chunk(session, chunk_being_archived, + &((enum lttng_trace_chunk_command_type) { + LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED})); if (ret) { cmd_ret = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER; goto error;