From 139a8d250fb18f8ffc95b0936f7285f7b484b72f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Mon, 27 Jun 2022 12:01:48 -0400 Subject: [PATCH] Fix: sessiond: size-based rotation threshold exceeded in per-pid tracing (1/2) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Issue observed -------------- When tracing short-lived applications with buffers configured in per-pid mode, the size-based rotation threshold is often greatly exceeded. In the CI, this occasionally causes the size-based rotation tests to timeout for the per-pid case. Cause ----- There is a scenario where a session's consumed size is miscalculated. When an application exits during per-pid tracing, both the session and consumer daemons notice it. The session daemon sees the application's command pipe hanging-up, while the consumer daemon sees the application's data-ready pipe hanging-up. Upon handling these events, both daemons tear down their representation of the channels. In an ideal world, we'd want to sample the streams' "consumed_size" at the last possible moment to get the size of all consumed data for this stream. However, this is problematic in the following scenario: - the sessiond destroys the channel before the consumer daemon, - the consumer daemon sends a final buffer stats sample on tear down, - the sessiond can do nothing with the sample as it doesn't know that channel anymore. (Note that the session daemon gracefully handles the case where it doesn't know a channel.) When applications have a short lifetime and are traced in per-PID buffering mode, there is a high likelihood that the last buffer statistics sample sent for a given channel will target a channel that the session daemon has already torn down. Solution -------- Consumed-size conditions are somewhat special: they are bound to a session, but they are evaluated through a per-channel event (buffer statistics samples taken by the channels' monitoring timer). To work around the problem of lifetime of channels, we can rely on the fact that sessions outlive channels to perform the accounting of the consumed size. This patch is the first step to implement this fix: new notification-thread commands are introduced to announce the creation and destruction of an `ltt_session`. Currently, the notification thread implies the existence of a session by tracking its channels' creation and destruction. With this change, it no longer needs to do so; session are explicitly created and destroyed. Their unique ID is also kept stored. The key of `sessions_ht` becomes the `id` of the session to allow efficient look-ups on the reception of a buffer statistics sample. The existing callsites that make use of the session's name to perform a look-up are modified to look-up the id by name (see sample_session_id_by_name()). The add/remove channel commands and rotation ongoing/completed commands are modified to refer to sessions by ID since they can assume the notification thread knows about the session. Note ---- In a follow-up patch, buffer statistics samples are modified to include the session's ID and the consumed size is modified to become a "delta" relative to the previous sample associated with a given channel. This makes it possible to perform the accounting of a session's consumed size beyond the lifetime of its channels. The follow-up patch is the "core" of the fix, but it requires these prior changes. Signed-off-by: Jérémie Galarneau Change-Id: I865e9ac5e1a63e62123209be63957dad28c588a8 --- src/bin/lttng-sessiond/cmd.cpp | 25 +- src/bin/lttng-sessiond/kernel-consumer.cpp | 9 +- .../notification-thread-commands.cpp | 67 ++++- .../notification-thread-commands.hpp | 38 ++- .../notification-thread-events.cpp | 266 ++++++++++++------ .../notification-thread-internal.hpp | 1 + .../lttng-sessiond/notification-thread.hpp | 16 +- src/bin/lttng-sessiond/rotation-thread.cpp | 4 +- src/bin/lttng-sessiond/ust-app.cpp | 12 +- 9 files changed, 310 insertions(+), 128 deletions(-) diff --git a/src/bin/lttng-sessiond/cmd.cpp b/src/bin/lttng-sessiond/cmd.cpp index fe9656a89..0b7492055 100644 --- a/src/bin/lttng-sessiond/cmd.cpp +++ b/src/bin/lttng-sessiond/cmd.cpp @@ -3136,6 +3136,28 @@ enum lttng_error_code cmd_create_session_from_descriptor( goto end; } + ret_code = notification_thread_command_add_session(the_notification_thread_handle, + new_session->id, new_session->name, new_session->uid, new_session->gid); + if (ret_code != LTTNG_OK) { + goto end; + } + + /* Announce the session's destruction to the notification thread when it is destroyed. */ + ret = session_add_destroy_notifier( + new_session, + [](const struct ltt_session *session, + void *user_data __attribute__((unused))) { + (void) notification_thread_command_remove_session( + the_notification_thread_handle, session->id); + }, + NULL); + if (ret) { + PERROR("Failed to add notification thread command to session's destroy notifiers: session name = %s", + new_session->name); + ret = LTTNG_ERR_NOMEM; + goto end; + } + if (!session_name) { ret = lttng_session_descriptor_set_session_name(descriptor, new_session->name); @@ -5609,8 +5631,7 @@ int cmd_rotate_session(struct ltt_session *session, chunk_being_archived = NULL; if (!quiet_rotation) { ret = notification_thread_command_session_rotation_ongoing( - the_notification_thread_handle, session->name, - session->uid, session->gid, + the_notification_thread_handle, session->id, ongoing_rotation_chunk_id); if (ret != LTTNG_OK) { ERR("Failed to notify notification thread that a session rotation is ongoing for session %s", diff --git a/src/bin/lttng-sessiond/kernel-consumer.cpp b/src/bin/lttng-sessiond/kernel-consumer.cpp index ece50de11..b51b56c3e 100644 --- a/src/bin/lttng-sessiond/kernel-consumer.cpp +++ b/src/bin/lttng-sessiond/kernel-consumer.cpp @@ -172,12 +172,9 @@ int kernel_consumer_add_channel(struct consumer_socket *sock, ASSERT_LOCKED(session->lock); ASSERT_SESSION_LIST_LOCKED(); - status = notification_thread_command_add_channel( - the_notification_thread_handle, session->name, - ksession->uid, ksession->gid, channel->channel->name, - channel->key, LTTNG_DOMAIN_KERNEL, - channel->channel->attr.subbuf_size * - channel->channel->attr.num_subbuf); + status = notification_thread_command_add_channel(the_notification_thread_handle, + session->id, channel->channel->name, channel->key, LTTNG_DOMAIN_KERNEL, + channel->channel->attr.subbuf_size * channel->channel->attr.num_subbuf); rcu_read_unlock(); if (status != LTTNG_OK) { ret = -1; diff --git a/src/bin/lttng-sessiond/notification-thread-commands.cpp b/src/bin/lttng-sessiond/notification-thread-commands.cpp index 1de6ff58b..25c987b67 100644 --- a/src/bin/lttng-sessiond/notification-thread-commands.cpp +++ b/src/bin/lttng-sessiond/notification-thread-commands.cpp @@ -160,9 +160,58 @@ end: return ret_code; } +enum lttng_error_code notification_thread_command_add_session( + struct notification_thread_handle *handle, + uint64_t session_id, const char *session_name, uid_t session_uid, gid_t session_gid) +{ + int ret; + enum lttng_error_code ret_code; + struct notification_thread_command cmd = {}; + + init_notification_thread_command(&cmd); + + cmd.type = NOTIFICATION_COMMAND_TYPE_ADD_SESSION; + cmd.parameters.add_session.session_id = session_id; + cmd.parameters.add_session.session_name = session_name; + cmd.parameters.add_session.session_uid = session_uid; + cmd.parameters.add_session.session_gid = session_gid; + + ret = run_command_wait(handle, &cmd); + if (ret) { + ret_code = LTTNG_ERR_UNK; + goto end; + } + ret_code = cmd.reply_code; +end: + return ret_code; +} + +enum lttng_error_code notification_thread_command_remove_session( + struct notification_thread_handle *handle, + uint64_t session_id) +{ + int ret; + enum lttng_error_code ret_code; + struct notification_thread_command cmd = {}; + + init_notification_thread_command(&cmd); + + cmd.type = NOTIFICATION_COMMAND_TYPE_REMOVE_SESSION; + cmd.parameters.remove_session.session_id = session_id; + + ret = run_command_wait(handle, &cmd); + if (ret) { + ret_code = LTTNG_ERR_UNK; + goto end; + } + ret_code = cmd.reply_code; +end: + return ret_code; +} + enum lttng_error_code notification_thread_command_add_channel( struct notification_thread_handle *handle, - char *session_name, uid_t uid, gid_t gid, + uint64_t session_id, char *channel_name, uint64_t key, enum lttng_domain_type domain, uint64_t capacity) { @@ -173,9 +222,7 @@ enum lttng_error_code notification_thread_command_add_channel( init_notification_thread_command(&cmd); cmd.type = NOTIFICATION_COMMAND_TYPE_ADD_CHANNEL; - cmd.parameters.add_channel.session.name = session_name; - cmd.parameters.add_channel.session.uid = uid; - cmd.parameters.add_channel.session.gid = gid; + cmd.parameters.add_channel.session.id = session_id; cmd.parameters.add_channel.channel.name = channel_name; cmd.parameters.add_channel.channel.key = key; cmd.parameters.add_channel.channel.domain = domain; @@ -217,7 +264,7 @@ end: enum lttng_error_code notification_thread_command_session_rotation_ongoing( struct notification_thread_handle *handle, - const char *session_name, uid_t uid, gid_t gid, + uint64_t session_id, uint64_t trace_archive_chunk_id) { int ret; @@ -227,9 +274,7 @@ enum lttng_error_code notification_thread_command_session_rotation_ongoing( init_notification_thread_command(&cmd); cmd.type = NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING; - cmd.parameters.session_rotation.session_name = session_name; - cmd.parameters.session_rotation.uid = uid; - cmd.parameters.session_rotation.gid = gid; + cmd.parameters.session_rotation.session_id = session_id; cmd.parameters.session_rotation.trace_archive_chunk_id = trace_archive_chunk_id; @@ -245,7 +290,7 @@ end: enum lttng_error_code notification_thread_command_session_rotation_completed( struct notification_thread_handle *handle, - const char *session_name, uid_t uid, gid_t gid, + uint64_t session_id, uint64_t trace_archive_chunk_id, struct lttng_trace_archive_location *location) { @@ -256,9 +301,7 @@ enum lttng_error_code notification_thread_command_session_rotation_completed( init_notification_thread_command(&cmd); cmd.type = NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED; - cmd.parameters.session_rotation.session_name = session_name; - cmd.parameters.session_rotation.uid = uid; - cmd.parameters.session_rotation.gid = gid; + cmd.parameters.session_rotation.session_id = session_id; cmd.parameters.session_rotation.trace_archive_chunk_id = trace_archive_chunk_id; cmd.parameters.session_rotation.location = location; diff --git a/src/bin/lttng-sessiond/notification-thread-commands.hpp b/src/bin/lttng-sessiond/notification-thread-commands.hpp index 98b0abcee..293a0b4b7 100644 --- a/src/bin/lttng-sessiond/notification-thread-commands.hpp +++ b/src/bin/lttng-sessiond/notification-thread-commands.hpp @@ -25,6 +25,8 @@ enum notification_thread_command_type { NOTIFICATION_COMMAND_TYPE_UNREGISTER_TRIGGER, NOTIFICATION_COMMAND_TYPE_ADD_CHANNEL, NOTIFICATION_COMMAND_TYPE_REMOVE_CHANNEL, + NOTIFICATION_COMMAND_TYPE_ADD_SESSION, + NOTIFICATION_COMMAND_TYPE_REMOVE_SESSION, NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING, NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED, NOTIFICATION_COMMAND_TYPE_ADD_TRACER_EVENT_SOURCE, @@ -49,12 +51,21 @@ struct notification_thread_command { struct { const struct lttng_trigger *trigger; } unregister_trigger; + /* Add session. */ + struct { + uint64_t session_id; + const char *session_name; + uid_t session_uid; + gid_t session_gid; + } add_session; + /* Remove session. */ + struct { + uint64_t session_id; + } remove_session; /* Add channel. */ struct { struct { - const char *name; - uid_t uid; - gid_t gid; + uint64_t id; } session; struct { const char *name; @@ -69,9 +80,7 @@ struct notification_thread_command { enum lttng_domain_type domain; } remove_channel; struct { - const char *session_name; - uid_t uid; - gid_t gid; + uint64_t session_id; uint64_t trace_archive_chunk_id; /* Weak reference. */ struct lttng_trace_archive_location *location; @@ -121,9 +130,20 @@ enum lttng_error_code notification_thread_command_unregister_trigger( struct notification_thread_handle *handle, const struct lttng_trigger *trigger); +enum lttng_error_code notification_thread_command_add_session( + struct notification_thread_handle *handle, + uint64_t session_id, + const char *session_name, + uid_t session_uid, + gid_t session_gid); + +enum lttng_error_code notification_thread_command_remove_session( + struct notification_thread_handle *handle, + uint64_t session_id); + enum lttng_error_code notification_thread_command_add_channel( struct notification_thread_handle *handle, - char *session_name, uid_t session_uid, gid_t session_gid, + uint64_t session_id, char *channel_name, uint64_t key, enum lttng_domain_type domain, uint64_t capacity); @@ -133,13 +153,13 @@ enum lttng_error_code notification_thread_command_remove_channel( enum lttng_error_code notification_thread_command_session_rotation_ongoing( struct notification_thread_handle *handle, - const char *session_name, uid_t session_uid, gid_t session_gid, + uint64_t session_id, uint64_t trace_archive_chunk_id); /* Ownership of location is transferred. */ enum lttng_error_code notification_thread_command_session_rotation_completed( struct notification_thread_handle *handle, - const char *session_name, uid_t session_uid, gid_t session_gid, + uint64_t session_id, uint64_t trace_archive_chunk_id, struct lttng_trace_archive_location *location); diff --git a/src/bin/lttng-sessiond/notification-thread-events.cpp b/src/bin/lttng-sessiond/notification-thread-events.cpp index 3c33ee79f..586a9900b 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.cpp +++ b/src/bin/lttng-sessiond/notification-thread-events.cpp @@ -168,13 +168,14 @@ void session_info_get(struct session_info *session_info); static void session_info_put(struct session_info *session_info); static -struct session_info *session_info_create(const char *name, - uid_t uid, gid_t gid, +struct session_info *session_info_create(uint64_t id, + const char *name, + uid_t uid, + gid_t gid, struct lttng_session_trigger_list *trigger_list, struct cds_lfht *sessions_ht); -static -void session_info_add_channel(struct session_info *session_info, - struct channel_info *channel_info); +static void session_info_add_channel( + struct session_info *session_info, struct channel_info *channel_info); static void session_info_remove_channel(struct session_info *session_info, struct channel_info *channel_info); @@ -322,13 +323,60 @@ int match_client_list_condition(struct cds_lfht_node *node, const void *key) } static -int match_session(struct cds_lfht_node *node, const void *key) +int match_session_info(struct cds_lfht_node *node, const void *key) { - const char *name = (const char *) key; - struct session_info *session_info = lttng::utils::container_of( + const auto session_id = *((uint64_t *) key); + const auto *session_info = lttng::utils::container_of( node, &session_info::sessions_ht_node); - return !strcmp(session_info->name, name); + return session_id == session_info->id; +} + +static +unsigned long hash_session_info_id(uint64_t id) +{ + return hash_key_u64(&id, lttng_ht_seed); +} + +static +unsigned long hash_session_info(const struct session_info *session_info) +{ + return hash_session_info_id(session_info->id); +} + +static +struct session_info *get_session_info_by_id( + const struct notification_thread_state *state, uint64_t id) +{ + struct cds_lfht_iter iter; + struct cds_lfht_node *node; + lttng::urcu::read_lock_guard read_lock_guard; + + cds_lfht_lookup(state->sessions_ht, + hash_session_info_id(id), + match_session_info, + &id, + &iter); + node = cds_lfht_iter_get_node(&iter); + + if (node) { + auto session_info = lttng::utils::container_of(node, &session_info::sessions_ht_node); + + session_info_get(session_info); + return session_info; + } + + return NULL; +} + +static +struct session_info *get_session_info_by_name( + const struct notification_thread_state *state, const char *name) +{ + uint64_t session_id; + const auto found = sample_session_id_by_name(name, &session_id); + + return found ? get_session_info_by_id(state, session_id) : NULL; } static @@ -344,6 +392,10 @@ const char *notification_command_type_str( return "ADD_CHANNEL"; case NOTIFICATION_COMMAND_TYPE_REMOVE_CHANNEL: return "REMOVE_CHANNEL"; + case NOTIFICATION_COMMAND_TYPE_ADD_SESSION: + return "ADD_SESSION"; + case NOTIFICATION_COMMAND_TYPE_REMOVE_SESSION: + return "REMOVE_SESSION"; case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING: return "SESSION_ROTATION_ONGOING"; case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED: @@ -563,7 +615,10 @@ void session_info_put(struct session_info *session_info) } static -struct session_info *session_info_create(const char *name, uid_t uid, gid_t gid, +struct session_info *session_info_create(uint64_t id, + const char *name, + uid_t uid, + gid_t gid, struct lttng_session_trigger_list *trigger_list, struct cds_lfht *sessions_ht) { @@ -575,6 +630,7 @@ struct session_info *session_info_create(const char *name, uid_t uid, gid_t gid, if (!session_info) { goto end; } + lttng_ref_init(&session_info->ref, session_info_destroy); session_info->channel_infos_ht = cds_lfht_new(DEFAULT_HT_SIZE, @@ -584,10 +640,12 @@ struct session_info *session_info_create(const char *name, uid_t uid, gid_t gid, } cds_lfht_node_init(&session_info->sessions_ht_node); + session_info->id = id; session_info->name = strdup(name); if (!session_info->name) { goto error; } + session_info->uid = uid; session_info->gid = gid; session_info->trigger_list = trigger_list; @@ -960,32 +1018,21 @@ int evaluate_session_condition_for_client( uid_t *session_uid, gid_t *session_gid) { int ret; - struct cds_lfht_iter iter; - struct cds_lfht_node *node; const char *session_name; struct session_info *session_info = NULL; rcu_read_lock(); session_name = get_condition_session_name(condition); - /* Find the session associated with the trigger. */ - cds_lfht_lookup(state->sessions_ht, - hash_key_str(session_name, lttng_ht_seed), - match_session, - session_name, - &iter); - node = cds_lfht_iter_get_node(&iter); - if (!node) { - DBG("No known session matching name \"%s\"", + /* Find the session associated with the condition. */ + session_info = get_session_info_by_name(state, session_name); + if (!session_info) { + DBG("Unknown session while evaluating session condition for client: name = `%s`", session_name); ret = 0; goto end; } - session_info = caa_container_of(node, struct session_info, - sessions_ht_node); - session_info_get(session_info); - /* * Evaluation is performed in-line here since only one type of * session-bound condition is handled for the moment. @@ -1654,39 +1701,22 @@ error: } static -struct session_info *find_or_create_session_info( - struct notification_thread_state *state, - const char *name, uid_t uid, gid_t gid) +struct session_info *create_and_publish_session_info(struct notification_thread_state *state, + uint64_t id, + const char *name, + uid_t uid, + gid_t gid) { struct session_info *session = NULL; - struct cds_lfht_node *node; - struct cds_lfht_iter iter; struct lttng_session_trigger_list *trigger_list; rcu_read_lock(); - cds_lfht_lookup(state->sessions_ht, - hash_key_str(name, lttng_ht_seed), - match_session, - name, - &iter); - node = cds_lfht_iter_get_node(&iter); - if (node) { - DBG("Found session info of session \"%s\" (uid = %i, gid = %i)", - name, uid, gid); - session = caa_container_of(node, struct session_info, - sessions_ht_node); - LTTNG_ASSERT(session->uid == uid); - LTTNG_ASSERT(session->gid == gid); - session_info_get(session); - goto end; - } - trigger_list = lttng_session_trigger_list_build(state, name); if (!trigger_list) { goto error; } - session = session_info_create(name, uid, gid, trigger_list, + session = session_info_create(id, name, uid, gid, trigger_list, state->sessions_ht); if (!session) { ERR("Failed to allocation session info for session \"%s\" (uid = %i, gid = %i)", @@ -1694,11 +1724,16 @@ struct session_info *find_or_create_session_info( lttng_session_trigger_list_destroy(trigger_list); goto error; } + + /* Transferred ownership to the new session. */ trigger_list = NULL; - cds_lfht_add(state->sessions_ht, hash_key_str(name, lttng_ht_seed), - &session->sessions_ht_node); -end: + if (cds_lfht_add_unique(state->sessions_ht, hash_session_info(session), match_session_info, + &id, &session->sessions_ht_node) != &session->sessions_ht_node) { + ERR("Duplicate session found: name = `%s`, id = %" PRIu64, name, id); + goto error; + } + rcu_read_unlock(); return session; error: @@ -1708,11 +1743,12 @@ error: } static -int handle_notification_thread_command_add_channel( - struct notification_thread_state *state, - const char *session_name, uid_t session_uid, gid_t session_gid, - const char *channel_name, enum lttng_domain_type channel_domain, - uint64_t channel_key_int, uint64_t channel_capacity, +int handle_notification_thread_command_add_channel(struct notification_thread_state *state, + uint64_t session_id, + const char *channel_name, + enum lttng_domain_type channel_domain, + uint64_t channel_key_int, + uint64_t channel_capacity, enum lttng_error_code *cmd_result) { struct cds_list_head trigger_list; @@ -1727,16 +1763,17 @@ int handle_notification_thread_command_add_channel( struct cds_lfht_iter iter; struct session_info *session_info = NULL; - DBG("Adding channel %s from session %s, channel key = %" PRIu64 " in %s domain", - channel_name, session_name, channel_key_int, + DBG("Adding channel: channel name = `%s`, session id = %" PRIu64 ", channel key = %" PRIu64 ", domain = %s", + channel_name, session_id, channel_key_int, lttng_domain_type_str(channel_domain)); CDS_INIT_LIST_HEAD(&trigger_list); - session_info = find_or_create_session_info(state, session_name, - session_uid, session_gid); + session_info = get_session_info_by_id(state, session_id); if (!session_info) { - /* Allocation error or an internal error occurred. */ + /* Fatal logic error. */ + ERR("Failed to find session while adding channel: session id = %" PRIu64, + session_id); goto error; } @@ -1802,6 +1839,67 @@ error: return 1; } +static +int handle_notification_thread_command_add_session(struct notification_thread_state *state, + uint64_t session_id, + const char *session_name, + uid_t session_uid, + gid_t session_gid, + enum lttng_error_code *cmd_result) +{ + int ret; + + DBG("Adding session: session name = `%s`, session id = %" PRIu64 ", session uid = %d, session gid = %d", + session_name, session_id, session_uid, session_gid); + + auto session = create_and_publish_session_info(state, session_id, session_name, session_uid, session_gid); + if (!session) { + PERROR("Failed to add session: session name = `%s`, session id = %" PRIu64 ", session uid = %d, session gid = %d", + session_name, session_id, session_uid, session_gid); + ret = -1; + *cmd_result = LTTNG_ERR_NOMEM; + goto end; + } + + /* + * Note that the reference to `session` is not released; this reference is + * the "global" reference that is used to allow look-ups. This reference will + * only be released when the session is removed. See + * handle_notification_thread_command_remove_session. + */ + ret = 0; + *cmd_result = LTTNG_OK; +end: + return ret; +} + +static +int handle_notification_thread_command_remove_session( + struct notification_thread_state *state, + uint64_t session_id, + enum lttng_error_code *cmd_result) +{ + int ret; + + DBG("Removing session: session id = %" PRIu64, session_id); + + auto session = get_session_info_by_id(state, session_id); + if (!session) { + ERR("Failed to remove session: session id = %" PRIu64, session_id); + ret = -1; + *cmd_result = LTTNG_ERR_NO_SESSION; + goto end; + } + + /* Release the reference returned by the look-up, and then release the global reference. */ + session_info_put(session); + session_info_put(session); + ret = 0; + *cmd_result = LTTNG_OK; +end: + return ret; +} + static void free_channel_trigger_list_rcu(struct rcu_head *node) { @@ -1902,7 +2000,7 @@ static int handle_notification_thread_command_session_rotation( struct notification_thread_state *state, enum notification_thread_command_type cmd_type, - const char *session_name, uid_t session_uid, gid_t session_gid, + uint64_t session_id, uint64_t trace_archive_chunk_id, struct lttng_trace_archive_location *location, enum lttng_error_code *_cmd_result) @@ -1912,29 +2010,32 @@ int handle_notification_thread_command_session_rotation( struct lttng_session_trigger_list *trigger_list; struct lttng_trigger_list_element *trigger_list_element; struct session_info *session_info; - const struct lttng_credentials session_creds = { - .uid = LTTNG_OPTIONAL_INIT_VALUE(session_uid), - .gid = LTTNG_OPTIONAL_INIT_VALUE(session_gid), - }; + struct lttng_credentials session_creds; rcu_read_lock(); - session_info = find_or_create_session_info(state, session_name, - session_uid, session_gid); + session_info = get_session_info_by_id(state, session_id); if (!session_info) { - /* Allocation error or an internal error occurred. */ + /* Fatal logic error. */ + ERR("Failed to find session while handling rotation state change: session id = %" PRIu64, + session_id); ret = -1; - cmd_result = LTTNG_ERR_NOMEM; + cmd_result = LTTNG_ERR_FATAL; goto end; } + session_creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(session_info->uid), + .gid = LTTNG_OPTIONAL_INIT_VALUE(session_info->gid), + }; + session_info->rotation.ongoing = cmd_type == NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING; session_info->rotation.id = trace_archive_chunk_id; - trigger_list = get_session_trigger_list(state, session_name); + trigger_list = get_session_trigger_list(state, session_info->name); if (!trigger_list) { - DBG("No triggers applying to session \"%s\" found", - session_name); + DBG("No triggers apply to session: session name = `%s` ", + session_info->name); goto end; } @@ -3180,9 +3281,7 @@ int handle_notification_thread_command( case NOTIFICATION_COMMAND_TYPE_ADD_CHANNEL: ret = handle_notification_thread_command_add_channel( state, - cmd->parameters.add_channel.session.name, - cmd->parameters.add_channel.session.uid, - cmd->parameters.add_channel.session.gid, + cmd->parameters.add_channel.session.id, cmd->parameters.add_channel.channel.name, cmd->parameters.add_channel.channel.domain, cmd->parameters.add_channel.channel.key, @@ -3195,14 +3294,23 @@ int handle_notification_thread_command( cmd->parameters.remove_channel.domain, &cmd->reply_code); break; + case NOTIFICATION_COMMAND_TYPE_ADD_SESSION: + ret = handle_notification_thread_command_add_session(state, + cmd->parameters.add_session.session_id, + cmd->parameters.add_session.session_name, + cmd->parameters.add_session.session_uid, + cmd->parameters.add_session.session_gid, &cmd->reply_code); + break; + case NOTIFICATION_COMMAND_TYPE_REMOVE_SESSION: + ret = handle_notification_thread_command_remove_session( + state, cmd->parameters.remove_session.session_id, &cmd->reply_code); + break; case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_ONGOING: case NOTIFICATION_COMMAND_TYPE_SESSION_ROTATION_COMPLETED: ret = handle_notification_thread_command_session_rotation( state, cmd->type, - cmd->parameters.session_rotation.session_name, - cmd->parameters.session_rotation.uid, - cmd->parameters.session_rotation.gid, + cmd->parameters.session_rotation.session_id, cmd->parameters.session_rotation.trace_archive_chunk_id, cmd->parameters.session_rotation.location, &cmd->reply_code); diff --git a/src/bin/lttng-sessiond/notification-thread-internal.hpp b/src/bin/lttng-sessiond/notification-thread-internal.hpp index 0c992073e..b53c24b23 100644 --- a/src/bin/lttng-sessiond/notification-thread-internal.hpp +++ b/src/bin/lttng-sessiond/notification-thread-internal.hpp @@ -30,6 +30,7 @@ struct channel_key { struct session_info { struct lttng_ref ref; + uint64_t id; char *name; uid_t uid; gid_t gid; diff --git a/src/bin/lttng-sessiond/notification-thread.hpp b/src/bin/lttng-sessiond/notification-thread.hpp index 2f77189ad..2ff86dc06 100644 --- a/src/bin/lttng-sessiond/notification-thread.hpp +++ b/src/bin/lttng-sessiond/notification-thread.hpp @@ -157,13 +157,15 @@ struct notification_thread_handle { * The thread reacts to the following internal events: * 1) creation of a tracing channel, * 2) destruction of a tracing channel, - * 3) registration of a trigger, - * 4) unregistration of a trigger, - * 5) reception of a channel monitor sample from the consumer daemon, - * 6) Session rotation ongoing, - * 7) Session rotation completed, - * 8) registration of a tracer event source, - * 9) unregistration of a tracer event source, + * 3) creation of a tracing session, + * 4) destruction of a tracing session, + * 5) registration of a trigger, + * 6) unregistration of a trigger, + * 7) reception of a channel monitor sample from the consumer daemon, + * 8) Session rotation ongoing, + * 9) Session rotation completed, + * 10) registration of a tracer event source, + * 11) unregistration of a tracer event source, * * Events specific to notification-emitting triggers: * 9) connection of a notification client, diff --git a/src/bin/lttng-sessiond/rotation-thread.cpp b/src/bin/lttng-sessiond/rotation-thread.cpp index c1c6c50de..5efc24edd 100644 --- a/src/bin/lttng-sessiond/rotation-thread.cpp +++ b/src/bin/lttng-sessiond/rotation-thread.cpp @@ -487,9 +487,7 @@ int check_session_rotation_pending(struct ltt_session *session, location = session_get_trace_archive_location(session); ret = notification_thread_command_session_rotation_completed( notification_thread_handle, - session->name, - session->uid, - session->gid, + session->id, session->last_archived_chunk_id.value, location); lttng_trace_archive_location_put(location); diff --git a/src/bin/lttng-sessiond/ust-app.cpp b/src/bin/lttng-sessiond/ust-app.cpp index 1cfb08f91..c80658cbb 100644 --- a/src/bin/lttng-sessiond/ust-app.cpp +++ b/src/bin/lttng-sessiond/ust-app.cpp @@ -3461,11 +3461,7 @@ static int create_channel_per_uid(struct ust_app *app, /* Notify the notification subsystem of the channel's creation. */ notification_ret = notification_thread_command_add_channel( - the_notification_thread_handle, session->name, - lttng_credentials_get_uid( - &ua_sess->effective_credentials), - lttng_credentials_get_gid( - &ua_sess->effective_credentials), + the_notification_thread_handle, session->id, ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST, ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); if (notification_ret != LTTNG_OK) { @@ -3563,11 +3559,7 @@ static int create_channel_per_pid(struct ust_app *app, } cmd_ret = notification_thread_command_add_channel( - the_notification_thread_handle, session->name, - lttng_credentials_get_uid( - &ua_sess->effective_credentials), - lttng_credentials_get_gid( - &ua_sess->effective_credentials), + the_notification_thread_handle, session->id, ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST, ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf); if (cmd_ret != LTTNG_OK) { -- 2.34.1