X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsession.cpp;h=54b255e056dff80b445420e5ed33b73b0c0d0a3b;hb=28ab034a2c3582d07d3423d2d746731f87d3969f;hp=fbf8ce55c0b1c1d2e25c26688a09c9f0b0270cfd;hpb=21cf9b6b1843774306a76f4dccddddd706b64f79;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/session.cpp b/src/bin/lttng-sessiond/session.cpp index fbf8ce55c..54b255e05 100644 --- a/src/bin/lttng-sessiond/session.cpp +++ b/src/bin/lttng-sessiond/session.cpp @@ -6,31 +6,34 @@ */ #define _LGPL_SOURCE -#include +#include "cmd.hpp" +#include "kernel.hpp" +#include "lttng-sessiond.hpp" +#include "session.hpp" +#include "timer.hpp" +#include "trace-ust.hpp" +#include "utils.hpp" + +#include +#include +#include +#include +#include + +#include + +#include #include +#include +#include #include #include #include #include -#include -#include #include -#include - -#include -#include -#include -#include -#include -#include "lttng-sessiond.h" -#include "kernel.h" - -#include "session.h" -#include "utils.h" -#include "trace-ust.h" -#include "timer.h" -#include "cmd.h" +#include +namespace { struct ltt_session_destroy_notifier_element { ltt_session_destroy_notifier notifier; void *user_data; @@ -41,6 +44,8 @@ struct ltt_session_clear_notifier_element { void *user_data; }; +namespace ls = lttng::sessiond; + /* * NOTES: * @@ -50,25 +55,26 @@ struct ltt_session_clear_notifier_element { * using session_lock() and session_unlock(). */ +/* These characters are forbidden in a session name. Used by validate_name. */ +const char *forbidden_name_chars = "/"; + +/* Global hash table to keep the sessions, indexed by id. */ +struct lttng_ht *ltt_sessions_ht_by_id = NULL; +/* Global hash table to keep the sessions, indexed by name. */ +struct lttng_ht *ltt_sessions_ht_by_name = NULL; + /* * Init tracing session list. * * Please see session.h for more explanation and correct usage of the list. */ -static struct ltt_session_list ltt_session_list = { +struct ltt_session_list the_session_list = { .lock = PTHREAD_MUTEX_INITIALIZER, .removal_cond = PTHREAD_COND_INITIALIZER, .next_uuid = 0, - .head = CDS_LIST_HEAD_INIT(ltt_session_list.head), + .head = CDS_LIST_HEAD_INIT(the_session_list.head), }; - -/* These characters are forbidden in a session name. Used by validate_name. */ -static const char *forbidden_name_chars = "/"; - -/* Global hash table to keep the sessions, indexed by id. */ -static struct lttng_ht *ltt_sessions_ht_by_id = NULL; -/* Global hash table to keep the sessions, indexed by name. */ -static struct lttng_ht *ltt_sessions_ht_by_name = NULL; +} /* namespace */ /* * Validate the session name for forbidden characters. @@ -113,8 +119,8 @@ static uint64_t add_session_list(struct ltt_session *ls) { LTTNG_ASSERT(ls); - cds_list_add(&ls->list, <t_session_list.head); - return ltt_session_list.next_uuid++; + cds_list_add(&ls->list, &the_session_list.head); + return the_session_list.next_uuid++; } /* @@ -134,7 +140,7 @@ static void del_session_list(struct ltt_session *ls) */ struct ltt_session_list *session_get_list(void) { - return <t_session_list; + return &the_session_list; } /* @@ -142,12 +148,11 @@ struct ltt_session_list *session_get_list(void) */ void session_list_wait_empty(void) { - pthread_mutex_lock(<t_session_list.lock); - while (!cds_list_empty(<t_session_list.head)) { - pthread_cond_wait(<t_session_list.removal_cond, - <t_session_list.lock); + pthread_mutex_lock(&the_session_list.lock); + while (!cds_list_empty(&the_session_list.head)) { + pthread_cond_wait(&the_session_list.removal_cond, &the_session_list.lock); } - pthread_mutex_unlock(<t_session_list.lock); + pthread_mutex_unlock(&the_session_list.lock); } /* @@ -155,7 +160,7 @@ void session_list_wait_empty(void) */ void session_lock_list(void) { - pthread_mutex_lock(<t_session_list.lock); + pthread_mutex_lock(&the_session_list.lock); } /* @@ -163,7 +168,7 @@ void session_lock_list(void) */ int session_trylock_list(void) { - return pthread_mutex_trylock(<t_session_list.lock); + return pthread_mutex_trylock(&the_session_list.lock); } /* @@ -171,7 +176,7 @@ int session_trylock_list(void) */ void session_unlock_list(void) { - pthread_mutex_unlock(<t_session_list.lock); + pthread_mutex_unlock(&the_session_list.lock); } /* @@ -179,17 +184,15 @@ void session_unlock_list(void) * * The caller must hold the session lock. */ -enum consumer_dst_type session_get_consumer_destination_type( - const struct ltt_session *session) +enum consumer_dst_type session_get_consumer_destination_type(const struct ltt_session *session) { /* * The output information is duplicated in both of those session types. * Hence, it doesn't matter from which it is retrieved. However, it is * possible for only one of them to be set. */ - return session->kernel_session ? - session->kernel_session->consumer->type : - session->ust_session->consumer->type; + return session->kernel_session ? session->kernel_session->consumer->type : + session->ust_session->consumer->type; } /* @@ -203,9 +206,8 @@ const char *session_get_net_consumer_hostname(const struct ltt_session *session) const char *hostname = NULL; const struct consumer_output *output; - output = session->kernel_session ? - session->kernel_session->consumer : - session->ust_session->consumer; + output = session->kernel_session ? session->kernel_session->consumer : + session->ust_session->consumer; /* * hostname is assumed to be the same for both control and data @@ -231,13 +233,13 @@ const char *session_get_net_consumer_hostname(const struct ltt_session *session) * The caller must hold the session lock. */ void session_get_net_consumer_ports(const struct ltt_session *session, - uint16_t *control_port, uint16_t *data_port) + uint16_t *control_port, + uint16_t *data_port) { const struct consumer_output *output; - output = session->kernel_session ? - session->kernel_session->consumer : - session->ust_session->consumer; + output = session->kernel_session ? session->kernel_session->consumer : + session->ust_session->consumer; *control_port = output->dst.net.control.port; *data_port = output->dst.net.data.port; } @@ -247,29 +249,28 @@ void session_get_net_consumer_ports(const struct ltt_session *session, * * The caller must hold the session lock. */ -struct lttng_trace_archive_location *session_get_trace_archive_location( - const struct ltt_session *session) +struct lttng_trace_archive_location * +session_get_trace_archive_location(const struct ltt_session *session) { int ret; struct lttng_trace_archive_location *location = NULL; char *chunk_path = NULL; if (session->rotation_state != LTTNG_ROTATION_STATE_COMPLETED || - !session->last_archived_chunk_name) { + !session->last_archived_chunk_name) { goto end; } switch (session_get_consumer_destination_type(session)) { case CONSUMER_DST_LOCAL: ret = asprintf(&chunk_path, - "%s/" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY "/%s", - session_get_base_path(session), - session->last_archived_chunk_name); + "%s/" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY "/%s", + session_get_base_path(session), + session->last_archived_chunk_name); if (ret == -1) { goto end; } - location = lttng_trace_archive_location_local_create( - chunk_path); + location = lttng_trace_archive_location_local_create(chunk_path); break; case CONSUMER_DST_NET: { @@ -277,13 +278,13 @@ struct lttng_trace_archive_location *session_get_trace_archive_location( uint16_t control_port, data_port; hostname = session_get_net_consumer_hostname(session); - session_get_net_consumer_ports(session, - &control_port, - &data_port); + session_get_net_consumer_ports(session, &control_port, &data_port); location = lttng_trace_archive_location_relay_create( - hostname, - LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP, - control_port, data_port, session->last_chunk_path); + hostname, + LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP, + control_port, + data_port, + session->last_chunk_path); break; } default: @@ -331,12 +332,12 @@ end: static void ltt_sessions_ht_destroy(void) { if (ltt_sessions_ht_by_id) { - ht_cleanup_push(ltt_sessions_ht_by_id); + lttng_ht_destroy(ltt_sessions_ht_by_id); ltt_sessions_ht_by_id = NULL; } if (ltt_sessions_ht_by_name) { - ht_cleanup_push(ltt_sessions_ht_by_name); + lttng_ht_destroy(ltt_sessions_ht_by_name); ltt_sessions_ht_by_name = NULL; } @@ -377,24 +378,45 @@ end: /* * Test if ltt_sessions_ht_by_id/name are empty. - * Return 1 if empty, 0 if not empty. + * Return `false` if hash table objects are null. * The session list lock must be held. */ -static int ltt_sessions_ht_empty(void) +static bool ltt_sessions_ht_empty(void) { - unsigned long count; + bool empty = false; if (!ltt_sessions_ht_by_id) { - count = 0; + /* The hash tables do not exist yet. */ goto end; } LTTNG_ASSERT(ltt_sessions_ht_by_name); - count = lttng_ht_get_count(ltt_sessions_ht_by_id); - LTTNG_ASSERT(count == lttng_ht_get_count(ltt_sessions_ht_by_name)); + if (lttng_ht_get_count(ltt_sessions_ht_by_id) != 0) { + /* Not empty.*/ + goto end; + } + + /* + * At this point it is expected that the `ltt_sessions_ht_by_name` ht is + * empty. + * + * The removal from both hash tables is done in two different + * places: + * - removal from `ltt_sessions_ht_by_name` is done during + * `session_destroy()` + * - removal from `ltt_sessions_ht_by_id` is done later + * in `session_release()` on the last reference put. + * + * This means that it is possible for `ltt_sessions_ht_by_name` to be + * empty but for `ltt_sessions_ht_by_id` to still contain objects when + * multiple sessions exists. The reverse is false, hence this sanity + * check. + */ + LTTNG_ASSERT(lttng_ht_get_count(ltt_sessions_ht_by_name) == 0); + empty = true; end: - return count ? 0 : 1; + return empty; } /* @@ -441,10 +463,9 @@ void session_unlock(struct ltt_session *session) pthread_mutex_unlock(&session->lock); } -static -int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, - struct lttng_trace_chunk *new_trace_chunk, - struct lttng_trace_chunk **_current_trace_chunk) +static int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, + struct lttng_trace_chunk *new_trace_chunk, + struct lttng_trace_chunk **_current_trace_chunk) { int ret = 0; unsigned int i, refs_to_acquire = 0, refs_acquired = 0, refs_to_release = 0; @@ -462,13 +483,11 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, current_trace_chunk = session->current_trace_chunk; session->current_trace_chunk = NULL; if (session->ust_session) { - lttng_trace_chunk_put( - session->ust_session->current_trace_chunk); + lttng_trace_chunk_put(session->ust_session->current_trace_chunk); session->ust_session->current_trace_chunk = NULL; } if (session->kernel_session) { - lttng_trace_chunk_put( - session->kernel_session->current_trace_chunk); + lttng_trace_chunk_put(session->kernel_session->current_trace_chunk); session->kernel_session->current_trace_chunk = NULL; } if (!new_trace_chunk) { @@ -482,40 +501,37 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, refs_to_acquire += !!session->ust_session; refs_to_acquire += !!session->kernel_session; - for (refs_acquired = 0; refs_acquired < refs_to_acquire; - refs_acquired++) { + for (refs_acquired = 0; refs_acquired < refs_to_acquire; refs_acquired++) { if (!lttng_trace_chunk_get(new_trace_chunk)) { ERR("Failed to acquire reference to new trace chunk of session \"%s\"", - session->name); + session->name); goto error; } } if (session->ust_session) { - const uint64_t relayd_id = - session->ust_session->consumer->net_seq_index; - const bool is_local_trace = - session->ust_session->consumer->type == - CONSUMER_DST_LOCAL; + const uint64_t relayd_id = session->ust_session->consumer->net_seq_index; + const bool is_local_trace = session->ust_session->consumer->type == + CONSUMER_DST_LOCAL; session->ust_session->current_trace_chunk = new_trace_chunk; if (is_local_trace) { enum lttng_error_code ret_error_code; - ret_error_code = ust_app_create_channel_subdirectories( - session->ust_session); + ret_error_code = + ust_app_create_channel_subdirectories(session->ust_session); if (ret_error_code != LTTNG_OK) { goto error; } } - cds_lfht_for_each_entry( - session->ust_session->consumer->socks->ht, - &iter, socket, node.node) { + cds_lfht_for_each_entry ( + session->ust_session->consumer->socks->ht, &iter, socket, node.node) { pthread_mutex_lock(socket->lock); ret = consumer_create_trace_chunk(socket, - relayd_id, - session->id, new_trace_chunk, - DEFAULT_UST_TRACE_DIR); + relayd_id, + session->id, + new_trace_chunk, + DEFAULT_UST_TRACE_DIR); pthread_mutex_unlock(socket->lock); if (ret) { goto error; @@ -523,30 +539,28 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, } } if (session->kernel_session) { - const uint64_t relayd_id = - session->kernel_session->consumer->net_seq_index; - const bool is_local_trace = - session->kernel_session->consumer->type == - CONSUMER_DST_LOCAL; + const uint64_t relayd_id = session->kernel_session->consumer->net_seq_index; + const bool is_local_trace = session->kernel_session->consumer->type == + CONSUMER_DST_LOCAL; session->kernel_session->current_trace_chunk = new_trace_chunk; if (is_local_trace) { enum lttng_error_code ret_error_code; - ret_error_code = kernel_create_channel_subdirectories( - session->kernel_session); + ret_error_code = + kernel_create_channel_subdirectories(session->kernel_session); if (ret_error_code != LTTNG_OK) { goto error; } } - cds_lfht_for_each_entry( - session->kernel_session->consumer->socks->ht, - &iter, socket, node.node) { + cds_lfht_for_each_entry ( + session->kernel_session->consumer->socks->ht, &iter, socket, node.node) { pthread_mutex_lock(socket->lock); ret = consumer_create_trace_chunk(socket, - relayd_id, - session->id, new_trace_chunk, - DEFAULT_KERNEL_TRACE_DIR); + relayd_id, + session->id, + new_trace_chunk, + DEFAULT_KERNEL_TRACE_DIR); pthread_mutex_unlock(socket->lock); if (ret) { goto error; @@ -588,11 +602,11 @@ error: goto end_no_move; } -struct lttng_trace_chunk *session_create_new_trace_chunk( - const struct ltt_session *session, - const struct consumer_output *consumer_output_override, - const char *session_base_path_override, - const char *chunk_name_override) +struct lttng_trace_chunk * +session_create_new_trace_chunk(const struct ltt_session *session, + const struct consumer_output *consumer_output_override, + const char *session_base_path_override, + const char *chunk_name_override) { int ret; struct lttng_trace_chunk *trace_chunk = NULL; @@ -613,28 +627,26 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( output = consumer_output_override; } else { LTTNG_ASSERT(session->ust_session || session->kernel_session); - output = session->ust_session ? - session->ust_session->consumer : - session->kernel_session->consumer; + 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); + 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", - session->name); + session->name); goto error; } - next_chunk_id = session->most_recent_chunk_id.is_set ? - session->most_recent_chunk_id.value + 1 : 0; + next_chunk_id = + session->most_recent_chunk_id.is_set ? session->most_recent_chunk_id.value + 1 : 0; if (session->current_trace_chunk && - !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { + !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { chunk_status = lttng_trace_chunk_rename_path(session->current_trace_chunk, - DEFAULT_CHUNK_TMP_OLD_DIRECTORY); + DEFAULT_CHUNK_TMP_OLD_DIRECTORY); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { goto error; } @@ -649,15 +661,13 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( new_path = DEFAULT_CHUNK_TMP_NEW_DIRECTORY; } - trace_chunk = lttng_trace_chunk_create(next_chunk_id, - chunk_creation_ts, new_path); + trace_chunk = lttng_trace_chunk_create(next_chunk_id, chunk_creation_ts, new_path); if (!trace_chunk) { goto error; } if (chunk_name_override) { - chunk_status = lttng_trace_chunk_override_name(trace_chunk, - chunk_name_override); + chunk_status = lttng_trace_chunk_override_name(trace_chunk, chunk_name_override); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { goto error; } @@ -671,16 +681,13 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( goto end; } - chunk_status = lttng_trace_chunk_set_credentials(trace_chunk, - &session_credentials); + chunk_status = lttng_trace_chunk_set_credentials(trace_chunk, &session_credentials); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { goto error; } - DBG("Creating base output directory of session \"%s\" at %s", - session->name, base_path); - ret = utils_mkdir_recursive(base_path, S_IRWXU | S_IRWXG, - session->uid, session->gid); + DBG("Creating base output directory of session \"%s\" at %s", session->name, base_path); + ret = utils_mkdir_recursive(base_path, S_IRWXU | S_IRWXG, session->uid, session->gid); if (ret) { goto error; } @@ -688,8 +695,7 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( if (!session_output_directory) { goto error; } - chunk_status = lttng_trace_chunk_set_as_owner(trace_chunk, - session_output_directory); + chunk_status = lttng_trace_chunk_set_as_owner(trace_chunk, session_output_directory); lttng_directory_handle_put(session_output_directory); session_output_directory = NULL; if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { @@ -705,9 +711,9 @@ error: } int session_close_trace_chunk(struct ltt_session *session, - struct lttng_trace_chunk *trace_chunk, - enum lttng_trace_chunk_command_type close_command, - char *closed_trace_chunk_path) + struct lttng_trace_chunk *trace_chunk, + enum lttng_trace_chunk_command_type close_command, + char *closed_trace_chunk_path) { int ret = 0; bool error_occurred = false; @@ -717,8 +723,7 @@ int session_close_trace_chunk(struct ltt_session *session, const time_t chunk_close_timestamp = time(NULL); const char *new_path; - chunk_status = lttng_trace_chunk_set_close_command( - trace_chunk, close_command); + chunk_status = lttng_trace_chunk_set_close_command(trace_chunk, close_command); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ret = -1; goto end; @@ -726,7 +731,7 @@ int session_close_trace_chunk(struct ltt_session *session, if (chunk_close_timestamp == (time_t) -1) { ERR("Failed to sample the close timestamp of the current trace chunk of session \"%s\"", - session->name); + session->name); ret = -1; goto end; } @@ -739,17 +744,17 @@ int session_close_trace_chunk(struct ltt_session *session, new_path = NULL; } if (session->current_trace_chunk && - !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { + !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { /* Rename new chunk path. */ - chunk_status = lttng_trace_chunk_rename_path(session->current_trace_chunk, - new_path); + chunk_status = + lttng_trace_chunk_rename_path(session->current_trace_chunk, new_path); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ret = -1; goto end; } } if (!lttng_trace_chunk_get_name_overridden(trace_chunk) && - close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION) { + close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION) { const char *old_path; if (!session->rotated) { @@ -758,8 +763,7 @@ int session_close_trace_chunk(struct ltt_session *session, old_path = NULL; } /* We need to move back the .tmp_old_chunk to its rightful place. */ - chunk_status = lttng_trace_chunk_rename_path(trace_chunk, - old_path); + chunk_status = lttng_trace_chunk_rename_path(trace_chunk, old_path); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ret = -1; goto end; @@ -768,27 +772,25 @@ int session_close_trace_chunk(struct ltt_session *session, if (close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED) { session->rotated = true; } - chunk_status = lttng_trace_chunk_set_close_timestamp(trace_chunk, - chunk_close_timestamp); + chunk_status = lttng_trace_chunk_set_close_timestamp(trace_chunk, chunk_close_timestamp); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { ERR("Failed to set the close timestamp of the current trace chunk of session \"%s\"", - session->name); + session->name); ret = -1; goto end; } if (session->ust_session) { - const uint64_t relayd_id = - session->ust_session->consumer->net_seq_index; + 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) { + 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, - relayd_id, - session->id, - trace_chunk, closed_trace_chunk_path); + relayd_id, + session->id, + trace_chunk, + closed_trace_chunk_path); pthread_mutex_unlock(socket->lock); if (ret) { ERR("Failed to close trace chunk on user space consumer"); @@ -797,17 +799,16 @@ int session_close_trace_chunk(struct ltt_session *session, } } if (session->kernel_session) { - const uint64_t relayd_id = - session->kernel_session->consumer->net_seq_index; + 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) { + 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, - relayd_id, - session->id, - trace_chunk, closed_trace_chunk_path); + relayd_id, + session->id, + trace_chunk, + closed_trace_chunk_path); pthread_mutex_unlock(socket->lock); if (ret) { ERR("Failed to close trace chunk on kernel consumer"); @@ -836,8 +837,7 @@ end: * daemon as the same "offset" in a metadata stream will no longer point * to the same content. */ -static -enum lttng_error_code session_kernel_open_packets(struct ltt_session *session) +static enum lttng_error_code session_kernel_open_packets(struct ltt_session *session) { enum lttng_error_code ret = LTTNG_OK; struct consumer_socket *socket; @@ -849,15 +849,16 @@ enum lttng_error_code session_kernel_open_packets(struct ltt_session *session) cds_lfht_first(session->kernel_session->consumer->socks->ht, &iter.iter); node = cds_lfht_iter_get_node(&iter.iter); - socket = container_of(node, typeof(*socket), node.node); + socket = caa_container_of(node, typeof(*socket), node.node); - cds_list_for_each_entry(chan, - &session->kernel_session->channel_list.head, list) { + cds_list_for_each_entry (chan, &session->kernel_session->channel_list.head, list) { int open_ret; DBG("Open packet of kernel channel: channel key = %" PRIu64 - ", session name = %s, session_id = %" PRIu64, - chan->key, session->name, session->id); + ", session name = %s, session_id = %" PRIu64, + chan->key, + session->name, + session->id); open_ret = consumer_open_channel_packets(socket, chan->key); if (open_ret < 0) { @@ -877,7 +878,8 @@ enum lttng_error_code session_open_packets(struct ltt_session *session) enum lttng_error_code ret = LTTNG_OK; DBG("Opening packets of session channels: session name = %s, session id = %" PRIu64, - session->name, session->id); + session->name, + session->id); if (session->ust_session) { ret = ust_app_open_packets(session); @@ -903,25 +905,23 @@ end: * Must be called with the session lock held. */ int session_set_trace_chunk(struct ltt_session *session, - struct lttng_trace_chunk *new_trace_chunk, - struct lttng_trace_chunk **current_trace_chunk) + struct lttng_trace_chunk *new_trace_chunk, + struct lttng_trace_chunk **current_trace_chunk) { ASSERT_LOCKED(session->lock); - return _session_set_trace_chunk_no_lock_check(session, new_trace_chunk, - current_trace_chunk); + return _session_set_trace_chunk_no_lock_check( + session, new_trace_chunk, current_trace_chunk); } -static -void session_notify_destruction(const struct ltt_session *session) +static void session_notify_destruction(const struct ltt_session *session) { size_t i; - const size_t count = lttng_dynamic_array_get_count( - &session->destroy_notifiers); + const size_t count = lttng_dynamic_array_get_count(&session->destroy_notifiers); for (i = 0; i < count; i++) { const struct ltt_session_destroy_notifier_element *element = (ltt_session_destroy_notifier_element *) lttng_dynamic_array_get_element( - &session->destroy_notifiers, i); + &session->destroy_notifiers, i); element->notifier(session, element->user_data); } @@ -933,26 +933,24 @@ void session_notify_destruction(const struct ltt_session *session) void session_notify_clear(struct ltt_session *session) { size_t i; - const size_t count = lttng_dynamic_array_get_count( - &session->clear_notifiers); + const size_t count = lttng_dynamic_array_get_count(&session->clear_notifiers); for (i = 0; i < count; i++) { const struct ltt_session_clear_notifier_element *element = (ltt_session_clear_notifier_element *) lttng_dynamic_array_get_element( - &session->clear_notifiers, i); + &session->clear_notifiers, i); element->notifier(session, element->user_data); } lttng_dynamic_array_clear(&session->clear_notifiers); } -static -void session_release(struct urcu_ref *ref) +static void session_release(struct urcu_ref *ref) { int ret; struct ltt_ust_session *usess; struct ltt_kernel_session *ksess; - struct ltt_session *session = container_of(ref, typeof(*session), ref); + struct ltt_session *session = lttng::utils::container_of(ref, <t_session::ref); const bool session_published = session->published; LTTNG_ASSERT(!session->chunk_being_archived); @@ -994,7 +992,7 @@ void session_release(struct urcu_ref *ref) pthread_mutex_destroy(&session->lock); if (session_published) { - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_LOCKED(the_session_list.lock); del_session_list(session); del_session_ht(session); } @@ -1011,14 +1009,15 @@ void session_release(struct urcu_ref *ref) lttng_dynamic_array_reset(&session->clear_notifiers); free(session->last_archived_chunk_name); free(session->base_path); + lttng_trigger_put(session->rotate_trigger); free(session); if (session_published) { /* * Broadcast after free-ing to ensure the memory is * reclaimed before the main thread exits. */ - ASSERT_LOCKED(ltt_session_list.lock); - pthread_cond_broadcast(<t_session_list.removal_cond); + ASSERT_LOCKED(the_session_list.lock); + pthread_cond_broadcast(&the_session_list.removal_cond); } } @@ -1043,7 +1042,7 @@ void session_put(struct ltt_session *session) * The session list lock must be held as any session_put() * may cause the removal of the session from the session_list. */ - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_LOCKED(the_session_list.lock); LTTNG_ASSERT(session->ref.refcount); urcu_ref_put(&session->ref, session_release); } @@ -1082,27 +1081,23 @@ void session_destroy(struct ltt_session *session) } int session_add_destroy_notifier(struct ltt_session *session, - ltt_session_destroy_notifier notifier, void *user_data) + ltt_session_destroy_notifier notifier, + void *user_data) { - const struct ltt_session_destroy_notifier_element element = { - .notifier = notifier, - .user_data = user_data - }; + const struct ltt_session_destroy_notifier_element element = { .notifier = notifier, + .user_data = user_data }; - return lttng_dynamic_array_add_element(&session->destroy_notifiers, - &element); + return lttng_dynamic_array_add_element(&session->destroy_notifiers, &element); } int session_add_clear_notifier(struct ltt_session *session, - ltt_session_clear_notifier notifier, void *user_data) + ltt_session_clear_notifier notifier, + void *user_data) { - const struct ltt_session_clear_notifier_element element = { - .notifier = notifier, - .user_data = user_data - }; + const struct ltt_session_clear_notifier_element element = { .notifier = notifier, + .user_data = user_data }; - return lttng_dynamic_array_add_element(&session->clear_notifiers, - &element); + return lttng_dynamic_array_add_element(&session->clear_notifiers, &element); } /* @@ -1116,13 +1111,12 @@ struct ltt_session *session_find_by_name(const char *name) struct ltt_session *iter; LTTNG_ASSERT(name); - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_LOCKED(the_session_list.lock); DBG2("Trying to find session by name %s", name); - cds_list_for_each_entry(iter, <t_session_list.head, list) { - if (!strncmp(iter->name, name, NAME_MAX) && - !iter->destroyed) { + cds_list_for_each_entry (iter, &the_session_list.head, list) { + if (!strncmp(iter->name, name, NAME_MAX) && !iter->destroyed) { goto found; } } @@ -1143,7 +1137,8 @@ struct ltt_session *session_find_by_id(uint64_t id) struct lttng_ht_iter iter; struct ltt_session *ls; - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_RCU_READ_LOCKED(); + ASSERT_LOCKED(the_session_list.lock); if (!ltt_sessions_ht_by_id) { goto end; @@ -1154,7 +1149,7 @@ struct ltt_session *session_find_by_id(uint64_t id) if (node == NULL) { goto end; } - ls = caa_container_of(node, struct ltt_session, node); + ls = lttng::utils::container_of(node, <t_session::node); DBG3("Session %" PRIu64 " found by id.", id); return session_get(ls) ? ls : NULL; @@ -1168,14 +1163,14 @@ end: * Create a new session and add it to the session list. * 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) +enum lttng_error_code +session_create(const char *name, uid_t uid, gid_t gid, struct ltt_session **out_session) { int ret; enum lttng_error_code ret_code; struct ltt_session *new_session = NULL; - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_LOCKED(the_session_list.lock); if (name) { struct ltt_session *clashing_session; @@ -1186,7 +1181,7 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, goto error; } } - new_session = (ltt_session *) zmalloc(sizeof(struct ltt_session)); + new_session = zmalloc(); if (!new_session) { PERROR("Failed to allocate an ltt_session structure"); ret_code = LTTNG_ERR_NOMEM; @@ -1194,11 +1189,11 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, } lttng_dynamic_array_init(&new_session->destroy_notifiers, - sizeof(struct ltt_session_destroy_notifier_element), - NULL); + sizeof(struct ltt_session_destroy_notifier_element), + NULL); lttng_dynamic_array_init(&new_session->clear_notifiers, - sizeof(struct ltt_session_clear_notifier_element), - NULL); + sizeof(struct ltt_session_clear_notifier_element), + NULL); urcu_ref_init(&new_session->ref); pthread_mutex_init(&new_session->lock, NULL); @@ -1244,16 +1239,17 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, if (i == 0) { ret = snprintf(new_session->name, - sizeof(new_session->name), - "%s-%s", - DEFAULT_SESSION_NAME, - datetime); + sizeof(new_session->name), + "%s-%s", + DEFAULT_SESSION_NAME, + datetime); } else { ret = snprintf(new_session->name, - sizeof(new_session->name), - "%s%d-%s", - DEFAULT_SESSION_NAME, i, - datetime); + sizeof(new_session->name), + "%s%d-%s", + DEFAULT_SESSION_NAME, + i, + datetime); } new_session->name_contains_creation_time = true; if (ret == -1 || ret >= sizeof(new_session->name)) { @@ -1266,8 +1262,7 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, goto error; } - clashing_session = - session_find_by_name(new_session->name); + clashing_session = session_find_by_name(new_session->name); session_put(clashing_session); if (!clashing_session) { found_name = true; @@ -1289,7 +1284,7 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, if (errno == ENAMETOOLONG) { new_session->hostname[sizeof(new_session->hostname) - 1] = '\0'; ERR("Hostname exceeds the maximal permitted length and has been truncated to %s", - new_session->hostname); + new_session->hostname); } else { ret_code = LTTNG_ERR_SESSION_FAIL; goto error; @@ -1324,8 +1319,10 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, * set it up and, if valid, assign it to the session. */ DBG("Tracing session %s created with ID %" PRIu64 " by uid = %d, gid = %d", - new_session->name, new_session->id, new_session->uid, - new_session->gid); + new_session->name, + new_session->id, + new_session->uid, + new_session->gid); ret_code = LTTNG_OK; end: if (new_session) { @@ -1364,12 +1361,11 @@ bool session_access_ok(struct ltt_session *session, uid_t uid) * * Must be called with the session and session_list locks held. */ -int session_reset_rotation_state(struct ltt_session *session, - enum lttng_rotation_state result) +int session_reset_rotation_state(struct ltt_session *session, enum lttng_rotation_state result) { int ret = 0; - ASSERT_LOCKED(ltt_session_list.lock); + ASSERT_LOCKED(the_session_list.lock); ASSERT_LOCKED(session->lock); session->rotation_state = result; @@ -1380,12 +1376,9 @@ int session_reset_rotation_state(struct ltt_session *session, uint64_t chunk_id; enum lttng_trace_chunk_status chunk_status; - chunk_status = lttng_trace_chunk_get_id( - session->chunk_being_archived, - &chunk_id); + chunk_status = lttng_trace_chunk_get_id(session->chunk_being_archived, &chunk_id); LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK); - LTTNG_OPTIONAL_SET(&session->last_archived_chunk_id, - chunk_id); + LTTNG_OPTIONAL_SET(&session->last_archived_chunk_id, chunk_id); lttng_trace_chunk_put(session->chunk_being_archived); session->chunk_being_archived = NULL; /* @@ -1427,7 +1420,7 @@ bool sample_session_id_by_name(const char *name, uint64_t *id) goto end; } - ls = caa_container_of(node, struct ltt_session, node_by_name); + ls = lttng::utils::container_of(node, <t_session::node_by_name); *id = ls->id; found = true; @@ -1436,3 +1429,38 @@ end: rcu_read_unlock(); return found; } + +void ls::details::locked_session_release(ltt_session *session) +{ + session_unlock(session); + session_put(session); +} + +ltt_session::locked_ptr ls::find_locked_session_by_id(ltt_session::id_t id) +{ + lttng::urcu::read_lock_guard rcu_lock; + auto session = session_find_by_id(id); + + if (!session) { + return nullptr; + } + + /* + * The pointer falling out of scope will unlock and release the reference to the + * session. + */ + session_lock(session); + return ltt_session::locked_ptr(session); +} + +ltt_session::sptr ls::find_session_by_id(ltt_session::id_t id) +{ + lttng::urcu::read_lock_guard rcu_lock; + auto session = session_find_by_id(id); + + if (!session) { + return nullptr; + } + + return { session, session_put }; +}