X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsession.c;h=2a7b8b83bb8d643ecdfcfdbd3c1364e69b562b10;hp=4b5c22bfb8626ef8f52b48ebbb75a77d9b4b05e8;hb=6fa5fe7cc78bea0b0bba154a0f911d3df530e18f;hpb=bbc4768c20f1c552222e1746f9475d145d7bf04e diff --git a/src/bin/lttng-sessiond/session.c b/src/bin/lttng-sessiond/session.c index 4b5c22bfb..2a7b8b83b 100644 --- a/src/bin/lttng-sessiond/session.c +++ b/src/bin/lttng-sessiond/session.c @@ -39,6 +39,7 @@ #include "utils.h" #include "trace-ust.h" #include "timer.h" +#include "cmd.h" struct ltt_session_destroy_notifier_element { ltt_session_destroy_notifier notifier; @@ -564,22 +565,15 @@ error: goto end_no_move; } -static -bool output_supports_trace_chunks(const struct ltt_session *session) +bool session_output_supports_trace_chunks(const struct ltt_session *session) { - if (session->consumer->type == CONSUMER_DST_LOCAL) { + const struct consumer_output *output = session->kernel_session ? + session->kernel_session->consumer : + session->ust_session->consumer; + + if (output->type == CONSUMER_DST_LOCAL) { return true; } else { - struct consumer_output *output; - - if (session->ust_session) { - output = session->ust_session->consumer; - } else if (session->kernel_session) { - output = session->kernel_session->consumer; - } else { - abort(); - } - if (output->relay_major_version > 2) { return true; } else if (output->relay_major_version == 2 && @@ -591,7 +585,8 @@ bool output_supports_trace_chunks(const struct ltt_session *session) } struct lttng_trace_chunk *session_create_new_trace_chunk( - struct ltt_session *session, + const struct ltt_session *session, + const struct consumer_output *consumer_output_override, const char *session_base_path_override, const char *chunk_name_override) { @@ -599,16 +594,28 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( struct lttng_trace_chunk *trace_chunk = NULL; enum lttng_trace_chunk_status chunk_status; const time_t chunk_creation_ts = time(NULL); - const bool is_local_trace = - session->consumer->type == CONSUMER_DST_LOCAL; - const char *base_path = session_base_path_override ? : - session_get_base_path(session); + bool is_local_trace; + const char *base_path; struct lttng_directory_handle session_output_directory; const struct lttng_credentials session_credentials = { .uid = session->uid, .gid = session->gid, }; uint64_t next_chunk_id; + const struct consumer_output *output; + + if (consumer_output_override) { + output = consumer_output_override; + } else { + assert(session->ust_session || session->kernel_session); + output = session->ust_session ? + session->ust_session->consumer : + session->kernel_session->consumer; + } + + is_local_trace = output->type == CONSUMER_DST_LOCAL; + base_path = session_base_path_override ? : + consumer_output_get_base_path(output); if (chunk_creation_ts == (time_t) -1) { PERROR("Failed to sample time while creation session \"%s\" trace chunk", @@ -616,9 +623,6 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( goto error; } - if (!output_supports_trace_chunks(session)) { - goto end; - } next_chunk_id = session->most_recent_chunk_id.is_set ? session->most_recent_chunk_id.value + 1 : 0; @@ -712,12 +716,15 @@ int session_close_trace_chunk(const struct ltt_session *session, } if (session->ust_session) { + const uint64_t relayd_id = + session->ust_session->consumer->net_seq_index; + cds_lfht_for_each_entry( session->ust_session->consumer->socks->ht, &iter, socket, node.node) { pthread_mutex_lock(socket->lock); ret = consumer_close_trace_chunk(socket, - session->consumer->net_seq_index, + relayd_id, session->id, trace_chunk); pthread_mutex_unlock(socket->lock); @@ -728,12 +735,15 @@ int session_close_trace_chunk(const struct ltt_session *session, } } if (session->kernel_session) { + const uint64_t relayd_id = + session->kernel_session->consumer->net_seq_index; + cds_lfht_for_each_entry( session->kernel_session->consumer->socks->ht, &iter, socket, node.node) { pthread_mutex_lock(socket->lock); ret = consumer_close_trace_chunk(socket, - session->consumer->net_seq_index, + relayd_id, session->id, trace_chunk); pthread_mutex_unlock(socket->lock); @@ -785,32 +795,17 @@ void session_release(struct urcu_ref *ref) struct ltt_ust_session *usess; struct ltt_kernel_session *ksess; struct ltt_session *session = container_of(ref, typeof(*session), ref); + const bool session_published = session->published; assert(!session->chunk_being_archived); usess = session->ust_session; ksess = session->kernel_session; - session_notify_destruction(session); - lttng_dynamic_array_reset(&session->destroy_notifiers); - if (session->current_trace_chunk) { - ret = session_close_trace_chunk(session, session->current_trace_chunk, NULL); - if (ret) { - ERR("Failed to close the current trace chunk of session \"%s\" during its release", - session->name); - } - ret = _session_set_trace_chunk_no_lock_check(session, NULL, NULL); - if (ret) { - ERR("Failed to release the current trace chunk of session \"%s\" during its release", - session->name); - } - } - - /* Clean kernel session teardown */ + /* Clean kernel session teardown, keeping data for destroy notifier. */ kernel_destroy_session(ksess); - session->kernel_session = NULL; - /* UST session teardown */ + /* UST session teardown, keeping data for destroy notifier. */ if (usess) { /* Close any relayd session */ consumer_output_send_destroy_relayd(usess->consumer); @@ -821,9 +816,8 @@ void session_release(struct urcu_ref *ref) ERR("Error in ust_app_destroy_trace_all"); } - /* Clean up the rest. */ + /* Clean up the rest, keeping destroy notifier data. */ trace_ust_destroy_session(usess); - session->ust_session = NULL; } /* @@ -842,14 +836,30 @@ void session_release(struct urcu_ref *ref) pthread_mutex_destroy(&session->lock); - if (session->published) { + if (session_published) { ASSERT_LOCKED(ltt_session_list.lock); del_session_list(session); del_session_ht(session); - pthread_cond_broadcast(<t_session_list.removal_cond); } + session_notify_destruction(session); + + kernel_free_session(ksess); + session->kernel_session = NULL; + if (usess) { + trace_ust_free_session(usess); + session->ust_session = NULL; + } + lttng_dynamic_array_reset(&session->destroy_notifiers); free(session->last_archived_chunk_name); + free(session->base_path); free(session); + if (session_published) { + /* + * Broadcast after free-ing to ensure the memory is + * reclaimed before the main thread exits. + */ + pthread_cond_broadcast(<t_session_list.removal_cond); + } } /* @@ -972,7 +982,7 @@ end: * Session list lock must be held by the caller. */ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, - struct ltt_session **out_session) + const char *base_path, struct ltt_session **out_session) { int ret; enum lttng_error_code ret_code; @@ -1095,6 +1105,16 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, } } + if (base_path) { + new_session->base_path = strdup(base_path); + if (!new_session->base_path) { + ERR("Failed to allocate base path of session \"%s\"", + name); + ret_code = LTTNG_ERR_SESSION_FAIL; + goto error; + } + } + new_session->uid = uid; new_session->gid = gid;