sessiond: propagate the use of ltt_session::locked_ref
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 28 May 2024 03:21:18 +0000 (03:21 +0000)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 27 Jun 2024 15:09:21 +0000 (11:09 -0400)
The mix of managed and unmanaged ltt_session references makes their use
potentially confusing. Move to managed locked references for most of the client
request processing paths.

Change-Id: Iecb1668969ba07acfd84aa25127adb0addddbf10
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
37 files changed:
src/bin/lttng-sessiond/Makefile.am
src/bin/lttng-sessiond/action-executor.cpp
src/bin/lttng-sessiond/clear.cpp
src/bin/lttng-sessiond/clear.hpp
src/bin/lttng-sessiond/client.cpp
src/bin/lttng-sessiond/cmd.cpp
src/bin/lttng-sessiond/cmd.hpp
src/bin/lttng-sessiond/consumer-destination-type.hpp [new file with mode: 0644]
src/bin/lttng-sessiond/consumer-output.hpp [new file with mode: 0644]
src/bin/lttng-sessiond/consumer.cpp
src/bin/lttng-sessiond/consumer.hpp
src/bin/lttng-sessiond/dispatch.cpp
src/bin/lttng-sessiond/kernel-consumer.cpp
src/bin/lttng-sessiond/kernel.cpp
src/bin/lttng-sessiond/kernel.hpp
src/bin/lttng-sessiond/main.cpp
src/bin/lttng-sessiond/rotation-thread.cpp
src/bin/lttng-sessiond/save.cpp
src/bin/lttng-sessiond/session.cpp
src/bin/lttng-sessiond/session.hpp
src/bin/lttng-sessiond/snapshot-output.hpp [new file with mode: 0644]
src/bin/lttng-sessiond/snapshot.cpp
src/bin/lttng-sessiond/snapshot.hpp
src/bin/lttng-sessiond/timer.cpp
src/bin/lttng-sessiond/timer.hpp
src/bin/lttng-sessiond/ust-app.cpp
src/bin/lttng-sessiond/ust-app.hpp
src/bin/lttng-sessiond/utils.cpp
src/bin/lttng-sessiond/utils.hpp
src/bin/lttng/exception.cpp
src/bin/lttng/exception.hpp
src/common/Makefile.am
src/common/exception.cpp
src/common/make-unique-wrapper.hpp
src/common/meta-helpers.hpp [new file with mode: 0644]
src/common/reference.hpp [new file with mode: 0644]
tests/unit/test_session.cpp

index 15a9227100341e2836371cd9986847e5d2f73105..7dc4bbe4e65b148ad89e08e6951cd2e655639872 100644 (file)
@@ -62,7 +62,10 @@ liblttng_sessiond_common_la_SOURCES = utils.cpp utils.hpp \
                        clock-class.hpp clock-class.cpp \
                        event-class.hpp event-class.cpp \
                        stream-class.hpp stream-class.cpp \
-                       trace-class.hpp trace-class.cpp
+                       trace-class.hpp trace-class.cpp \
+                       consumer-destination-type.hpp \
+                       consumer-output.hpp \
+                       snapshot-output.hpp
 
 if HAVE_LIBLTTNG_UST_CTL
 liblttng_sessiond_common_la_SOURCES += trace-ust.cpp ust-registry.cpp ust-app.cpp \
index e3eded0faf3df57460131ae2604efe25c04ad863..aa8be1fcf037b34d162c6282c7c687a829b3ab17 100644 (file)
@@ -174,7 +174,7 @@ static const char *get_action_name(const struct lttng_action *action)
 
 /* Check if this trigger allowed to interect with a given session. */
 static bool is_trigger_allowed_for_session(const struct lttng_trigger *trigger,
-                                          struct ltt_session *session)
+                                          const ltt_session::locked_ref& session)
 {
        bool is_allowed = false;
        const struct lttng_credentials session_creds = {
@@ -311,18 +311,51 @@ static int action_executor_start_session_handler(struct action_executor *executo
        }
 
        /*
-        * Mind the order of the declaration of list_lock vs target_session:
+        * Mind the order of the declaration of list_lock vs session:
         * the session list lock must always be released _after_ the release of
         * a session's reference (the destruction of a ref/locked_ref) to ensure
         * since the reference's release may unpublish the session from the list of
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::locked_ref session;
-
        try {
-               session = ltt_session::find_locked_session(
+               const auto session = ltt_session::find_locked_session(
                        LTTNG_OPTIONAL_GET(item->context.session_id));
+
+               if (session->destroyed) {
+                       DBG("Session `%s` with id = %" PRIu64
+                           " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+                           session->name,
+                           session->id,
+                           get_action_name(action),
+                           get_trigger_name(work_item->trigger));
+                       return 0;
+               }
+
+               if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
+                       return 0;
+               }
+
+               cmd_ret = (lttng_error_code) cmd_start_trace(session);
+               switch (cmd_ret) {
+               case LTTNG_OK:
+                       DBG("Successfully started session `%s` on behalf of trigger `%s`",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               case LTTNG_ERR_TRACE_ALREADY_STARTED:
+                       DBG("Attempted to start session `%s` on behalf of trigger `%s` but it was already started",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               default:
+                       WARN("Failed to start session `%s` on behalf of trigger `%s`: %s",
+                            session_name,
+                            get_trigger_name(work_item->trigger),
+                            lttng_strerror(-cmd_ret));
+                       lttng_action_increase_execution_failure_count(action);
+                       break;
+               }
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to execution trigger action: {}, action=`{}`, trigger_name=`{}`, location='{}'",
                        ex.what(),
@@ -331,42 +364,6 @@ static int action_executor_start_session_handler(struct action_executor *executo
                        get_trigger_name(work_item->trigger),
                        ex.source_location);
                lttng_action_increase_execution_failure_count(action);
-               return 0;
-       }
-
-       if (session->destroyed) {
-               DBG("Session `%s` with id = %" PRIu64
-                   " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
-                   session->name,
-                   session->id,
-                   get_action_name(action),
-                   get_trigger_name(work_item->trigger));
-               return 0;
-       }
-
-       if (!is_trigger_allowed_for_session(work_item->trigger, session.get())) {
-               return 0;
-       }
-
-       cmd_ret = (lttng_error_code) cmd_start_trace(session.get());
-       switch (cmd_ret) {
-       case LTTNG_OK:
-               DBG("Successfully started session `%s` on behalf of trigger `%s`",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       case LTTNG_ERR_TRACE_ALREADY_STARTED:
-               DBG("Attempted to start session `%s` on behalf of trigger `%s` but it was already started",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       default:
-               WARN("Failed to start session `%s` on behalf of trigger `%s`: %s",
-                    session_name,
-                    get_trigger_name(work_item->trigger),
-                    lttng_strerror(-cmd_ret));
-               lttng_action_increase_execution_failure_count(action);
-               break;
        }
 
        return 0;
@@ -404,18 +401,52 @@ static int action_executor_stop_session_handler(struct action_executor *executor
        }
 
        /*
-        * Mind the order of the declaration of list_lock vs target_session:
+        * Mind the order of the declaration of list_lock vs session:
         * the session list lock must always be released _after_ the release of
         * a session's reference (the destruction of a ref/locked_ref) to ensure
         * since the reference's release may unpublish the session from the list of
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::locked_ref session;
 
        try {
-               session = ltt_session::find_locked_session(
+               const auto session = ltt_session::find_locked_session(
                        LTTNG_OPTIONAL_GET(item->context.session_id));
+
+               if (session->destroyed) {
+                       DBG("Session `%s` with id = %" PRIu64
+                           " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+                           session->name,
+                           session->id,
+                           get_action_name(action),
+                           get_trigger_name(work_item->trigger));
+                       return 0;
+               }
+
+               if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
+                       return 0;
+               }
+
+               cmd_ret = (lttng_error_code) cmd_stop_trace(session);
+               switch (cmd_ret) {
+               case LTTNG_OK:
+                       DBG("Successfully stopped session `%s` on behalf of trigger `%s`",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               case LTTNG_ERR_TRACE_ALREADY_STOPPED:
+                       DBG("Attempted to stop session `%s` on behalf of trigger `%s` but it was already stopped",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               default:
+                       WARN("Failed to stop session `%s` on behalf of trigger `%s`: %s",
+                            session_name,
+                            get_trigger_name(work_item->trigger),
+                            lttng_strerror(-cmd_ret));
+                       lttng_action_increase_execution_failure_count(action);
+                       break;
+               }
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to execution trigger action: {}, action=`{}`, trigger_name=`{}`, location='{}'",
                        ex.what(),
@@ -424,42 +455,6 @@ static int action_executor_stop_session_handler(struct action_executor *executor
                        get_trigger_name(work_item->trigger),
                        ex.source_location);
                lttng_action_increase_execution_failure_count(action);
-               return 0;
-       }
-
-       if (session->destroyed) {
-               DBG("Session `%s` with id = %" PRIu64
-                   " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
-                   session->name,
-                   session->id,
-                   get_action_name(action),
-                   get_trigger_name(work_item->trigger));
-               return 0;
-       }
-
-       if (!is_trigger_allowed_for_session(work_item->trigger, session.get())) {
-               return 0;
-       }
-
-       cmd_ret = (lttng_error_code) cmd_stop_trace(session.get());
-       switch (cmd_ret) {
-       case LTTNG_OK:
-               DBG("Successfully stopped session `%s` on behalf of trigger `%s`",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       case LTTNG_ERR_TRACE_ALREADY_STOPPED:
-               DBG("Attempted to stop session `%s` on behalf of trigger `%s` but it was already stopped",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       default:
-               WARN("Failed to stop session `%s` on behalf of trigger `%s`: %s",
-                    session_name,
-                    get_trigger_name(work_item->trigger),
-                    lttng_strerror(-cmd_ret));
-               lttng_action_increase_execution_failure_count(action);
-               break;
        }
 
        return 0;
@@ -497,18 +492,59 @@ static int action_executor_rotate_session_handler(struct action_executor *execut
        }
 
        /*
-        * Mind the order of the declaration of list_lock vs target_session:
+        * Mind the order of the declaration of list_lock vs session:
         * the session list lock must always be released _after_ the release of
         * a session's reference (the destruction of a ref/locked_ref) to ensure
         * since the reference's release may unpublish the session from the list of
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::locked_ref session;
-
        try {
-               session = ltt_session::find_locked_session(
+               const auto session = ltt_session::find_locked_session(
                        LTTNG_OPTIONAL_GET(item->context.session_id));
+
+               if (session->destroyed) {
+                       DBG("Session `%s` with id = %" PRIu64
+                           " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+                           session->name,
+                           session->id,
+                           get_action_name(action),
+                           get_trigger_name(work_item->trigger));
+                       return 0;
+               }
+
+               if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
+                       return 0;
+               }
+
+               cmd_ret = (lttng_error_code) cmd_rotate_session(
+                       session, nullptr, false, LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
+               switch (cmd_ret) {
+               case LTTNG_OK:
+                       DBG("Successfully started rotation of session `%s` on behalf of trigger `%s`",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               case LTTNG_ERR_ROTATION_PENDING:
+                       DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation is already ongoing",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       lttng_action_increase_execution_failure_count(action);
+                       break;
+               case LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
+               case LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
+                       DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation has already been completed since the last stop or clear",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               default:
+                       WARN("Failed to start a rotation of session `%s` on behalf of trigger `%s`: %s",
+                            session_name,
+                            get_trigger_name(work_item->trigger),
+                            lttng_strerror(-cmd_ret));
+                       lttng_action_increase_execution_failure_count(action);
+                       break;
+               }
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to execution trigger action: {}, action=`{}`, trigger_name=`{}`, location='{}'",
                        ex.what(),
@@ -517,50 +553,6 @@ static int action_executor_rotate_session_handler(struct action_executor *execut
                        get_trigger_name(work_item->trigger),
                        ex.source_location);
                lttng_action_increase_execution_failure_count(action);
-               return 0;
-       }
-
-       if (session->destroyed) {
-               DBG("Session `%s` with id = %" PRIu64
-                   " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
-                   session->name,
-                   session->id,
-                   get_action_name(action),
-                   get_trigger_name(work_item->trigger));
-               return 0;
-       }
-
-       if (!is_trigger_allowed_for_session(work_item->trigger, session.get())) {
-               return 0;
-       }
-
-       cmd_ret = (lttng_error_code) cmd_rotate_session(
-               session.get(), nullptr, false, LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
-       switch (cmd_ret) {
-       case LTTNG_OK:
-               DBG("Successfully started rotation of session `%s` on behalf of trigger `%s`",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       case LTTNG_ERR_ROTATION_PENDING:
-               DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation is already ongoing",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               lttng_action_increase_execution_failure_count(action);
-               break;
-       case LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
-       case LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
-               DBG("Attempted to start a rotation of session `%s` on behalf of trigger `%s` but a rotation has already been completed since the last stop or clear",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       default:
-               WARN("Failed to start a rotation of session `%s` on behalf of trigger `%s`: %s",
-                    session_name,
-                    get_trigger_name(work_item->trigger),
-                    lttng_strerror(-cmd_ret));
-               lttng_action_increase_execution_failure_count(action);
-               break;
        }
 
        return 0;
@@ -614,11 +606,40 @@ static int action_executor_snapshot_session_handler(struct action_executor *exec
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::locked_ref session;
-
        try {
-               session = ltt_session::find_locked_session(
+               const auto session = ltt_session::find_locked_session(
                        LTTNG_OPTIONAL_GET(item->context.session_id));
+
+               if (session->destroyed) {
+                       DBG("Session `%s` with id = %" PRIu64
+                           " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+                           session->name,
+                           session->id,
+                           get_action_name(action),
+                           get_trigger_name(work_item->trigger));
+                       return 0;
+               }
+
+               if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
+                       return 0;
+               }
+
+               cmd_ret = (lttng_error_code) cmd_snapshot_record(session, snapshot_output, 0);
+               switch (cmd_ret) {
+               case LTTNG_OK:
+                       DBG("Successfully recorded snapshot of session `%s` on behalf of trigger `%s`",
+                           session_name,
+                           get_trigger_name(work_item->trigger));
+                       break;
+               default:
+                       WARN("Failed to record snapshot of session `%s` on behalf of trigger `%s`: %s",
+                            session_name,
+                            get_trigger_name(work_item->trigger),
+                            lttng_strerror(-cmd_ret));
+                       lttng_action_increase_execution_failure_count(action);
+                       break;
+               }
+
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to execution trigger action: {}, action=`{}`, trigger_name=`{}`, location='{}'",
                        ex.what(),
@@ -627,37 +648,6 @@ static int action_executor_snapshot_session_handler(struct action_executor *exec
                        get_trigger_name(work_item->trigger),
                        ex.source_location);
                lttng_action_increase_execution_failure_count(action);
-               return 0;
-       }
-
-       if (session->destroyed) {
-               DBG("Session `%s` with id = %" PRIu64
-                   " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
-                   session->name,
-                   session->id,
-                   get_action_name(action),
-                   get_trigger_name(work_item->trigger));
-               return 0;
-       }
-
-       if (!is_trigger_allowed_for_session(work_item->trigger, session.get())) {
-               return 0;
-       }
-
-       cmd_ret = (lttng_error_code) cmd_snapshot_record(session.get(), snapshot_output, 0);
-       switch (cmd_ret) {
-       case LTTNG_OK:
-               DBG("Successfully recorded snapshot of session `%s` on behalf of trigger `%s`",
-                   session_name,
-                   get_trigger_name(work_item->trigger));
-               break;
-       default:
-               WARN("Failed to record snapshot of session `%s` on behalf of trigger `%s`: %s",
-                    session_name,
-                    get_trigger_name(work_item->trigger),
-                    lttng_strerror(-cmd_ret));
-               lttng_action_increase_execution_failure_count(action);
-               break;
        }
 
        return 0;
index ced9925943b83d543676ce45d191806f6d8472f2..b08cc8791ac2bf2a28297fae667389f0e833c82a 100644 (file)
@@ -26,7 +26,7 @@ struct cmd_clear_session_reply_context {
 };
 } /* namespace */
 
-static void cmd_clear_session_reply(const struct ltt_session *session, void *_reply_context)
+static void cmd_clear_session_reply(const ltt_session::locked_ref& session, void *_reply_context)
 {
        int ret;
        ssize_t comm_ret;
@@ -53,7 +53,7 @@ static void cmd_clear_session_reply(const struct ltt_session *session, void *_re
        free(_reply_context);
 }
 
-int cmd_clear_session(struct ltt_session *session, int *sock_fd)
+int cmd_clear_session(const ltt_session::locked_ref& session, int *sock_fd)
 {
        int ret = LTTNG_OK;
        struct cmd_clear_session_reply_context *reply_context = nullptr;
index aca20d35a14c68a366ee73b923a32b283f3040af..b3618bfde7f8438080fbc0e5170fa741abdcdc29 100644 (file)
@@ -10,6 +10,6 @@
 
 #include "session.hpp"
 
-int cmd_clear_session(struct ltt_session *session, int *sock_fd);
+int cmd_clear_session(const ltt_session::locked_ref& session, int *sock_fd);
 
 #endif /* CLEAT_H */
index fa368a90d420b475dcb3ba1a6bcb1a73808d370e..b4958e3743037393c19717f5609397e7a18486f5 100644 (file)
@@ -421,13 +421,12 @@ error:
  * function also applies the right modification on a per domain basis for the
  * trace files destination directory.
  */
-static int copy_session_consumer(int domain, struct ltt_session *session)
+static int copy_session_consumer(int domain, const ltt_session::locked_ref& session)
 {
        int ret;
        const char *dir_name;
        struct consumer_output *consumer;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(session->consumer);
 
        switch (domain) {
@@ -481,12 +480,12 @@ error:
 /*
  * Create an UST session and add it to the session ust list.
  */
-static int create_ust_session(struct ltt_session *session, const struct lttng_domain *domain)
+static int create_ust_session(const ltt_session::locked_ref& session,
+                             const struct lttng_domain *domain)
 {
        int ret;
        struct ltt_ust_session *lus = nullptr;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(domain);
        LTTNG_ASSERT(session->consumer);
 
@@ -540,7 +539,7 @@ error:
 /*
  * Create a kernel tracer session then create the default channel.
  */
-static int create_kernel_session(struct ltt_session *session)
+static int create_kernel_session(const ltt_session::locked_ref& session)
 {
        int ret;
 
@@ -582,22 +581,23 @@ error_create:
 static unsigned int lttng_sessions_count(uid_t uid, gid_t gid __attribute__((unused)))
 {
        unsigned int i = 0;
-       struct ltt_session *session;
+       struct ltt_session *raw_session_ptr;
        const struct ltt_session_list *session_list = session_get_list();
 
        DBG("Counting number of available session for UID %d", uid);
-       cds_list_for_each_entry (session, &session_list->head, list) {
-               if (!session_get(session)) {
-                       continue;
-               }
-               session_lock(session);
+       cds_list_for_each_entry (raw_session_ptr, &session_list->head, list) {
+               auto session = [raw_session_ptr]() {
+                       session_get(raw_session_ptr);
+                       raw_session_ptr->lock();
+                       return ltt_session::locked_ref(*raw_session_ptr);
+               }();
+
                /* Only count the sessions the user can control. */
                if (session_access_ok(session, uid) && !session->destroyed) {
                        i++;
                }
-               session_unlock(session);
-               session_put(session);
        }
+
        return i;
 }
 
@@ -1111,10 +1111,10 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
        std::unique_lock<std::mutex> list_lock;
        /*
         * A locked_ref is typically "never null" (hence its name). However, due to the
-        * structure of this function, target_session remains null for commands that don't
+        * structure of this function, target_session remains unset for commands that don't
         * have a target session.
         */
-       ltt_session::locked_ref target_session;
+       nonstd::optional<ltt_session::locked_ref> target_session;
 
        /* Commands that DO NOT need a session. */
        switch (cmd_ctx->lsm.cmd_type) {
@@ -1146,8 +1146,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
                 */
                list_lock = lttng::sessiond::lock_session_list();
                try {
-                       target_session =
-                               ltt_session::find_locked_session(cmd_ctx->lsm.session.name);
+                       target_session.emplace(
+                               ltt_session::find_locked_session(cmd_ctx->lsm.session.name));
                } catch (...) {
                        std::throw_with_nested(lttng::ctl::error(
                                fmt::format(
@@ -1173,7 +1173,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
        case LTTCOMM_SESSIOND_COMMAND_DISABLE_EVENT:
                switch (cmd_ctx->lsm.domain.type) {
                case LTTNG_DOMAIN_KERNEL:
-                       if (!target_session->kernel_session) {
+                       if (!(*target_session)->kernel_session) {
                                return LTTNG_ERR_NO_CHANNEL;
                        }
                        break;
@@ -1181,7 +1181,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
                case LTTNG_DOMAIN_LOG4J:
                case LTTNG_DOMAIN_PYTHON:
                case LTTNG_DOMAIN_UST:
-                       if (!target_session->ust_session) {
+                       if (!(*target_session)->ust_session) {
                                return LTTNG_ERR_NO_CHANNEL;
                                goto error;
                        }
@@ -1225,8 +1225,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
 
                /* Need a session for kernel command */
                if (need_tracing_session) {
-                       if (target_session->kernel_session == nullptr) {
-                               ret = create_kernel_session(target_session.get());
+                       if ((*target_session)->kernel_session == nullptr) {
+                               ret = create_kernel_session(*target_session);
                                if (ret != LTTNG_OK) {
                                        ret = LTTNG_ERR_KERN_SESS_FAIL;
                                        goto error;
@@ -1253,7 +1253,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
                         * the consumer output of the session if exist.
                         */
                        ret = consumer_create_socket(&the_kconsumer_data,
-                                                    target_session->kernel_session->consumer);
+                                                    (*target_session)->kernel_session->consumer);
                        if (ret < 0) {
                                goto error;
                        }
@@ -1283,9 +1283,9 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
 
                if (need_tracing_session) {
                        /* Create UST session if none exist. */
-                       if (target_session->ust_session == nullptr) {
+                       if ((*target_session)->ust_session == nullptr) {
                                lttng_domain domain = cmd_ctx->lsm.domain;
-                               ret = create_ust_session(target_session.get(), &domain);
+                               ret = create_ust_session(*target_session, &domain);
                                if (ret != LTTNG_OK) {
                                        goto error;
                                }
@@ -1317,7 +1317,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
                         * since it was set above and can ONLY be set in this thread.
                         */
                        ret = consumer_create_socket(&the_ustconsumer64_data,
-                                                    target_session->ust_session->consumer);
+                                                    (*target_session)->ust_session->consumer);
                        if (ret < 0) {
                                goto error;
                        }
@@ -1347,7 +1347,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, int *sock_
                         * since it was set above and can ONLY be set in this thread.
                         */
                        ret = consumer_create_socket(&the_ustconsumer32_data,
-                                                    target_session->ust_session->consumer);
+                                                    (*target_session)->ust_session->consumer);
                        if (ret < 0) {
                                goto error;
                        }
@@ -1391,9 +1391,8 @@ skip_domain:
         * The root user can interact with all sessions.
         */
        if (need_tracing_session) {
-               if (!session_access_ok(target_session.get(),
-                                      LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds)) ||
-                   target_session->destroyed) {
+               if (!session_access_ok(*target_session, LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds)) ||
+                   (*target_session)->destroyed) {
                        ret = LTTNG_ERR_EPERM;
                        goto error;
                }
@@ -1408,7 +1407,7 @@ skip_domain:
                 * Setup relayd if not done yet. If the relayd information was already
                 * sent to the consumer, this call will gracefully return.
                 */
-               ret = cmd_setup_relayd(target_session.get());
+               ret = cmd_setup_relayd(*target_session);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1428,20 +1427,20 @@ skip_domain:
                }
 
                ret = cmd_add_context(
-                       cmd_ctx, target_session, event_context, the_kernel_poll_pipe[1]);
+                       cmd_ctx, *target_session, event_context, the_kernel_poll_pipe[1]);
                lttng_event_context_destroy(event_context);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_DISABLE_CHANNEL:
        {
-               ret = cmd_disable_channel(target_session.get(),
+               ret = cmd_disable_channel(*target_session,
                                          cmd_ctx->lsm.domain.type,
                                          cmd_ctx->lsm.u.disable.channel_name);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_ENABLE_CHANNEL:
        {
-               ret = cmd_enable_channel(cmd_ctx, target_session, *sock, the_kernel_poll_pipe[1]);
+               ret = cmd_enable_channel(cmd_ctx, *target_session, *sock, the_kernel_poll_pipe[1]);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_ADD_INCLUDE_VALUE:
@@ -1538,10 +1537,10 @@ skip_domain:
 
                if (add_value) {
                        ret = cmd_process_attr_tracker_inclusion_set_add_value(
-                               target_session.get(), domain_type, process_attr, value);
+                               *target_session, domain_type, process_attr, value);
                } else {
                        ret = cmd_process_attr_tracker_inclusion_set_remove_value(
-                               target_session.get(), domain_type, process_attr, value);
+                               *target_session, domain_type, process_attr, value);
                }
                process_attr_value_destroy(value);
        error_add_remove_tracker_value:
@@ -1558,7 +1557,7 @@ skip_domain:
                                .process_attr_tracker_get_tracking_policy.process_attr;
 
                ret = cmd_process_attr_tracker_get_tracking_policy(
-                       target_session.get(), domain_type, process_attr, &tracking_policy);
+                       *target_session, domain_type, process_attr, &tracking_policy);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1581,7 +1580,7 @@ skip_domain:
                                .process_attr_tracker_set_tracking_policy.process_attr;
 
                ret = cmd_process_attr_tracker_set_tracking_policy(
-                       target_session.get(), domain_type, process_attr, tracking_policy);
+                       *target_session, domain_type, process_attr, tracking_policy);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1598,7 +1597,7 @@ skip_domain:
                                cmd_ctx->lsm.u.process_attr_tracker_get_inclusion_set.process_attr;
 
                ret = cmd_process_attr_tracker_get_inclusion_set(
-                       target_session.get(), domain_type, process_attr, &values);
+                       *target_session, domain_type, process_attr, &values);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1643,14 +1642,14 @@ skip_domain:
                 */
                ret = cmd_ctx->lsm.cmd_type == LTTCOMM_SESSIOND_COMMAND_ENABLE_EVENT ?
                        cmd_enable_event(cmd_ctx,
-                                        target_session,
+                                        *target_session,
                                         event,
                                         filter_expression,
                                         exclusions,
                                         bytecode,
                                         the_kernel_poll_pipe[1]) :
                        cmd_disable_event(cmd_ctx,
-                                         target_session,
+                                         *target_session,
                                          event,
                                          filter_expression,
                                          bytecode,
@@ -1764,7 +1763,7 @@ skip_domain:
                        goto error;
                }
 
-               ret = cmd_set_consumer_uri(target_session.get(), nb_uri, uris);
+               ret = cmd_set_consumer_uri(*target_session, nb_uri, uris);
                free(uris);
                if (ret != LTTNG_OK) {
                        goto error;
@@ -1779,24 +1778,24 @@ skip_domain:
                 * enabled time or size-based rotations, we have to make sure
                 * the kernel tracer supports it.
                 */
-               if (!target_session->has_been_started && target_session->kernel_session &&
-                   (target_session->rotate_timer_period || target_session->rotate_size) &&
+               if (!(*target_session)->has_been_started && (*target_session)->kernel_session &&
+                   ((*target_session)->rotate_timer_period || (*target_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(target_session.get());
+               ret = cmd_start_trace(*target_session);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_STOP_TRACE:
        {
-               ret = cmd_stop_trace(target_session.get());
+               ret = cmd_stop_trace(*target_session);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_DESTROY_SESSION:
        {
-               ret = cmd_destroy_session(target_session.get(), sock);
+               ret = cmd_destroy_session(*target_session, sock);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_LIST_DOMAINS:
@@ -1804,7 +1803,7 @@ skip_domain:
                ssize_t nb_dom;
                struct lttng_domain *domains = nullptr;
 
-               nb_dom = cmd_list_domains(target_session.get(), &domains);
+               nb_dom = cmd_list_domains(*target_session, &domains);
                if (nb_dom < 0) {
                        /* Return value is a negative lttng_error_code. */
                        ret = -nb_dom;
@@ -1830,7 +1829,7 @@ skip_domain:
                original_payload_size = cmd_ctx->reply_payload.buffer.size;
 
                ret_code = cmd_list_channels(
-                       cmd_ctx->lsm.domain.type, target_session.get(), &cmd_ctx->reply_payload);
+                       cmd_ctx->lsm.domain.type, *target_session, &cmd_ctx->reply_payload);
                if (ret_code != LTTNG_OK) {
                        ret = (int) ret_code;
                        goto error;
@@ -1855,7 +1854,7 @@ skip_domain:
                original_payload_size = cmd_ctx->reply_payload.buffer.size;
 
                ret_code = cmd_list_events(cmd_ctx->lsm.domain.type,
-                                          target_session.get(),
+                                          *target_session,
                                           cmd_ctx->lsm.u.list.channel_name,
                                           &cmd_ctx->reply_payload);
                if (ret_code != LTTNG_OK) {
@@ -1915,10 +1914,8 @@ skip_domain:
                        goto error;
                }
 
-               ret = cmd_register_consumer(target_session.get(),
-                                           cmd_ctx->lsm.domain.type,
-                                           cmd_ctx->lsm.u.reg.path,
-                                           cdata);
+               ret = cmd_register_consumer(
+                       *target_session, cmd_ctx->lsm.domain.type, cmd_ctx->lsm.u.reg.path, cdata);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_KERNEL_TRACER_STATUS:
@@ -1942,7 +1939,7 @@ skip_domain:
                int pending_ret;
                uint8_t pending_ret_byte;
 
-               pending_ret = cmd_data_pending(target_session.get());
+               pending_ret = cmd_data_pending(*target_session);
 
                /*
                 * FIXME
@@ -1980,7 +1977,7 @@ skip_domain:
                struct lttcomm_lttng_output_id reply;
                lttng_snapshot_output output = cmd_ctx->lsm.u.snapshot_output.output;
 
-               ret = cmd_snapshot_add_output(target_session.get(), &output, &snapshot_id);
+               ret = cmd_snapshot_add_output(*target_session, &output, &snapshot_id);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -1995,7 +1992,7 @@ skip_domain:
        case LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_DEL_OUTPUT:
        {
                lttng_snapshot_output output = cmd_ctx->lsm.u.snapshot_output.output;
-               ret = cmd_snapshot_del_output(target_session.get(), &output);
+               ret = cmd_snapshot_del_output(*target_session, &output);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_LIST_OUTPUT:
@@ -2003,7 +2000,7 @@ skip_domain:
                ssize_t nb_output;
                struct lttng_snapshot_output *outputs = nullptr;
 
-               nb_output = cmd_snapshot_list_outputs(target_session.get(), &outputs);
+               nb_output = cmd_snapshot_list_outputs(*target_session, &outputs);
                if (nb_output < 0) {
                        ret = -nb_output;
                        goto error;
@@ -2020,10 +2017,10 @@ skip_domain:
        case LTTCOMM_SESSIOND_COMMAND_SNAPSHOT_RECORD:
        {
                lttng_snapshot_output output = cmd_ctx->lsm.u.snapshot_record.output;
-               ret = cmd_snapshot_record(target_session.get(), &output, 0); // RFC: set to zero
-                                                                            // since it's ignored
-                                                                            // by
-                                                                            // cmd_snapshot_record
+               ret = cmd_snapshot_record(*target_session, &output, 0); // RFC: set to zero
+                                                                       // since it's ignored
+                                                                       // by
+                                                                       // cmd_snapshot_record
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_CREATE_SESSION_EXT:
@@ -2062,18 +2059,18 @@ skip_domain:
        }
        case LTTCOMM_SESSIOND_COMMAND_SET_SESSION_SHM_PATH:
        {
-               ret = cmd_set_session_shm_path(target_session.get(),
+               ret = cmd_set_session_shm_path(*target_session,
                                               cmd_ctx->lsm.u.set_shm_path.shm_path);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_REGENERATE_METADATA:
        {
-               ret = cmd_regenerate_metadata(target_session.get());
+               ret = cmd_regenerate_metadata(*target_session);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_REGENERATE_STATEDUMP:
        {
-               ret = cmd_regenerate_statedump(target_session.get());
+               ret = cmd_regenerate_statedump(*target_session);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_REGISTER_TRIGGER:
@@ -2132,16 +2129,16 @@ skip_domain:
        {
                struct lttng_rotate_session_return rotate_return;
 
-               DBG("Client rotate session \"%s\"", target_session->name);
+               DBG("Client rotate session \"%s\"", (*target_session)->name);
 
                memset(&rotate_return, 0, sizeof(rotate_return));
-               if (target_session->kernel_session && !check_rotate_compatible()) {
+               if ((*target_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(target_session.get(),
+               ret = cmd_rotate_session(*target_session,
                                         &rotate_return,
                                         false,
                                         LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
@@ -2160,7 +2157,7 @@ skip_domain:
                struct lttng_rotation_get_info_return get_info_return;
 
                memset(&get_info_return, 0, sizeof(get_info_return));
-               ret = cmd_rotate_get_info(target_session.get(),
+               ret = cmd_rotate_get_info(*target_session,
                                          &get_info_return,
                                          cmd_ctx->lsm.u.get_rotation_info.rotation_id);
                if (ret < 0) {
@@ -2179,7 +2176,7 @@ skip_domain:
                enum lttng_rotation_schedule_type schedule_type;
                uint64_t value;
 
-               if (target_session->kernel_session && !check_rotate_compatible()) {
+               if ((*target_session)->kernel_session && !check_rotate_compatible()) {
                        DBG("Kernel tracer version does not support session rotations");
                        ret = LTTNG_ERR_ROTATION_WRONG_VERSION;
                        goto error;
@@ -2191,7 +2188,7 @@ skip_domain:
                value = cmd_ctx->lsm.u.rotation_set_schedule.value;
 
                ret = cmd_rotation_set_schedule(
-                       target_session.get(), set_schedule, schedule_type, value);
+                       *target_session, set_schedule, schedule_type, value);
                if (ret != LTTNG_OK) {
                        goto error;
                }
@@ -2202,10 +2199,10 @@ skip_domain:
        {
                lttng_session_list_schedules_return schedules;
 
-               schedules.periodic.set = !!target_session->rotate_timer_period;
-               schedules.periodic.value = target_session->rotate_timer_period;
-               schedules.size.set = !!target_session->rotate_size;
-               schedules.size.value = target_session->rotate_size;
+               schedules.periodic.set = !!(*target_session)->rotate_timer_period;
+               schedules.periodic.value = (*target_session)->rotate_timer_period;
+               schedules.size.set = !!(*target_session)->rotate_size;
+               schedules.size.value = (*target_session)->rotate_size;
 
                setup_lttng_msg_no_cmd_header(cmd_ctx, &schedules, sizeof(schedules));
 
@@ -2214,7 +2211,7 @@ skip_domain:
        }
        case LTTCOMM_SESSIOND_COMMAND_CLEAR_SESSION:
        {
-               ret = cmd_clear_session(target_session.get(), sock);
+               ret = cmd_clear_session(*target_session, sock);
                break;
        }
        case LTTCOMM_SESSIOND_COMMAND_LIST_TRIGGERS:
index 3f79ee2bb47fe35b15fbf115b5e927df252b067e..ee96fc8285913b2fdf5cc75015478548d0b953b0 100644 (file)
@@ -12,6 +12,7 @@
 #include "buffer-registry.hpp"
 #include "channel.hpp"
 #include "cmd.hpp"
+#include "consumer-output.hpp"
 #include "consumer.hpp"
 #include "event-notifier-error-accounting.hpp"
 #include "event.hpp"
@@ -133,13 +134,13 @@ static enum lttng_error_code cmd_enable_channel_internal(ltt_session::locked_ref
  * Create a session path used by list_lttng_sessions for the case that the
  * session consumer is on the network.
  */
-static int build_network_session_path(char *dst, size_t size, struct ltt_session *session)
+static int
+build_network_session_path(char *dst, size_t size, const ltt_session::locked_ref& session)
 {
        int ret, kdata_port, udata_port;
        struct lttng_uri *kuri = nullptr, *uuri = nullptr, *uri = nullptr;
        char tmp_uurl[PATH_MAX], tmp_urls[PATH_MAX];
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(dst);
 
        memset(tmp_urls, 0, sizeof(tmp_urls));
@@ -215,7 +216,7 @@ error:
  * Get run-time attributes if the session has been started (discarded events,
  * lost packets).
  */
-static int get_kernel_runtime_stats(struct ltt_session *session,
+static int get_kernel_runtime_stats(const ltt_session::locked_ref& session,
                                    struct ltt_kernel_channel *kchan,
                                    uint64_t *discarded_events,
                                    uint64_t *lost_packets)
@@ -249,7 +250,7 @@ end:
  * Get run-time attributes if the session has been started (discarded events,
  * lost packets).
  */
-static int get_ust_runtime_stats(struct ltt_session *session,
+static int get_ust_runtime_stats(const ltt_session::locked_ref& session,
                                 struct ltt_ust_channel *uchan,
                                 uint64_t *discarded_events,
                                 uint64_t *lost_packets)
@@ -645,7 +646,7 @@ end:
  * Add URI so the consumer output object. Set the correct path depending on the
  * domain adding the default trace directory.
  */
-static enum lttng_error_code add_uri_to_consumer(const struct ltt_session *session,
+static enum lttng_error_code add_uri_to_consumer(const ltt_session::locked_ref& session,
                                                 struct consumer_output *consumer,
                                                 struct lttng_uri *uri,
                                                 enum lttng_domain_type domain)
@@ -1013,7 +1014,7 @@ error:
  * the relayd and send them to the right domain consumer. Consumer type MUST be
  * network.
  */
-int cmd_setup_relayd(struct ltt_session *session)
+int cmd_setup_relayd(const ltt_session::locked_ref& session)
 {
        int ret = LTTNG_OK;
        struct ltt_ust_session *usess;
@@ -1022,8 +1023,6 @@ int cmd_setup_relayd(struct ltt_session *session)
        struct lttng_ht_iter iter;
        LTTNG_OPTIONAL(uint64_t) current_chunk_id = {};
 
-       LTTNG_ASSERT(session);
-
        usess = session->ust_session;
        ksess = session->kernel_session;
 
@@ -1224,7 +1223,7 @@ error:
 /*
  * Command LTTNG_DISABLE_CHANNEL processed by the client thread.
  */
-int cmd_disable_channel(struct ltt_session *session,
+int cmd_disable_channel(const ltt_session::locked_ref& session,
                        enum lttng_domain_type domain,
                        char *channel_name)
 {
@@ -1332,7 +1331,7 @@ static enum lttng_error_code cmd_enable_channel_internal(ltt_session::locked_ref
                                                         int wpipe)
 {
        enum lttng_error_code ret_code;
-       struct ltt_ust_session *usess = session.get()->ust_session;
+       struct ltt_ust_session *usess = session->ust_session;
        struct lttng_ht *chan_ht;
        size_t len;
        struct lttng_channel *attr = nullptr;
@@ -1363,8 +1362,8 @@ static enum lttng_error_code cmd_enable_channel_internal(ltt_session::locked_ref
         * live timer does the same thing but sends also synchronisation
         * beacons for inactive streams.
         */
-       if (session.get()->live_timer > 0) {
-               attr->attr.live_timer_interval = session.get()->live_timer;
+       if (session->live_timer > 0) {
+               attr->attr.live_timer_interval = session->live_timer;
                attr->attr.switch_timer_interval = 0;
        }
 
@@ -1378,7 +1377,7 @@ static enum lttng_error_code cmd_enable_channel_internal(ltt_session::locked_ref
                             "Setting the monitor interval timer to 0 "
                             "(disabled) for channel '%s' of session '%s'",
                             attr->name,
-                            session.get()->name);
+                            session->name);
                        lttng_channel_set_monitor_timer_interval(attr, 0);
                }
                break;
@@ -1509,7 +1508,7 @@ end:
 }
 
 enum lttng_error_code
-cmd_process_attr_tracker_get_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_get_tracking_policy(const ltt_session::locked_ref& session,
                                             enum lttng_domain_type domain,
                                             enum lttng_process_attr process_attr,
                                             enum lttng_tracking_policy *policy)
@@ -1546,7 +1545,7 @@ end:
 }
 
 enum lttng_error_code
-cmd_process_attr_tracker_set_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_set_tracking_policy(const ltt_session::locked_ref& session,
                                             enum lttng_domain_type domain,
                                             enum lttng_process_attr process_attr,
                                             enum lttng_tracking_policy policy)
@@ -1589,7 +1588,7 @@ end:
 }
 
 enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_add_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_add_value(const ltt_session::locked_ref& session,
                                                 enum lttng_domain_type domain,
                                                 enum lttng_process_attr process_attr,
                                                 const struct process_attr_value *value)
@@ -1622,7 +1621,7 @@ end:
 }
 
 enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_remove_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_remove_value(const ltt_session::locked_ref& session,
                                                    enum lttng_domain_type domain,
                                                    enum lttng_process_attr process_attr,
                                                    const struct process_attr_value *value)
@@ -1655,7 +1654,7 @@ end:
 }
 
 enum lttng_error_code
-cmd_process_attr_tracker_get_inclusion_set(struct ltt_session *session,
+cmd_process_attr_tracker_get_inclusion_set(const ltt_session::locked_ref& session,
                                           enum lttng_domain_type domain,
                                           enum lttng_process_attr process_attr,
                                           struct lttng_process_attr_values **values)
@@ -1720,7 +1719,7 @@ int cmd_disable_event(struct command_ctx *cmd_ctx,
                      struct lttng_event_exclusion *exclusion)
 {
        int ret;
-       ltt_session& session = *locked_session.get();
+       const ltt_session& session = *locked_session;
        const char *event_name;
        const char *channel_name = cmd_ctx->lsm.u.disable.channel_name;
        const enum lttng_domain_type domain = cmd_ctx->lsm.domain.type;
@@ -1912,7 +1911,7 @@ int cmd_add_context(struct command_ctx *cmd_ctx,
 {
        int ret, chan_kern_created = 0, chan_ust_created = 0;
        const enum lttng_domain_type domain = cmd_ctx->lsm.domain.type;
-       const struct ltt_session& session = *locked_session.get();
+       const struct ltt_session& session = *locked_session;
        const char *channel_name = cmd_ctx->lsm.u.context.channel_name;
 
        /*
@@ -2075,7 +2074,7 @@ static int _cmd_enable_event(ltt_session::locked_ref& locked_session,
 {
        int ret = 0, channel_created = 0;
        struct lttng_channel *attr = nullptr;
-       ltt_session& session = *locked_session.get();
+       ltt_session& session = *locked_session;
 
        LTTNG_ASSERT(event);
        LTTNG_ASSERT(channel_name);
@@ -2716,10 +2715,8 @@ end:
 
 /*
  * Command LTTNG_START_TRACE processed by the client thread.
- *
- * Called with session mutex held.
  */
-int cmd_start_trace(struct ltt_session *session)
+int cmd_start_trace(const ltt_session::locked_ref& session)
 {
        enum lttng_error_code ret;
        unsigned long nb_chan = 0;
@@ -2728,8 +2725,6 @@ int cmd_start_trace(struct ltt_session *session)
        const bool session_rotated_after_last_stop = session->rotated_after_last_stop;
        const bool session_cleared_after_last_stop = session->cleared_after_last_stop;
 
-       LTTNG_ASSERT(session);
-
        /* Ease our life a bit ;) */
        ksession = session->kernel_session;
        usess = session->ust_session;
@@ -2880,14 +2875,12 @@ end:
 /*
  * Command LTTNG_STOP_TRACE processed by the client thread.
  */
-int cmd_stop_trace(struct ltt_session *session)
+int cmd_stop_trace(const ltt_session::locked_ref& session)
 {
        int ret;
        struct ltt_kernel_session *ksession;
        struct ltt_ust_session *usess;
 
-       LTTNG_ASSERT(session);
-
        DBG("Begin stop session \"%s\" (id %" PRIu64 ")", session->name, session->id);
        /* Short cut */
        ksession = session->kernel_session;
@@ -2925,8 +2918,9 @@ error:
  * Set the base_path of the session only if subdir of a control uris is set.
  * Return LTTNG_OK on success, otherwise LTTNG_ERR_*.
  */
-static int
-set_session_base_path_from_uris(struct ltt_session *session, size_t nb_uri, struct lttng_uri *uris)
+static int set_session_base_path_from_uris(const ltt_session::locked_ref& session,
+                                          size_t nb_uri,
+                                          struct lttng_uri *uris)
 {
        int ret;
        size_t i;
@@ -2963,13 +2957,14 @@ error:
 /*
  * Command LTTNG_SET_CONSUMER_URI processed by the client thread.
  */
-int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, struct lttng_uri *uris)
+int cmd_set_consumer_uri(const ltt_session::locked_ref& session,
+                        size_t nb_uri,
+                        struct lttng_uri *uris)
 {
        int ret, i;
        struct ltt_kernel_session *ksess = session->kernel_session;
        struct ltt_ust_session *usess = session->ust_session;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(uris);
        LTTNG_ASSERT(nb_uri > 0);
 
@@ -3044,7 +3039,7 @@ error:
 }
 
 static enum lttng_error_code
-set_session_output_from_descriptor(struct ltt_session *session,
+set_session_output_from_descriptor(const ltt_session::locked_ref& session,
                                   const struct lttng_session_descriptor *descriptor)
 {
        int ret;
@@ -3161,8 +3156,13 @@ cmd_create_session_from_descriptor(struct lttng_session_descriptor *descriptor,
 
        /* 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))) {
+               [new_session]() {
+                       session_get(new_session);
+                       new_session->lock();
+                       return ltt_session::locked_ref(*new_session);
+               }(),
+               [](const ltt_session::locked_ref& session,
+                  void *user_data __attribute__((unused))) {
                        (void) notification_thread_command_remove_session(
                                the_notification_thread_handle, session->id);
                },
@@ -3212,7 +3212,13 @@ cmd_create_session_from_descriptor(struct lttng_session_descriptor *descriptor,
                break;
        }
 
-       ret_code = set_session_output_from_descriptor(new_session, descriptor);
+       ret_code = set_session_output_from_descriptor(
+               [new_session]() {
+                       session_get(new_session);
+                       new_session->lock();
+                       return ltt_session::locked_ref(*new_session);
+               }(),
+               descriptor);
        if (ret_code != LTTNG_OK) {
                goto end;
        }
@@ -3315,7 +3321,7 @@ error:
        return ret_code;
 }
 
-static void cmd_destroy_session_reply(const struct ltt_session *session, void *_reply_context)
+static void cmd_destroy_session_reply(const ltt_session::locked_ref& session, void *_reply_context)
 {
        int ret;
        ssize_t comm_ret;
@@ -3400,7 +3406,7 @@ error:
  *
  * Called with session lock held.
  */
-int cmd_destroy_session(struct ltt_session *session, int *sock_fd)
+int cmd_destroy_session(const ltt_session::locked_ref& session, int *sock_fd)
 {
        int ret;
        enum lttng_error_code destruction_last_error = LTTNG_OK;
@@ -3416,9 +3422,6 @@ int cmd_destroy_session(struct ltt_session *session, int *sock_fd)
                reply_context->reply_sock_fd = *sock_fd;
        }
 
-       /* Safety net */
-       LTTNG_ASSERT(session);
-
        DBG("Begin destroy session %s (id %" PRIu64 ")", session->name, session->id);
        if (session->active) {
                DBG("Session \"%s\" is active, attempting to stop it before destroying it",
@@ -3556,7 +3559,7 @@ int cmd_destroy_session(struct ltt_session *session, int *sock_fd)
         * still holds a reference to the session, thus delaying its destruction
         * _at least_ up to the point when that reference is released.
         */
-       session_destroy(session);
+       session_destroy(&session.get());
        if (reply_context) {
                reply_context->destruction_status = destruction_last_error;
                ret = session_add_destroy_notifier(
@@ -3576,7 +3579,7 @@ end:
 /*
  * Command LTTNG_REGISTER_CONSUMER processed by the client thread.
  */
-int cmd_register_consumer(struct ltt_session *session,
+int cmd_register_consumer(const ltt_session::locked_ref& session,
                          enum lttng_domain_type domain,
                          const char *sock_path,
                          struct consumer_data *cdata)
@@ -3584,7 +3587,6 @@ int cmd_register_consumer(struct ltt_session *session,
        int ret, sock;
        struct consumer_socket *socket = nullptr;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(cdata);
        LTTNG_ASSERT(sock_path);
 
@@ -3656,7 +3658,7 @@ error:
 /*
  * Command LTTNG_LIST_DOMAINS processed by the client thread.
  */
-ssize_t cmd_list_domains(struct ltt_session *session, struct lttng_domain **domains)
+ssize_t cmd_list_domains(const ltt_session::locked_ref& session, struct lttng_domain **domains)
 {
        int ret, index = 0;
        ssize_t nb_dom = 0;
@@ -3732,7 +3734,7 @@ error:
  * Command LTTNG_LIST_CHANNELS processed by the client thread.
  */
 enum lttng_error_code cmd_list_channels(enum lttng_domain_type domain,
-                                       struct ltt_session *session,
+                                       const ltt_session::locked_ref& session,
                                        struct lttng_payload *payload)
 {
        int ret = 0;
@@ -3741,8 +3743,7 @@ enum lttng_error_code cmd_list_channels(enum lttng_domain_type domain,
        size_t cmd_header_offset;
        enum lttng_error_code ret_code;
 
-       assert(session);
-       assert(payload);
+       LTTNG_ASSERT(payload);
 
        DBG("Listing channels for session %s", session->name);
 
@@ -3872,7 +3873,7 @@ end:
  * Command LTTNG_LIST_EVENTS processed by the client thread.
  */
 enum lttng_error_code cmd_list_events(enum lttng_domain_type domain,
-                                     struct ltt_session *session,
+                                     const ltt_session::locked_ref& session,
                                      char *channel_name,
                                      struct lttng_payload *reply_payload)
 {
@@ -3966,7 +3967,7 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
 {
        int ret;
        unsigned int i = 0;
-       struct ltt_session *session;
+       struct ltt_session *raw_session_ptr;
        struct ltt_session_list *list = session_get_list();
        struct lttng_session_extended *extended = (typeof(extended)) (&sessions[session_count]);
 
@@ -3975,15 +3976,17 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
         * Iterate over session list and append data after the control struct in
         * the buffer.
         */
-       cds_list_for_each_entry (session, &list->head, list) {
-               if (!session_get(session)) {
-                       continue;
-               }
+       cds_list_for_each_entry (raw_session_ptr, &list->head, list) {
+               auto session = [raw_session_ptr]() {
+                       session_get(raw_session_ptr);
+                       raw_session_ptr->lock();
+                       return ltt_session::locked_ref(*raw_session_ptr);
+               }();
+
                /*
                 * Only list the sessions the user can control.
                 */
                if (!session_access_ok(session, uid) || session->destroyed) {
-                       session_put(session);
                        continue;
                }
 
@@ -4003,7 +4006,6 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
                }
                if (ret < 0) {
                        PERROR("snprintf session path");
-                       session_put(session);
                        continue;
                }
 
@@ -4015,7 +4017,6 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
                extended[i].creation_time.value = (uint64_t) session->creation_time;
                extended[i].creation_time.is_set = 1;
                i++;
-               session_put(session);
        }
 }
 
@@ -4036,14 +4037,12 @@ enum lttng_error_code cmd_kernel_tracer_status(enum lttng_kernel_tracer_status *
  * Command LTTNG_DATA_PENDING returning 0 if the data is NOT pending meaning
  * ready for trace analysis (or any kind of reader) or else 1 for pending data.
  */
-int cmd_data_pending(struct ltt_session *session)
+int cmd_data_pending(const ltt_session::locked_ref& session)
 {
        int ret;
        struct ltt_kernel_session *ksess = session->kernel_session;
        struct ltt_ust_session *usess = session->ust_session;
 
-       LTTNG_ASSERT(session);
-
        DBG("Data pending for session %s", session->name);
 
        /* Session MUST be stopped to ask for data availability. */
@@ -4102,14 +4101,13 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR code.
  */
-int cmd_snapshot_add_output(struct ltt_session *session,
+int cmd_snapshot_add_output(const ltt_session::locked_ref& session,
                            const struct lttng_snapshot_output *output,
                            uint32_t *id)
 {
        int ret;
        struct snapshot_output *new_output;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(output);
 
        DBG("Cmd snapshot add output for session %s", session->name);
@@ -4174,12 +4172,12 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR code.
  */
-int cmd_snapshot_del_output(struct ltt_session *session, const struct lttng_snapshot_output *output)
+int cmd_snapshot_del_output(const ltt_session::locked_ref& session,
+                           const struct lttng_snapshot_output *output)
 {
        int ret;
        struct snapshot_output *sout = nullptr;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(output);
 
        lttng::urcu::read_lock_guard read_lock;
@@ -4222,7 +4220,7 @@ error:
  *
  * Return the size of the newly allocated outputs or a negative LTTNG_ERR code.
  */
-ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
+ssize_t cmd_snapshot_list_outputs(const ltt_session::locked_ref& session,
                                  struct lttng_snapshot_output **outputs)
 {
        int ret, idx = 0;
@@ -4230,7 +4228,6 @@ ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
        struct lttng_ht_iter iter;
        struct snapshot_output *output;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(outputs);
 
        DBG("Cmd snapshot list outputs for session %s", session->name);
@@ -4315,12 +4312,10 @@ end:
  *
  * Return 0 if the metadata can be generated, a LTTNG_ERR code otherwise.
  */
-static int check_regenerate_metadata_support(struct ltt_session *session)
+static int check_regenerate_metadata_support(const ltt_session::locked_ref& session)
 {
        int ret;
 
-       LTTNG_ASSERT(session);
-
        if (session->live_timer != 0) {
                ret = LTTNG_ERR_LIVE_SESSION;
                goto end;
@@ -4362,12 +4357,10 @@ end:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR code.
  */
-int cmd_regenerate_metadata(struct ltt_session *session)
+int cmd_regenerate_metadata(const ltt_session::locked_ref& session)
 {
        int ret;
 
-       LTTNG_ASSERT(session);
-
        ret = check_regenerate_metadata_support(session);
        if (ret) {
                goto end;
@@ -4402,12 +4395,10 @@ end:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR code.
  */
-int cmd_regenerate_statedump(struct ltt_session *session)
+int cmd_regenerate_statedump(const ltt_session::locked_ref& session)
 {
        int ret;
 
-       LTTNG_ASSERT(session);
-
        if (!session->active) {
                ret = LTTNG_ERR_SESSION_NOT_STARTED;
                goto end;
@@ -4940,7 +4931,7 @@ end:
  * Return LTTNG_OK on success or a LTTNG_ERR code.
  */
 static enum lttng_error_code set_relayd_for_snapshot(struct consumer_output *output,
-                                                    const struct ltt_session *session)
+                                                    const ltt_session::locked_ref& session)
 {
        enum lttng_error_code status = LTTNG_OK;
        struct lttng_ht_iter iter;
@@ -4949,7 +4940,6 @@ static enum lttng_error_code set_relayd_for_snapshot(struct consumer_output *out
        const char *base_path;
 
        LTTNG_ASSERT(output);
-       LTTNG_ASSERT(session);
 
        DBG2("Set relayd object from snapshot output");
 
@@ -5019,14 +5009,12 @@ error:
  */
 static enum lttng_error_code record_kernel_snapshot(struct ltt_kernel_session *ksess,
                                                    const struct consumer_output *output,
-                                                   const struct ltt_session *session,
                                                    uint64_t nb_packets_per_stream)
 {
        enum lttng_error_code status;
 
        LTTNG_ASSERT(ksess);
        LTTNG_ASSERT(output);
-       LTTNG_ASSERT(session);
 
        status = kernel_snapshot_record(ksess, output, nb_packets_per_stream);
        return status;
@@ -5039,20 +5027,18 @@ static enum lttng_error_code record_kernel_snapshot(struct ltt_kernel_session *k
  */
 static enum lttng_error_code record_ust_snapshot(struct ltt_ust_session *usess,
                                                 const struct consumer_output *output,
-                                                const struct ltt_session *session,
                                                 uint64_t nb_packets_per_stream)
 {
        enum lttng_error_code status;
 
        LTTNG_ASSERT(usess);
        LTTNG_ASSERT(output);
-       LTTNG_ASSERT(session);
 
        status = ust_app_snapshot_record(usess, output, nb_packets_per_stream);
        return status;
 }
 
-static uint64_t get_session_size_one_more_packet_per_stream(const struct ltt_session *session,
+static uint64_t get_session_size_one_more_packet_per_stream(const ltt_session::locked_ref& session,
                                                            uint64_t cur_nr_packets)
 {
        uint64_t tot_size = 0;
@@ -5102,7 +5088,7 @@ static uint64_t get_session_size_one_more_packet_per_stream(const struct ltt_ses
  * an approximation: for instance, applications could appear/disappear
  * in between this call and actually grabbing data.
  */
-static int64_t get_session_nb_packets_per_stream(const struct ltt_session *session,
+static int64_t get_session_nb_packets_per_stream(const ltt_session::locked_ref& session,
                                                 uint64_t max_size)
 {
        int64_t size_left;
@@ -5135,7 +5121,7 @@ static int64_t get_session_nb_packets_per_stream(const struct ltt_session *sessi
        return cur_nb_packets;
 }
 
-static enum lttng_error_code snapshot_record(struct ltt_session *session,
+static enum lttng_error_code snapshot_record(const ltt_session::locked_ref& session,
                                             const struct snapshot_output *snapshot_output)
 {
        int64_t nb_packets_per_stream;
@@ -5248,7 +5234,6 @@ static enum lttng_error_code snapshot_record(struct ltt_session *session,
        if (session->kernel_session) {
                ret_code = record_kernel_snapshot(session->kernel_session,
                                                  snapshot_kernel_consumer_output,
-                                                 session,
                                                  nb_packets_per_stream);
                if (ret_code != LTTNG_OK) {
                        goto error_close_trace_chunk;
@@ -5256,10 +5241,8 @@ static enum lttng_error_code snapshot_record(struct ltt_session *session,
        }
 
        if (session->ust_session) {
-               ret_code = record_ust_snapshot(session->ust_session,
-                                              snapshot_ust_consumer_output,
-                                              session,
-                                              nb_packets_per_stream);
+               ret_code = record_ust_snapshot(
+                       session->ust_session, snapshot_ust_consumer_output, nb_packets_per_stream);
                if (ret_code != LTTNG_OK) {
                        goto error_close_trace_chunk;
                }
@@ -5305,7 +5288,7 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR code.
  */
-int cmd_snapshot_record(struct ltt_session *session,
+int cmd_snapshot_record(const ltt_session::locked_ref& session,
                        const struct lttng_snapshot_output *output,
                        int wait __attribute__((unused)))
 {
@@ -5315,7 +5298,6 @@ int cmd_snapshot_record(struct ltt_session *session,
        char datetime[16];
        struct snapshot_output *tmp_output = nullptr;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(output);
 
        DBG("Cmd snapshot record for session %s", session->name);
@@ -5436,11 +5418,8 @@ error:
 /*
  * Command LTTNG_SET_SESSION_SHM_PATH processed by the client thread.
  */
-int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path)
+int cmd_set_session_shm_path(const ltt_session::locked_ref& session, const char *shm_path)
 {
-       /* Safety net */
-       LTTNG_ASSERT(session);
-
        /*
         * Can only set shm path before session is started.
         */
@@ -5462,7 +5441,7 @@ int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path)
  *
  * Returns LTTNG_OK on success or else a negative LTTng error code.
  */
-int cmd_rotate_session(struct ltt_session *session,
+int cmd_rotate_session(const ltt_session::locked_ref& session,
                       struct lttng_rotate_session_return *rotate_return,
                       bool quiet_rotation,
                       enum lttng_trace_chunk_command_type command)
@@ -5476,8 +5455,6 @@ int cmd_rotate_session(struct ltt_session *session,
        bool failed_to_rotate = false;
        enum lttng_error_code rotation_fail_code = LTTNG_OK;
 
-       LTTNG_ASSERT(session);
-
        if (!session->has_been_started) {
                cmd_ret = LTTNG_ERR_START_SESSION_ONCE;
                goto end;
@@ -5637,7 +5614,7 @@ end:
        ret = (cmd_ret == LTTNG_OK) ? cmd_ret : -((int) cmd_ret);
        return ret;
 error:
-       if (session_reset_rotation_state(*session, LTTNG_ROTATION_STATE_ERROR)) {
+       if (session_reset_rotation_state(session, LTTNG_ROTATION_STATE_ERROR)) {
                ERR("Failed to reset rotation state of session \"%s\"", session->name);
        }
        goto end;
@@ -5650,7 +5627,7 @@ error:
  *
  * Return LTTNG_OK on success or else an LTTNG_ERR code.
  */
-int cmd_rotate_get_info(struct ltt_session *session,
+int cmd_rotate_get_info(const ltt_session::locked_ref& session,
                        struct lttng_rotation_get_info_return *info_return,
                        uint64_t rotation_id)
 {
@@ -5801,7 +5778,7 @@ end:
  *
  * Return LTTNG_OK on success or else a positive LTTNG_ERR code.
  */
-int cmd_rotation_set_schedule(struct ltt_session *session,
+int cmd_rotation_set_schedule(const ltt_session::locked_ref& session,
                              bool activate,
                              enum lttng_rotation_schedule_type schedule_type,
                              uint64_t new_value)
@@ -5809,8 +5786,6 @@ int cmd_rotation_set_schedule(struct ltt_session *session,
        int ret;
        uint64_t *parameter_value;
 
-       LTTNG_ASSERT(session);
-
        DBG("Cmd rotate set schedule session %s", session->name);
 
        if (session->live_timer || !session->output_traces) {
index 7e5184a21970939d3f7c00eb363eacd189b1e266..6b6dfedf5de0c9de2d16824ef6f1d8ba6b516d0f 100644 (file)
@@ -13,6 +13,7 @@
 #include "lttng-sessiond.hpp"
 #include "lttng/tracker.h"
 #include "session.hpp"
+#include "snapshot-output.hpp"
 
 #include <common/tracker.hpp>
 
@@ -45,10 +46,10 @@ void cmd_init();
 enum lttng_error_code cmd_create_session(struct command_ctx *cmd_ctx,
                                         int sock,
                                         struct lttng_session_descriptor **return_descriptor);
-int cmd_destroy_session(struct ltt_session *session, int *sock_fd);
+int cmd_destroy_session(const ltt_session::locked_ref& session, int *sock_fd);
 
 /* Channel commands */
-int cmd_disable_channel(struct ltt_session *session,
+int cmd_disable_channel(const ltt_session::locked_ref& session,
                        enum lttng_domain_type domain,
                        char *channel_name);
 int cmd_enable_channel(struct command_ctx *cmd_ctx,
@@ -58,27 +59,27 @@ int cmd_enable_channel(struct command_ctx *cmd_ctx,
 
 /* Process attribute tracker commands */
 enum lttng_error_code
-cmd_process_attr_tracker_get_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_get_tracking_policy(const ltt_session::locked_ref& session,
                                             enum lttng_domain_type domain,
                                             enum lttng_process_attr process_attr,
                                             enum lttng_tracking_policy *policy);
 enum lttng_error_code
-cmd_process_attr_tracker_set_tracking_policy(struct ltt_session *session,
+cmd_process_attr_tracker_set_tracking_policy(const ltt_session::locked_ref& session,
                                             enum lttng_domain_type domain,
                                             enum lttng_process_attr process_attr,
                                             enum lttng_tracking_policy policy);
 enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_add_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_add_value(const ltt_session::locked_ref& session,
                                                 enum lttng_domain_type domain,
                                                 enum lttng_process_attr process_attr,
                                                 const struct process_attr_value *value);
 enum lttng_error_code
-cmd_process_attr_tracker_inclusion_set_remove_value(struct ltt_session *session,
+cmd_process_attr_tracker_inclusion_set_remove_value(const ltt_session::locked_ref& session,
                                                    enum lttng_domain_type domain,
                                                    enum lttng_process_attr process_attr,
                                                    const struct process_attr_value *value);
 enum lttng_error_code
-cmd_process_attr_tracker_get_inclusion_set(struct ltt_session *session,
+cmd_process_attr_tracker_get_inclusion_set(const ltt_session::locked_ref& session,
                                           enum lttng_domain_type domain,
                                           enum lttng_process_attr process_attr,
                                           struct lttng_process_attr_values **values);
@@ -108,54 +109,53 @@ int cmd_enable_event(struct command_ctx *cmd_ctx,
                     int wpipe);
 
 /* Trace session action commands */
-int cmd_start_trace(struct ltt_session *session);
-int cmd_stop_trace(struct ltt_session *session);
+int cmd_start_trace(const ltt_session::locked_ref& session);
+int cmd_stop_trace(const ltt_session::locked_ref& session);
 
 /* Consumer commands */
-int cmd_register_consumer(struct ltt_session *session,
+int cmd_register_consumer(const ltt_session::locked_ref& session,
                          enum lttng_domain_type domain,
                          const char *sock_path,
                          struct consumer_data *cdata);
-int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, struct lttng_uri *uris);
-int cmd_setup_relayd(struct ltt_session *session);
+int cmd_set_consumer_uri(const ltt_session::locked_ref& session,
+                        size_t nb_uri,
+                        struct lttng_uri *uris);
+int cmd_setup_relayd(const ltt_session::locked_ref& session);
 
 /* Listing commands */
-ssize_t cmd_list_domains(struct ltt_session *session, struct lttng_domain **domains);
+ssize_t cmd_list_domains(const ltt_session::locked_ref& session, struct lttng_domain **domains);
 enum lttng_error_code cmd_list_events(enum lttng_domain_type domain,
-                                     struct ltt_session *session,
+                                     const ltt_session::locked_ref& session,
                                      char *channel_name,
                                      struct lttng_payload *payload);
 enum lttng_error_code cmd_list_channels(enum lttng_domain_type domain,
-                                       struct ltt_session *session,
+                                       const ltt_session::locked_ref& session,
                                        struct lttng_payload *payload);
-void cmd_list_lttng_sessions(struct lttng_session *sessions,
-                            size_t session_count,
-                            uid_t uid,
-                            gid_t gid);
+void cmd_list_lttng_sessions(lttng_session *sessions, size_t session_count, uid_t uid, gid_t gid);
 enum lttng_error_code cmd_list_tracepoint_fields(enum lttng_domain_type domain,
                                                 struct lttng_payload *reply);
 enum lttng_error_code cmd_list_tracepoints(enum lttng_domain_type domain,
                                           struct lttng_payload *reply_payload);
-ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
+ssize_t cmd_snapshot_list_outputs(const ltt_session::locked_ref& session,
                                  struct lttng_snapshot_output **outputs);
 enum lttng_error_code cmd_list_syscalls(struct lttng_payload *reply_payload);
 
-int cmd_data_pending(struct ltt_session *session);
+int cmd_data_pending(const ltt_session::locked_ref& session);
 enum lttng_error_code cmd_kernel_tracer_status(enum lttng_kernel_tracer_status *status);
 
 /* Snapshot */
-int cmd_snapshot_add_output(struct ltt_session *session,
+int cmd_snapshot_add_output(const ltt_session::locked_ref& session,
                            const struct lttng_snapshot_output *output,
                            uint32_t *id);
-int cmd_snapshot_del_output(struct ltt_session *session,
+int cmd_snapshot_del_output(const ltt_session::locked_ref& session,
                            const struct lttng_snapshot_output *output);
-int cmd_snapshot_record(struct ltt_session *session,
+int cmd_snapshot_record(const ltt_session::locked_ref& session,
                        const struct lttng_snapshot_output *output,
                        int wait);
 
-int cmd_set_session_shm_path(struct ltt_session *session, const char *shm_path);
-int cmd_regenerate_metadata(struct ltt_session *session);
-int cmd_regenerate_statedump(struct ltt_session *session);
+int cmd_set_session_shm_path(const ltt_session::locked_ref& session, const char *shm_path);
+int cmd_regenerate_metadata(const ltt_session::locked_ref& session);
+int cmd_regenerate_statedump(const ltt_session::locked_ref& session);
 
 lttng::ctl::trigger
 cmd_register_trigger(const struct lttng_credentials *cmd_creds,
@@ -177,14 +177,14 @@ cmd_execute_error_query(const struct lttng_credentials *cmd_creds,
                        struct lttng_error_query_results **_results,
                        struct notification_thread_handle *notification_thread);
 
-int cmd_rotate_session(struct ltt_session *session,
+int cmd_rotate_session(const ltt_session::locked_ref& session,
                       struct lttng_rotate_session_return *rotate_return,
                       bool quiet_rotation,
                       enum lttng_trace_chunk_command_type command);
-int cmd_rotate_get_info(struct ltt_session *session,
+int cmd_rotate_get_info(const ltt_session::locked_ref& session,
                        struct lttng_rotation_get_info_return *info_return,
                        uint64_t rotate_id);
-int cmd_rotation_set_schedule(struct ltt_session *session,
+int cmd_rotation_set_schedule(const ltt_session::locked_ref& session,
                              bool activate,
                              enum lttng_rotation_schedule_type schedule_type,
                              uint64_t value);
diff --git a/src/bin/lttng-sessiond/consumer-destination-type.hpp b/src/bin/lttng-sessiond/consumer-destination-type.hpp
new file mode 100644 (file)
index 0000000..3b020e1
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_CONSUMER_DESTINATION_TYPE_HPP
+#define LTTNG_CONSUMER_DESTINATION_TYPE_HPP
+
+enum consumer_dst_type {
+       CONSUMER_DST_LOCAL,
+       CONSUMER_DST_NET,
+};
+
+#endif /* LTTNG_CONSUMER_DESTINATION_TYPE_HPP */
diff --git a/src/bin/lttng-sessiond/consumer-output.hpp b/src/bin/lttng-sessiond/consumer-output.hpp
new file mode 100644 (file)
index 0000000..1e1cbcb
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_CONSUMER_OUTPUT_HPP
+#define LTTNG_CONSUMER_OUTPUT_HPP
+
+#include "session.hpp"
+
+int consumer_set_network_uri(const ltt_session::locked_ref& session,
+                            struct consumer_output *obj,
+                            struct lttng_uri *uri);
+
+#endif /* LTTNG_CONSUMER_OUTPUT_HPP */
index 13c18325d75d363e5da76674734b4e3aedcd0c07..9e7e0536325eb2a398b4f374ecf0d6c695a0598e 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #define _LGPL_SOURCE
+#include "consumer-output.hpp"
 #include "consumer.hpp"
 #include "health-sessiond.hpp"
 #include "lttng-sessiond.hpp"
@@ -674,7 +675,7 @@ error:
  * Return 0 on success. Return 1 if the URI were equal. Else, negative value on
  * error.
  */
-int consumer_set_network_uri(const struct ltt_session *session,
+int consumer_set_network_uri(const ltt_session::locked_ref& session,
                             struct consumer_output *output,
                             struct lttng_uri *uri)
 {
index 6c334875b26012650169d71d30dda47e2bb73926..54365aa6469470e180091e1e63e05e656b240015 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _CONSUMER_H
 #define _CONSUMER_H
 
+#include "consumer-destination-type.hpp"
 #include "snapshot.hpp"
 
 #include <common/consumer/consumer.hpp>
@@ -20,7 +21,6 @@
 
 struct snapshot;
 struct snapshot_output;
-struct ltt_session;
 
 /*
  * Needed until we use C++14, where std::max is constexpr.
@@ -35,11 +35,6 @@ constexpr NumericalType max_constexpr(NumericalType l, NumericalType r)
        return l > r ? l : r;
 }
 
-enum consumer_dst_type {
-       CONSUMER_DST_LOCAL,
-       CONSUMER_DST_NET,
-};
-
 enum consumer_trace_chunk_exists_status {
        CONSUMER_TRACE_CHUNK_EXISTS_STATUS_EXISTS_LOCAL,
        CONSUMER_TRACE_CHUNK_EXISTS_STATUS_EXISTS_REMOTE,
@@ -210,9 +205,7 @@ struct consumer_output *consumer_create_output(enum consumer_dst_type type);
 struct consumer_output *consumer_copy_output(struct consumer_output *obj);
 void consumer_output_get(struct consumer_output *obj);
 void consumer_output_put(struct consumer_output *obj);
-int consumer_set_network_uri(const struct ltt_session *session,
-                            struct consumer_output *obj,
-                            struct lttng_uri *uri);
+
 int consumer_send_fds(struct consumer_socket *sock, const int *fds, size_t nb_fd);
 int consumer_send_msg(struct consumer_socket *sock, const struct lttcomm_consumer_msg *msg);
 int consumer_send_stream(struct consumer_socket *sock,
index 9d53896df9857ff7fa7c0208bb391ea62e428e76..33e90a1a59aeb6b0ef8f39a8a65ac70741804af9 100644 (file)
@@ -434,7 +434,6 @@ static void *thread_dispatch_ust_registration(void *data)
                                        err = 0;
                                        goto error;
                                }
-
                        }
                } while (node != nullptr);
 
index 1ea81f8010d4ff329062ff2609ffa6d7ee3c478e..b813f0fe691a96d730cb9e8be5ef35d52a02b1ad 100644 (file)
@@ -96,7 +96,6 @@ static int kernel_consumer_add_channel(struct consumer_socket *sock,
        bool is_local_trace;
        size_t consumer_path_offset = 0;
        lttng::urcu::read_lock_guard read_lock;
-       ltt_session::ref session;
 
        /* Safety net */
        LTTNG_ASSERT(channel);
@@ -168,7 +167,17 @@ static int kernel_consumer_add_channel(struct consumer_socket *sock,
        health_code_update();
 
        try {
-               session = ltt_session::find_session(ksession->id);
+               const auto session = ltt_session::find_session(ksession->id);
+
+               ASSERT_SESSION_LIST_LOCKED();
+
+               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);
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                ERR_FMT("Fatal error during the creation of a kernel channel: {}, location='{}'",
                        ex.what(),
@@ -176,16 +185,6 @@ static int kernel_consumer_add_channel(struct consumer_socket *sock,
                abort();
        }
 
-       ASSERT_LOCKED(session->_lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
-       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);
        if (status != LTTNG_OK) {
                ret = -1;
                goto error;
index 4cc51a279806e8f68b217b344057eebf03908bdf..e7626a85d41cbb411c3564321eb89068b58f89f0 100644 (file)
@@ -163,13 +163,11 @@ error:
  * Create a new kernel session, register it to the kernel tracer and add it to
  * the session daemon session.
  */
-int kernel_create_session(struct ltt_session *session)
+int kernel_create_session(const ltt_session::locked_ref& session)
 {
        int ret;
        struct ltt_kernel_session *lks;
 
-       LTTNG_ASSERT(session);
-
        /* Allocate data structure */
        lks = trace_kernel_create_session();
        if (lks == nullptr) {
@@ -1898,7 +1896,7 @@ int kernel_supports_event_notifiers()
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code kernel_rotate_session(struct ltt_session *session)
+enum lttng_error_code kernel_rotate_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code status = LTTNG_OK;
@@ -2243,7 +2241,7 @@ bool kernel_tracer_is_initialized()
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code kernel_clear_session(struct ltt_session *session)
+enum lttng_error_code kernel_clear_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code status = LTTNG_OK;
index 6cb89a19ff53782c15dd9a954f9b2c95237b3526..65b3c7896b77d97d918996dccd75a51d11c2e6be 100644 (file)
@@ -24,7 +24,7 @@
 #define KERNEL_EVENT_INIT_LIST_SIZE 64
 
 int kernel_add_channel_context(struct ltt_kernel_channel *chan, struct ltt_kernel_context *ctx);
-int kernel_create_session(struct ltt_session *session);
+int kernel_create_session(const ltt_session::locked_ref& session);
 int kernel_create_channel(struct ltt_kernel_session *session, struct lttng_channel *chan);
 int kernel_create_event(struct lttng_event *ev,
                        struct ltt_kernel_channel *channel,
@@ -67,8 +67,8 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
                                             const struct consumer_output *output,
                                             uint64_t nb_packets_per_stream);
 int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits);
-enum lttng_error_code kernel_rotate_session(struct ltt_session *session);
-enum lttng_error_code kernel_clear_session(struct ltt_session *session);
+enum lttng_error_code kernel_rotate_session(const ltt_session::locked_ref& session);
+enum lttng_error_code kernel_clear_session(const ltt_session::locked_ref& session);
 
 int init_kernel_workarounds();
 int kernel_supports_ring_buffer_snapshot_sample_positions();
index 6451899cd412ea2eaf330a1a95a98366e91abb88..ee4e4690b09f2a3f0a868442caf8a67490e11a1c 100644 (file)
@@ -1279,7 +1279,7 @@ end:
 
 static void destroy_all_sessions_and_wait()
 {
-       struct ltt_session *session, *tmp;
+       struct ltt_session *raw_session_ptr, *tmp;
        struct ltt_session_list *session_list;
 
        DBG("Initiating destruction of all sessions");
@@ -1292,20 +1292,19 @@ static void destroy_all_sessions_and_wait()
        }
 
        /* Initiate the destruction of all sessions. */
-       cds_list_for_each_entry_safe (session, tmp, &session_list->head, list) {
-               if (!session_get(session)) {
-                       continue;
-               }
+       cds_list_for_each_entry_safe (raw_session_ptr, tmp, &session_list->head, list) {
+               const auto session = [raw_session_ptr]() {
+                       session_get(raw_session_ptr);
+                       raw_session_ptr->lock();
+                       return ltt_session::locked_ref(*raw_session_ptr);
+               }();
 
-               session_lock(session);
                if (session->destroyed) {
-                       goto unlock_session;
+                       continue;
                }
+
                (void) cmd_stop_trace(session);
                (void) cmd_destroy_session(session, nullptr);
-       unlock_session:
-               session_unlock(session);
-               session_put(session);
        }
 
        /* Wait for the destruction of all sessions to complete. */
index ca7237802e61096846d9fca358a7d3cd39767842..71f9bbcb5c10d4cba3998dfb5eecd55ec50b9c39 100644 (file)
@@ -112,7 +112,8 @@ end:
        return exists;
 }
 
-void check_session_rotation_pending_on_consumers(ltt_session& session, bool& _rotation_completed)
+void check_session_rotation_pending_on_consumers(const ltt_session::locked_ref& session,
+                                                bool& _rotation_completed)
 {
        int ret = 0;
        struct consumer_socket *socket;
@@ -123,27 +124,27 @@ void check_session_rotation_pending_on_consumers(ltt_session& session, bool& _ro
        enum lttng_trace_chunk_status chunk_status;
        lttng::urcu::read_lock_guard read_lock;
 
-       LTTNG_ASSERT(session.chunk_being_archived);
+       LTTNG_ASSERT(session->chunk_being_archived);
 
        /*
         * Check for a local pending rotation on all consumers (32-bit
         * user space, 64-bit user space, and kernel).
         */
-       if (!session.ust_session) {
+       if (!session->ust_session) {
                goto skip_ust;
        }
 
        cds_lfht_for_each_entry (
-               session.ust_session->consumer->socks->ht, &iter, socket, node.node) {
-               relayd_id = session.ust_session->consumer->type == CONSUMER_DST_LOCAL ?
+               session->ust_session->consumer->socks->ht, &iter, socket, node.node) {
+               relayd_id = session->ust_session->consumer->type == CONSUMER_DST_LOCAL ?
                        -1ULL :
-                       session.ust_session->consumer->net_seq_index;
+                       session->ust_session->consumer->net_seq_index;
 
                lttng::pthread::lock_guard socket_lock(*socket->lock);
                ret = consumer_trace_chunk_exists(socket,
                                                  relayd_id,
-                                                 session.id,
-                                                 session.chunk_being_archived,
+                                                 session->id,
+                                                 session->chunk_being_archived,
                                                  &exists_status);
                if (ret) {
                        ERR("Error occurred while checking rotation status on consumer daemon");
@@ -157,22 +158,22 @@ void check_session_rotation_pending_on_consumers(ltt_session& session, bool& _ro
        }
 
 skip_ust:
-       if (!session.kernel_session) {
+       if (!session->kernel_session) {
                goto skip_kernel;
        }
 
        cds_lfht_for_each_entry (
-               session.kernel_session->consumer->socks->ht, &iter, socket, node.node) {
+               session->kernel_session->consumer->socks->ht, &iter, socket, node.node) {
                lttng::pthread::lock_guard socket_lock(*socket->lock);
 
-               relayd_id = session.kernel_session->consumer->type == CONSUMER_DST_LOCAL ?
+               relayd_id = session->kernel_session->consumer->type == CONSUMER_DST_LOCAL ?
                        -1ULL :
-                       session.kernel_session->consumer->net_seq_index;
+                       session->kernel_session->consumer->net_seq_index;
 
                ret = consumer_trace_chunk_exists(socket,
                                                  relayd_id,
-                                                 session.id,
-                                                 session.chunk_being_archived,
+                                                 session->id,
+                                                 session->chunk_being_archived,
                                                  &exists_status);
                if (ret) {
                        ERR("Error occurred while checking rotation status on consumer daemon");
@@ -190,20 +191,20 @@ end:
        if (!chunk_exists_on_peer) {
                uint64_t chunk_being_archived_id;
 
-               chunk_status = lttng_trace_chunk_get_id(session.chunk_being_archived,
+               chunk_status = lttng_trace_chunk_get_id(session->chunk_being_archived,
                                                        &chunk_being_archived_id);
                LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
                DBG("Rotation of trace archive %" PRIu64
                    " of session \"%s\" is complete on all consumers",
                    chunk_being_archived_id,
-                   session.name);
+                   session->name);
        }
 
        _rotation_completed = !chunk_exists_on_peer;
        if (ret) {
                ret = session_reset_rotation_state(session, LTTNG_ROTATION_STATE_ERROR);
                if (ret) {
-                       ERR("Failed to reset rotation state of session \"%s\"", session.name);
+                       ERR("Failed to reset rotation state of session \"%s\"", session->name);
                }
        }
 }
@@ -213,7 +214,7 @@ end:
  * Should only return non-zero in the event of a fatal error. Doing so will
  * shutdown the thread.
  */
-int check_session_rotation_pending(ltt_session& session,
+int check_session_rotation_pending(const ltt_session::locked_ref& session,
                                   notification_thread_handle& notification_thread_handle)
 {
        int ret;
@@ -223,17 +224,17 @@ int check_session_rotation_pending(ltt_session& session,
        const char *archived_chunk_name;
        uint64_t chunk_being_archived_id;
 
-       if (!session.chunk_being_archived) {
+       if (!session->chunk_being_archived) {
                ret = 0;
                goto end;
        }
 
        chunk_status =
-               lttng_trace_chunk_get_id(session.chunk_being_archived, &chunk_being_archived_id);
+               lttng_trace_chunk_get_id(session->chunk_being_archived, &chunk_being_archived_id);
        LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
 
        DBG("Checking for pending rotation on session \"%s\", trace archive %" PRIu64,
-           session.name,
+           session->name,
            chunk_being_archived_id);
 
        /*
@@ -250,7 +251,7 @@ int check_session_rotation_pending(ltt_session& session,
        }
 
        check_session_rotation_pending_on_consumers(session, rotation_completed);
-       if (!rotation_completed || session.rotation_state == LTTNG_ROTATION_STATE_ERROR) {
+       if (!rotation_completed || session->rotation_state == LTTNG_ROTATION_STATE_ERROR) {
                goto check_ongoing_rotation;
        }
 
@@ -259,41 +260,41 @@ int check_session_rotation_pending(ltt_session& session,
         * rotations can start now.
         */
        chunk_status = lttng_trace_chunk_get_name(
-               session.chunk_being_archived, &archived_chunk_name, nullptr);
+               session->chunk_being_archived, &archived_chunk_name, nullptr);
        LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
-       free(session.last_archived_chunk_name);
-       session.last_archived_chunk_name = strdup(archived_chunk_name);
-       if (!session.last_archived_chunk_name) {
+       free(session->last_archived_chunk_name);
+       session->last_archived_chunk_name = strdup(archived_chunk_name);
+       if (!session->last_archived_chunk_name) {
                PERROR("Failed to duplicate archived chunk name");
        }
 
        session_reset_rotation_state(session, LTTNG_ROTATION_STATE_COMPLETED);
 
-       if (!session.quiet_rotation) {
-               location = session_get_trace_archive_location(&session);
+       if (!session->quiet_rotation) {
+               location = session_get_trace_archive_location(session);
                ret = notification_thread_command_session_rotation_completed(
                        &notification_thread_handle,
-                       session.id,
-                       session.last_archived_chunk_id.value,
+                       session->id,
+                       session->last_archived_chunk_id.value,
                        location);
                lttng_trace_archive_location_put(location);
                if (ret != LTTNG_OK) {
                        ERR("Failed to notify notification thread of completed rotation for session %s",
-                           session.name);
+                           session->name);
                }
        }
 
        ret = 0;
 check_ongoing_rotation:
-       if (session.rotation_state == LTTNG_ROTATION_STATE_ONGOING) {
-               chunk_status = lttng_trace_chunk_get_id(session.chunk_being_archived,
+       if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING) {
+               chunk_status = lttng_trace_chunk_get_id(session->chunk_being_archived,
                                                        &chunk_being_archived_id);
                LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
 
                DBG("Rotation of trace archive %" PRIu64 " is still pending for session %s",
                    chunk_being_archived_id,
-                   session.name);
-               ret = timer_session_rotation_pending_check_start(&session,
+                   session->name);
+               ret = timer_session_rotation_pending_check_start(session,
                                                                 DEFAULT_ROTATE_PENDING_TIMER);
                if (ret) {
                        ERR("Failed to re-enable rotation pending timer");
@@ -307,42 +308,46 @@ end:
 }
 
 /* Call with the session and session_list locks held. */
-int launch_session_rotation(ltt_session& session)
+void launch_session_rotation(const ltt_session::locked_ref& session)
 {
        int ret;
-       struct lttng_rotate_session_return rotation_return;
 
-       DBG("Launching scheduled time-based rotation on session \"%s\"", session.name);
+       DBG_FMT("Launching scheduled time-based rotation: session_name='{}'", session->name);
 
        ASSERT_SESSION_LIST_LOCKED();
-       ASSERT_LOCKED(session._lock);
 
-       ret = cmd_rotate_session(&session,
-                                &rotation_return,
-                                false,
-                                LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
-       if (ret == LTTNG_OK) {
-               DBG("Scheduled time-based rotation successfully launched on session \"%s\"",
-                   session.name);
+       ret = cmd_rotate_session(
+               session, nullptr, false, LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
+       if (ret != LTTNG_OK) {
+               LTTNG_THROW_CTL(fmt::format("Failed to launch session rotation: session_name={}",
+                                           session->name),
+                               static_cast<lttng_error_code>(ret));
        } else {
                /* Don't consider errors as fatal. */
-               DBG("Scheduled time-based rotation aborted for session %s: %s",
-                   session.name,
-                   lttng_strerror(ret));
+               DBG_FMT("Scheduled time-based rotation aborted session_name=`{}`, error='{}'",
+                       session->name,
+                       lttng_strerror(ret));
        }
-
-       return 0;
 }
 
 int run_job(const rotation_thread_job& job,
-           ltt_session& session,
+           const ltt_session::locked_ref& session,
            notification_thread_handle& notification_thread_handle)
 {
-       int ret;
+       int ret = 0;
 
        switch (job.type) {
        case ls::rotation_thread_job_type::SCHEDULED_ROTATION:
-               ret = launch_session_rotation(session);
+               try {
+                       launch_session_rotation(session);
+                       DBG("Scheduled time-based rotation successfully launched on session \"%s\"",
+                           session->name);
+               } catch (const lttng::ctl::error& ctl_ex) {
+                       /* Don't consider errors as fatal. */
+                       DBG("Scheduled time-based rotation aborted for session %s: %s",
+                           session->name,
+                           lttng_strerror(ctl_ex.code()));
+               }
                break;
        case ls::rotation_thread_job_type::CHECK_PENDING_ROTATION:
                ret = check_session_rotation_pending(session, notification_thread_handle);
@@ -543,9 +548,9 @@ void ls::rotation_thread::_handle_job_queue()
 
                /* locked_ref will unlock the session and release the ref held by the job. */
                session_lock(job->session);
-               auto session = ltt_session::locked_ref(job->session);
+               auto session = ltt_session::locked_ref(*job->session);
 
-               if (run_job(*job, *session, _notification_thread_handle)) {
+               if (run_job(*job, session, _notification_thread_handle)) {
                        return;
                }
        }
@@ -591,9 +596,39 @@ void ls::rotation_thread::_handle_notification(const lttng_notification& notific
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::locked_ref session;
        try {
-               session = ltt_session::find_locked_session(condition_session_name);
+               const auto session = ltt_session::find_locked_session(condition_session_name);
+
+               if (!lttng_trigger_is_equal(session->rotate_trigger,
+                                           lttng_notification_get_const_trigger(&notification))) {
+                       DBG("Notification does not originate from the internal size-based scheduled rotation trigger, skipping");
+                       return;
+               }
+
+               unsubscribe_session_consumed_size_rotation(*session);
+
+               ret = cmd_rotate_session(
+                       session, nullptr, false, LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
+               if (ret != LTTNG_OK) {
+                       switch (ret) {
+                       case LTTNG_OK:
+                               break;
+                       case -LTTNG_ERR_ROTATION_PENDING:
+                               DBG("Rotate already pending, subscribe to the next threshold value");
+                               break;
+                       case -LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
+                               DBG("Rotation already happened since last stop, subscribe to the next threshold value");
+                               break;
+                       case -LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
+                               DBG("Rotation already happened since last stop and clear, subscribe to the next threshold value");
+                               break;
+                       default:
+                               LTTNG_THROW_CTL("Failed to rotate on consumed size notification",
+                                               static_cast<lttng_error_code>(-ret));
+                       }
+               }
+
+               subscribe_session_consumed_size_rotation(*session, consumed + session->rotate_size);
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to find session while handling notification: notification_type={}, session name=`{}`",
                        lttng_condition_type_str(condition_type),
@@ -604,35 +639,6 @@ void ls::rotation_thread::_handle_notification(const lttng_notification& notific
                 */
                return;
        }
-
-       if (!lttng_trigger_is_equal(session->rotate_trigger,
-                                   lttng_notification_get_const_trigger(&notification))) {
-               DBG("Notification does not originate from the internal size-based scheduled rotation trigger, skipping");
-               return;
-       }
-
-       unsubscribe_session_consumed_size_rotation(*session);
-
-       ret = cmd_rotate_session(
-               session.get(), nullptr, false, LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
-       switch (ret) {
-       case LTTNG_OK:
-               break;
-       case -LTTNG_ERR_ROTATION_PENDING:
-               DBG("Rotate already pending, subscribe to the next threshold value");
-               break;
-       case -LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP:
-               DBG("Rotation already happened since last stop, subscribe to the next threshold value");
-               break;
-       case -LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR:
-               DBG("Rotation already happened since last stop and clear, subscribe to the next threshold value");
-               break;
-       default:
-               LTTNG_THROW_CTL("Failed to rotate on consumed size notification",
-                               static_cast<lttng_error_code>(-ret));
-       }
-
-       subscribe_session_consumed_size_rotation(*session, consumed + session->rotate_size);
 }
 
 void ls::rotation_thread::_handle_notification_channel_activity()
index 484bf7c906a665a7fe9cc3a70c737c7a54a79ad9..b65bcf9f28a06d7fde45437e8206dd2dad420a6e 100644 (file)
@@ -1670,13 +1670,12 @@ end:
 }
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int save_kernel_session(struct config_writer *writer, struct ltt_session *session)
+static int save_kernel_session(struct config_writer *writer, const ltt_session::locked_ref& session)
 {
        int ret;
        struct ltt_kernel_channel *kchan;
 
        LTTNG_ASSERT(writer);
-       LTTNG_ASSERT(session);
 
        ret = config_writer_write_element_string(
                writer, config_element_type, config_domain_type_kernel);
@@ -1746,7 +1745,7 @@ static const char *get_config_domain_str(enum lttng_domain_type domain)
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
 static int save_process_attr_tracker(struct config_writer *writer,
-                                    struct ltt_session *sess,
+                                    const ltt_session::locked_ref& session,
                                     int domain,
                                     enum lttng_process_attr process_attr)
 {
@@ -1795,13 +1794,13 @@ static int save_process_attr_tracker(struct config_writer *writer,
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
        {
-               tracker = kernel_get_process_attr_tracker(sess->kernel_session, process_attr);
+               tracker = kernel_get_process_attr_tracker(session->kernel_session, process_attr);
                LTTNG_ASSERT(tracker);
                break;
        }
        case LTTNG_DOMAIN_UST:
        {
-               tracker = trace_ust_get_process_attr_tracker(sess->ust_session, process_attr);
+               tracker = trace_ust_get_process_attr_tracker(session->ust_session, process_attr);
                LTTNG_ASSERT(tracker);
                break;
        }
@@ -1922,55 +1921,58 @@ end:
 }
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int
-save_process_attr_trackers(struct config_writer *writer, struct ltt_session *sess, int domain)
+static int save_process_attr_trackers(struct config_writer *writer,
+                                     const ltt_session::locked_ref& session,
+                                     int domain)
 {
        int ret;
 
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_PROCESS_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_PROCESS_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
-               ret = save_process_attr_tracker(writer, sess, domain, LTTNG_PROCESS_ATTR_USER_ID);
+               ret = save_process_attr_tracker(
+                       writer, session, domain, LTTNG_PROCESS_ATTR_USER_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
-               ret = save_process_attr_tracker(writer, sess, domain, LTTNG_PROCESS_ATTR_GROUP_ID);
+               ret = save_process_attr_tracker(
+                       writer, session, domain, LTTNG_PROCESS_ATTR_GROUP_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                break;
        case LTTNG_DOMAIN_UST:
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
                ret = save_process_attr_tracker(
-                       writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
+                       writer, session, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
                if (ret != LTTNG_OK) {
                        goto end;
                }
@@ -1986,7 +1988,7 @@ end:
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
 static int save_ust_domain(struct config_writer *writer,
-                          struct ltt_session *session,
+                          const ltt_session::locked_ref& session,
                           enum lttng_domain_type domain)
 {
        int ret;
@@ -1997,7 +1999,6 @@ static int save_ust_domain(struct config_writer *writer,
        const char *config_domain_name;
 
        LTTNG_ASSERT(writer);
-       LTTNG_ASSERT(session);
 
        ret = config_writer_open_element(writer, config_element_domain);
        if (ret) {
@@ -2092,12 +2093,11 @@ end:
 }
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int save_domains(struct config_writer *writer, struct ltt_session *session)
+static int save_domains(struct config_writer *writer, const ltt_session::locked_ref& session)
 {
        int ret = LTTNG_OK;
 
        LTTNG_ASSERT(writer);
-       LTTNG_ASSERT(session);
 
        if (!session->kernel_session && !session->ust_session) {
                goto end;
@@ -2371,12 +2371,11 @@ end_unlock:
 }
 
 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int save_session_output(struct config_writer *writer, struct ltt_session *session)
+static int save_session_output(struct config_writer *writer, const ltt_session::locked_ref& session)
 {
        int ret;
 
        LTTNG_ASSERT(writer);
-       LTTNG_ASSERT(session);
 
        if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
            (!session->snapshot_mode && !session->consumer)) {
@@ -2458,7 +2457,7 @@ end:
 }
 
 static int save_session_rotation_schedules(struct config_writer *writer,
-                                          struct ltt_session *session)
+                                          const ltt_session::locked_ref& session)
 {
        int ret;
 
@@ -2497,7 +2496,7 @@ end:
  *
  * Return LTTNG_OK on success else a LTTNG_ERR* code.
  */
-static int save_session(struct ltt_session *session,
+static int save_session(const ltt_session::locked_ref& session,
                        struct lttng_save_session_attr *attr,
                        lttng_sock_cred *creds)
 {
@@ -2509,7 +2508,6 @@ static int save_session(struct ltt_session *session,
        const char *provided_path;
        int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC;
 
-       LTTNG_ASSERT(session);
        LTTNG_ASSERT(attr);
        LTTNG_ASSERT(creds);
 
@@ -2735,50 +2733,42 @@ end:
 
 int cmd_save_sessions(struct lttng_save_session_attr *attr, lttng_sock_cred *creds)
 {
-       int ret;
-       const char *session_name;
-
        const auto list_lock = lttng::sessiond::lock_session_list();
+       const auto session_name = lttng_save_session_attr_get_session_name(attr);
 
-       session_name = lttng_save_session_attr_get_session_name(attr);
        if (session_name) {
-
                /*
-               * Mind the order of the declaration of list_lock vs session:
-               * the session list lock must always be released _after_ the release of
-               * a session's reference (the destruction of a ref/locked_ref) to ensure
-               * since the reference's release may unpublish the session from the list of
-               * sessions.
-               */
-               ltt_session::locked_ref session;
-
+                * Mind the order of the declaration of list_lock vs session:
+                * the session list lock must always be released _after_ the release of
+                * a session's reference (the destruction of a ref/locked_ref) to ensure
+                * since the reference's release may unpublish the session from the list of
+                * sessions.
+                */
                try {
-                       session = ltt_session::find_locked_session(session_name);
+                       const auto session = ltt_session::find_locked_session(session_name);
+                       const auto save_ret = save_session(session, attr, creds);
+                       if (save_ret != LTTNG_OK) {
+                               return save_ret;
+                       }
                } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                        WARN_FMT("Failed to save session: {} {}", ex.what(), ex.source_location);
-                       ret = LTTNG_ERR_SESS_NOT_FOUND;
-                       return ret;
-               }
-
-               ret = save_session(session.get(), attr, creds);
-               if (ret != LTTNG_OK) {
-                       return ret;
+                       return LTTNG_ERR_SESS_NOT_FOUND;
                }
        } else {
                struct ltt_session_list *list = session_get_list();
-               struct ltt_session *session;
+               struct ltt_session *raw_session_ptr;
+
+               cds_list_for_each_entry (raw_session_ptr, &list->head, list) {
+                       auto session = [raw_session_ptr]() {
+                               session_get(raw_session_ptr);
+                               raw_session_ptr->lock();
+                               return ltt_session::locked_ref(*raw_session_ptr);
+                       }();
+                       const auto save_ret = save_session(session, attr, creds);
 
-               cds_list_for_each_entry (session, &list->head, list) {
-                       if (!session_get(session)) {
-                               continue;
-                       }
-                       session_lock(session);
-                       ret = save_session(session, attr, creds);
-                       session_unlock(session);
-                       session_put(session);
                        /* Don't abort if we don't have the required permissions. */
-                       if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
-                               return ret;
+                       if (save_ret != LTTNG_OK && save_ret != LTTNG_ERR_EPERM) {
+                               return save_ret;
                        }
                }
        }
index b588e605510e48b9118c391d4e3dc3c1ee3f5552..97391ad98f1ae1d9006cf5b316b011abe719fdf7 100644 (file)
@@ -218,10 +218,8 @@ int session_trylock_list() noexcept
 
 /*
  * Get the session's consumer destination type.
- *
- * 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 ltt_session::locked_ref& session)
 {
        /*
         * The output information is duplicated in both of those session types.
@@ -235,10 +233,8 @@ enum consumer_dst_type session_get_consumer_destination_type(const struct ltt_se
 /*
  * Get the session's consumer network hostname.
  * The caller must ensure that the destination is of type "net".
- *
- * The caller must hold the session lock.
  */
-const char *session_get_net_consumer_hostname(const struct ltt_session *session)
+const char *session_get_net_consumer_hostname(const ltt_session::locked_ref& session)
 {
        const char *hostname = nullptr;
        const struct consumer_output *output;
@@ -266,10 +262,8 @@ const char *session_get_net_consumer_hostname(const struct ltt_session *session)
 /*
  * Get the session's consumer network control and data ports.
  * The caller must ensure that the destination is of type "net".
- *
- * The caller must hold the session lock.
  */
-void session_get_net_consumer_ports(const struct ltt_session *session,
+void session_get_net_consumer_ports(const ltt_session::locked_ref& session,
                                    uint16_t *control_port,
                                    uint16_t *data_port)
 {
@@ -283,11 +277,9 @@ void session_get_net_consumer_ports(const struct ltt_session *session,
 
 /*
  * Get the location of the latest trace archive produced by a rotation.
- *
- * The caller must hold the session lock.
  */
 struct lttng_trace_archive_location *
-session_get_trace_archive_location(const struct ltt_session *session)
+session_get_trace_archive_location(const ltt_session::locked_ref& session)
 {
        int ret;
        struct lttng_trace_archive_location *location = nullptr;
@@ -508,12 +500,12 @@ void session_unlock(struct ltt_session *session)
        session->unlock();
 }
 
-void ltt_session::_const_session_unlock(const ltt_session &session)
+void ltt_session::_const_session_unlock(const ltt_sessionsession)
 {
        pthread_mutex_unlock(&session._lock);
 }
 
-static int _session_set_trace_chunk_no_lock_check(struct ltt_session *session,
+static int _session_set_trace_chunk_no_lock_check(const ltt_session::locked_ref& session,
                                                  struct lttng_trace_chunk *new_trace_chunk,
                                                  struct lttng_trace_chunk **_current_trace_chunk)
 {
@@ -652,7 +644,7 @@ error:
 }
 
 struct lttng_trace_chunk *
-session_create_new_trace_chunk(const struct ltt_session *session,
+session_create_new_trace_chunk(const ltt_session::locked_ref& session,
                               const struct consumer_output *consumer_output_override,
                               const char *session_base_path_override,
                               const char *chunk_name_override)
@@ -759,7 +751,7 @@ error:
        goto end;
 }
 
-int session_close_trace_chunk(struct ltt_session *session,
+int session_close_trace_chunk(const ltt_session::locked_ref& session,
                              struct lttng_trace_chunk *trace_chunk,
                              enum lttng_trace_chunk_command_type close_command,
                              char *closed_trace_chunk_path)
@@ -886,7 +878,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(const ltt_session::locked_ref& session)
 {
        enum lttng_error_code ret = LTTNG_OK;
        struct consumer_socket *socket;
@@ -921,7 +913,7 @@ end:
        return ret;
 }
 
-enum lttng_error_code session_open_packets(struct ltt_session *session)
+enum lttng_error_code session_open_packets(const ltt_session::locked_ref& session)
 {
        enum lttng_error_code ret = LTTNG_OK;
 
@@ -952,7 +944,7 @@ end:
  *
  * Must be called with the session lock held.
  */
-int session_set_trace_chunk(struct ltt_session *session,
+int session_set_trace_chunk(const ltt_session::locked_ref& session,
                            struct lttng_trace_chunk *new_trace_chunk,
                            struct lttng_trace_chunk **current_trace_chunk)
 {
@@ -961,10 +953,10 @@ int session_set_trace_chunk(struct ltt_session *session,
                session, new_trace_chunk, current_trace_chunk);
 }
 
-static void session_notify_destruction(const struct ltt_session *session)
+static void session_notify_destruction(const ltt_session::locked_ref& session)
 {
        size_t i;
-       const size_t count = lttng_dynamic_array_get_count(&session->destroy_notifiers);
+       const auto count = lttng_dynamic_array_get_count(&session->destroy_notifiers);
 
        for (i = 0; i < count; i++) {
                const struct ltt_session_destroy_notifier_element *element =
@@ -978,19 +970,19 @@ static void session_notify_destruction(const struct ltt_session *session)
 /*
  * Fire each clear notifier once, and remove them from the array.
  */
-void session_notify_clear(ltt_session& session)
+void session_notify_clear(const ltt_session::locked_ref& session)
 {
        size_t i;
-       const size_t count = lttng_dynamic_array_get_count(&session.clear_notifiers);
+       const auto 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);
+               element->notifier(session, element->user_data);
        }
-       lttng_dynamic_array_clear(&session.clear_notifiers);
+       lttng_dynamic_array_clear(&session->clear_notifiers);
 }
 
 static void session_release(struct urcu_ref *ref)
@@ -1037,14 +1029,26 @@ static void session_release(struct urcu_ref *ref)
 
        snapshot_destroy(&session->snapshot);
 
-       pthread_mutex_destroy(&session->_lock);
-
        if (session_published) {
                ASSERT_SESSION_LIST_LOCKED();
                del_session_list(session);
                del_session_ht(session);
        }
-       session_notify_destruction(session);
+
+       /*
+        * The notifiers make use of free-functions that expect a locked reference to a session.
+        * To create such a reference, we need to acquire the lock and acquire a reference (increase
+        * the ref-count). To ensure the release of the reference does not re-cross the zero value,
+        * set the refcount to a tombstone value.
+        */
+       session->ref_count.refcount = 0xDEAD5E55;
+       session_notify_destruction([session]() {
+               session_lock(session);
+               session_get(session);
+               return ltt_session::locked_ref(*session);
+       }());
+
+       pthread_mutex_destroy(&session->_lock);
 
        consumer_output_put(session->consumer);
        kernel_free_session(ksess);
@@ -1129,7 +1133,7 @@ void session_destroy(struct ltt_session *session)
        session_put(session);
 }
 
-int session_add_destroy_notifier(struct ltt_session *session,
+int session_add_destroy_notifier(const ltt_session::locked_ref& session,
                                 ltt_session_destroy_notifier notifier,
                                 void *user_data)
 {
@@ -1139,7 +1143,7 @@ int session_add_destroy_notifier(struct ltt_session *session,
        return lttng_dynamic_array_add_element(&session->destroy_notifiers, &element);
 }
 
-int session_add_clear_notifier(struct ltt_session *session,
+int session_add_clear_notifier(const ltt_session::locked_ref& session,
                               ltt_session_clear_notifier notifier,
                               void *user_data)
 {
@@ -1330,9 +1334,8 @@ error:
  * Check if the UID matches the session. Root user has access to all
  * sessions.
  */
-bool session_access_ok(struct ltt_session *session, uid_t uid)
+bool session_access_ok(const ltt_session::locked_ref& session, uid_t uid)
 {
-       LTTNG_ASSERT(session);
        return (uid == session->uid) || uid == 0;
 }
 
@@ -1351,26 +1354,26 @@ 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(ltt_session& session, enum lttng_rotation_state result)
+int session_reset_rotation_state(const ltt_session::locked_ref& session,
+                                enum lttng_rotation_state result)
 {
        int ret = 0;
 
        ASSERT_SESSION_LIST_LOCKED();
-       ASSERT_LOCKED(session._lock);
 
-       session.rotation_state = result;
-       if (session.rotation_pending_check_timer_enabled) {
+       session->rotation_state = result;
+       if (session->rotation_pending_check_timer_enabled) {
                ret = timer_session_rotation_pending_check_stop(session);
        }
-       if (session.chunk_being_archived) {
+       if (session->chunk_being_archived) {
                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_trace_chunk_put(session.chunk_being_archived);
-               session.chunk_being_archived = nullptr;
+               LTTNG_OPTIONAL_SET(&session->last_archived_chunk_id, chunk_id);
+               lttng_trace_chunk_put(session->chunk_being_archived);
+               session->chunk_being_archived = nullptr;
                /*
                 * Fire the clear reply notifiers if we are completing a clear
                 * rotation.
@@ -1453,7 +1456,7 @@ ltt_session::locked_ref ltt_session::find_locked_session(ltt_session::id_t id)
         * session.
         */
        session_lock(session);
-       return ltt_session::locked_ref(session);
+       return ltt_session::locked_ref(*session);
 }
 
 ltt_session::locked_ref ltt_session::find_locked_session(lttng::c_string_view name)
@@ -1466,7 +1469,7 @@ ltt_session::locked_ref ltt_session::find_locked_session(lttng::c_string_view na
        }
 
        session_lock(session);
-       return ltt_session::locked_ref(session);
+       return ltt_session::locked_ref(*session);
 }
 
 ltt_session::const_locked_ref ltt_session::find_locked_const_session(ltt_session::id_t id)
@@ -1479,7 +1482,7 @@ ltt_session::const_locked_ref ltt_session::find_locked_const_session(ltt_session
        }
 
        session_lock(session);
-       return ltt_session::const_locked_ref(session);
+       return ltt_session::const_locked_ref(*session);
 }
 
 ltt_session::const_locked_ref ltt_session::find_locked_const_session(lttng::c_string_view name)
@@ -1492,7 +1495,7 @@ ltt_session::const_locked_ref ltt_session::find_locked_const_session(lttng::c_st
        }
 
        session_lock(session);
-       return ltt_session::const_locked_ref(session);
+       return ltt_session::const_locked_ref(*session);
 }
 
 ltt_session::ref ltt_session::find_session(ltt_session::id_t id)
@@ -1504,7 +1507,7 @@ ltt_session::ref ltt_session::find_session(ltt_session::id_t id)
                LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
        }
 
-       return ltt_session::ref(session);
+       return ltt_session::ref(*session);
 }
 
 ltt_session::ref ltt_session::find_session(lttng::c_string_view name)
@@ -1516,7 +1519,7 @@ ltt_session::ref ltt_session::find_session(lttng::c_string_view name)
                LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
        }
 
-       return ltt_session::ref(session);
+       return ltt_session::ref(*session);
 }
 
 ltt_session::const_ref ltt_session::find_const_session(ltt_session::id_t id)
@@ -1528,7 +1531,7 @@ ltt_session::const_ref ltt_session::find_const_session(ltt_session::id_t id)
                LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
        }
 
-       return ltt_session::const_ref(session);
+       return ltt_session::const_ref(*session);
 }
 
 ltt_session::const_ref ltt_session::find_const_session(lttng::c_string_view name)
@@ -1540,7 +1543,7 @@ ltt_session::const_ref ltt_session::find_const_session(lttng::c_string_view name
                LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
        }
 
-       return ltt_session::const_ref(session);
+       return ltt_session::const_ref(*session);
 }
 
 void ltt_session::_const_session_put(const ltt_session *session)
index e4d62a7c46bc4b7b1a072573e5c7ebfe1583144d..d86147ac48d7da9a6e6236bf2195ef45146db232 100644 (file)
@@ -17,6 +17,7 @@
 #include <common/hashtable/hashtable.hpp>
 #include <common/make-unique-wrapper.hpp>
 #include <common/pthread-lock.hpp>
+#include <common/reference.hpp>
 
 #include <lttng/location.h>
 #include <lttng/lttng-error.h>
@@ -32,9 +33,6 @@
 
 struct ltt_ust_session;
 
-using ltt_session_destroy_notifier = void (*)(const struct ltt_session *, void *);
-using ltt_session_clear_notifier = void (*)(const struct ltt_session *, void *);
-
 struct ltt_session;
 struct ltt_session_list;
 
@@ -63,75 +61,6 @@ int session_trylock_list() noexcept;
 #define LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id) \
        throw lttng::sessiond::exceptions::session_not_found_error(id, LTTNG_SOURCE_LOCATION())
 
-void session_destroy(struct ltt_session *session);
-int session_add_destroy_notifier(struct ltt_session *session,
-                                ltt_session_destroy_notifier notifier,
-                                void *user_data);
-
-int session_add_clear_notifier(struct ltt_session *session,
-                              ltt_session_clear_notifier notifier,
-                              void *user_data);
-void session_notify_clear(ltt_session& session);
-
-enum consumer_dst_type session_get_consumer_destination_type(const struct ltt_session *session);
-const char *session_get_net_consumer_hostname(const struct ltt_session *session);
-void session_get_net_consumer_ports(const struct ltt_session *session,
-                                   uint16_t *control_port,
-                                   uint16_t *data_port);
-struct lttng_trace_archive_location *
-session_get_trace_archive_location(const struct ltt_session *session);
-
-struct ltt_session_list *session_get_list();
-void session_list_wait_empty(std::unique_lock<std::mutex> list_lock);
-
-bool session_access_ok(struct ltt_session *session, uid_t uid);
-
-int session_reset_rotation_state(ltt_session& session, enum lttng_rotation_state result);
-
-/* Create a new trace chunk object from the session's configuration. */
-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);
-
-/*
- * Set `new_trace_chunk` as the session's current trace chunk. A reference
- * to `new_trace_chunk` is acquired by the session. The chunk is created
- * on remote peers (consumer and relay daemons).
- *
- * A reference to the session's current trace chunk is returned through
- * `current_session_trace_chunk` on success.
- */
-int session_set_trace_chunk(struct ltt_session *session,
-                           struct lttng_trace_chunk *new_trace_chunk,
-                           struct lttng_trace_chunk **current_session_trace_chunk);
-
-/*
- * Close a chunk on the remote peers of a session. Has no effect on the
- * ltt_session itself.
- */
-int session_close_trace_chunk(struct ltt_session *session,
-                             struct lttng_trace_chunk *trace_chunk,
-                             enum lttng_trace_chunk_command_type close_command,
-                             char *path);
-
-/* Open a packet in all channels of a given session. */
-enum lttng_error_code session_open_packets(struct ltt_session *session);
-
-bool session_output_supports_trace_chunks(const struct ltt_session *session);
-
-/*
- * Sample the id of a session looked up via its name.
- * Here the term "sampling" hint the caller that this return the id at a given
- * point in time with no guarantee that the session for which the id was
- * sampled still exist at that point.
- *
- * Return 0 when the session is not found,
- * Return 1 when the session is found and set `id`.
- */
-bool sample_session_id_by_name(const char *name, uint64_t *id);
-
 /*
  * Tracing session list
  *
@@ -174,25 +103,25 @@ private:
        static void _locked_session_release(ltt_session *session);
        static void _locked_const_session_release(const ltt_session *session);
        static void _const_session_put(const ltt_session *session);
-       static void _const_session_unlock(const ltt_session &session);
+       static void _const_session_unlock(const ltt_sessionsession);
 
 public:
-       using locked_ref =
-               std::unique_ptr<ltt_session,
-                               lttng::memory::create_deleter_class<
-                                       ltt_session,
-                                       ltt_session::_locked_session_release>::deleter>;
-       using ref = std::unique_ptr<
+       using locked_ref = lttng::non_copyable_reference<
+               ltt_session,
+               lttng::memory::create_deleter_class<ltt_session,
+                                                   ltt_session::_locked_session_release>::deleter>;
+       using ref = lttng::non_copyable_reference<
                ltt_session,
                lttng::memory::create_deleter_class<ltt_session, session_put>::deleter>;
-       using const_locked_ref =
-               std::unique_ptr<const ltt_session,
-                               lttng::memory::create_deleter_class<
-                                       const ltt_session,
-                                       ltt_session::_locked_const_session_release>::deleter>;
-       using const_ref = std::unique_ptr<
+       using const_locked_ref = lttng::non_copyable_reference<
+               const ltt_session,
+               lttng::memory::create_deleter_class<
+                       const ltt_session,
+                       ltt_session::_locked_const_session_release>::deleter>;
+       using const_ref = lttng::non_copyable_reference<
                const ltt_session,
-               lttng::memory::create_deleter_class<const ltt_session, ltt_session::_const_session_put>::deleter>;
+               lttng::memory::create_deleter_class<const ltt_session,
+                                                   ltt_session::_const_session_put>::deleter>;
 
        void lock() const noexcept;
        void unlock() const noexcept;
@@ -343,10 +272,15 @@ public:
        struct lttng_dynamic_array clear_notifiers;
        /* Session base path override. Set non-null. */
        char *base_path;
-
-
 };
 
+/*
+ * Destruction notifiers are invoked in an exclusive context. There is no need for the session to be
+ * locked nor for a reference to be acquired.
+ */
+using ltt_session_destroy_notifier = void (*)(const ltt_session::locked_ref&, void *);
+using ltt_session_clear_notifier = void (*)(const ltt_session::locked_ref&, void *);
+
 namespace lttng {
 namespace sessiond {
 
@@ -376,7 +310,8 @@ public:
                }
                /* NOLINTEND(google-explicit-constructor) */
 
-               explicit query_parameter(ltt_session::id_t id_) : type(query_type::BY_ID), parameter(id_)
+               explicit query_parameter(ltt_session::id_t id_) :
+                       type(query_type::BY_ID), parameter(id_)
                {
                }
 
@@ -453,4 +388,75 @@ public:
 } /* namespace sessiond */
 } /* namespace lttng */
 
+void session_destroy(struct ltt_session *session);
+int session_add_destroy_notifier(const ltt_session::locked_ref& session,
+                                ltt_session_destroy_notifier notifier,
+                                void *user_data);
+
+int session_add_clear_notifier(const ltt_session::locked_ref& session,
+                              ltt_session_clear_notifier notifier,
+                              void *user_data);
+void session_notify_clear(const ltt_session::locked_ref& session);
+
+enum consumer_dst_type
+session_get_consumer_destination_type(const ltt_session::locked_ref& session);
+const char *session_get_net_consumer_hostname(const ltt_session::locked_ref& session);
+void session_get_net_consumer_ports(const ltt_session::locked_ref& session,
+                                   uint16_t *control_port,
+                                   uint16_t *data_port);
+struct lttng_trace_archive_location *
+session_get_trace_archive_location(const ltt_session::locked_ref& session);
+
+struct ltt_session_list *session_get_list();
+void session_list_wait_empty(std::unique_lock<std::mutex> list_lock);
+
+bool session_access_ok(const ltt_session::locked_ref& session, uid_t uid);
+
+int session_reset_rotation_state(const ltt_session::locked_ref& session,
+                                enum lttng_rotation_state result);
+
+/* Create a new trace chunk object from the session's configuration. */
+struct lttng_trace_chunk *
+session_create_new_trace_chunk(const ltt_session::locked_ref& session,
+                              const struct consumer_output *consumer_output_override,
+                              const char *session_base_path_override,
+                              const char *chunk_name_override);
+
+/*
+ * Set `new_trace_chunk` as the session's current trace chunk. A reference
+ * to `new_trace_chunk` is acquired by the session. The chunk is created
+ * on remote peers (consumer and relay daemons).
+ *
+ * A reference to the session's current trace chunk is returned through
+ * `current_session_trace_chunk` on success.
+ */
+int session_set_trace_chunk(const ltt_session::locked_ref& session,
+                           struct lttng_trace_chunk *new_trace_chunk,
+                           struct lttng_trace_chunk **current_session_trace_chunk);
+
+/*
+ * Close a chunk on the remote peers of a session. Has no effect on the
+ * ltt_session itself.
+ */
+int session_close_trace_chunk(const ltt_session::locked_ref& session,
+                             struct lttng_trace_chunk *trace_chunk,
+                             enum lttng_trace_chunk_command_type close_command,
+                             char *path);
+
+/* Open a packet in all channels of a given session. */
+enum lttng_error_code session_open_packets(const ltt_session::locked_ref& session);
+
+bool session_output_supports_trace_chunks(const struct ltt_session *session);
+
+/*
+ * Sample the id of a session looked up via its name.
+ * Here the term "sampling" hint the caller that this return the id at a given
+ * point in time with no guarantee that the session for which the id was
+ * sampled still exist at that point.
+ *
+ * Return 0 when the session is not found,
+ * Return 1 when the session is found and set `id`.
+ */
+bool sample_session_id_by_name(const char *name, uint64_t *id);
+
 #endif /* _LTT_SESSION_H */
diff --git a/src/bin/lttng-sessiond/snapshot-output.hpp b/src/bin/lttng-sessiond/snapshot-output.hpp
new file mode 100644 (file)
index 0000000..6d580e4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_SNAPSHOT_OUTPUT_HPP
+#define LTTNG_SNAPSHOT_OUTPUT_HPP
+
+int snapshot_output_init(const ltt_session::locked_ref& session,
+                        uint64_t max_size,
+                        const char *name,
+                        const char *ctrl_url,
+                        const char *data_url,
+                        struct consumer_output *consumer,
+                        struct snapshot_output *output,
+                        struct snapshot *snapshot);
+int snapshot_output_init_with_uri(const ltt_session::locked_ref& session,
+                                 uint64_t max_size,
+                                 const char *name,
+                                 struct lttng_uri *uris,
+                                 size_t nb_uri,
+                                 struct consumer_output *consumer,
+                                 struct snapshot_output *output,
+                                 struct snapshot *snapshot);
+
+#endif /* LTTNG_SNAPSHOT_OUTPUT_HPP */
index e7a0033541a5d07d5cdafd77d5f4306e462e2662..4f72306ac1ea18e0bb9807acc501e5402da6bcd7 100644 (file)
@@ -6,6 +6,8 @@
  */
 
 #define _LGPL_SOURCE
+#include "consumer-output.hpp"
+#include "snapshot-output.hpp"
 #include "snapshot.hpp"
 #include "utils.hpp"
 
@@ -29,7 +31,7 @@ static inline unsigned long get_next_output_id(struct snapshot *snapshot)
  *
  * Return 0 on success or else a negative value.
  */
-static int output_init(const struct ltt_session *session,
+static int output_init(const ltt_session::locked_ref& session,
                       uint64_t max_size,
                       const char *name,
                       struct lttng_uri *uris,
@@ -130,7 +132,7 @@ end:
  *
  * Return 0 on success or else a negative value.
  */
-int snapshot_output_init_with_uri(const struct ltt_session *session,
+int snapshot_output_init_with_uri(const ltt_session::locked_ref& session,
                                  uint64_t max_size,
                                  const char *name,
                                  struct lttng_uri *uris,
@@ -148,7 +150,7 @@ int snapshot_output_init_with_uri(const struct ltt_session *session,
  *
  * Return 0 on success or else a negative value.
  */
-int snapshot_output_init(const struct ltt_session *session,
+int snapshot_output_init(const ltt_session::locked_ref& session,
                         uint64_t max_size,
                         const char *name,
                         const char *ctrl_url,
index 726b89f80c23fbea59ea73452a29a6c692159f66..bdc520643aa1040f0b521acfed8254934e03ac87 100644 (file)
@@ -18,7 +18,6 @@
 #include <stdint.h>
 
 struct consumer_output;
-struct ltt_session;
 
 struct snapshot_output {
        uint32_t id;
@@ -61,22 +60,7 @@ void snapshot_add_output(struct snapshot *snapshot, struct snapshot_output *outp
 /* Snapshot output object. */
 struct snapshot_output *snapshot_output_alloc();
 void snapshot_output_destroy(struct snapshot_output *obj);
-int snapshot_output_init(const struct ltt_session *session,
-                        uint64_t max_size,
-                        const char *name,
-                        const char *ctrl_url,
-                        const char *data_url,
-                        struct consumer_output *consumer,
-                        struct snapshot_output *output,
-                        struct snapshot *snapshot);
-int snapshot_output_init_with_uri(const struct ltt_session *session,
-                                 uint64_t max_size,
-                                 const char *name,
-                                 struct lttng_uri *uris,
-                                 size_t nb_uri,
-                                 struct consumer_output *consumer,
-                                 struct snapshot_output *output,
-                                 struct snapshot *snapshot);
+
 struct snapshot_output *snapshot_find_output_by_id(uint32_t id, struct snapshot *snapshot);
 struct snapshot_output *snapshot_find_output_by_name(const char *name, struct snapshot *snapshot);
 
index 838983e3baa2d26a5b8c554a0a05e9d4ffe4449f..b70d648499c7e8744a07443355fd5f5a62e18b99 100644 (file)
@@ -199,15 +199,16 @@ end:
        return ret;
 }
 
-int timer_session_rotation_pending_check_start(struct ltt_session *session,
+int timer_session_rotation_pending_check_start(const ltt_session::locked_ref& session,
                                               unsigned int interval_us)
 {
        int ret;
 
-       if (!session_get(session)) {
+       if (!session_get(&session.get())) {
                ret = -1;
                goto end;
        }
+
        DBG("Enabling session rotation pending check timer on session %" PRIu64, session->id);
        /*
         * We arm this timer in a one-shot mode so we don't have to disable it
@@ -219,7 +220,7 @@ int timer_session_rotation_pending_check_start(struct ltt_session *session,
         * no need to go through the whole signal teardown scheme everytime.
         */
        ret = timer_start(&session->rotation_pending_check_timer,
-                         session,
+                         &session.get(),
                          interval_us,
                          LTTNG_SESSIOND_SIG_PENDING_ROTATION_CHECK,
                          /* one-shot */ true);
@@ -231,39 +232,39 @@ end:
 }
 
 /*
- * Call with session and session_list locks held.
+ * Call with session_list lock held.
  */
-int timer_session_rotation_pending_check_stop(ltt_session& session)
+int timer_session_rotation_pending_check_stop(const ltt_session::locked_ref& session)
 {
        int ret;
 
-       LTTNG_ASSERT(session.rotation_pending_check_timer_enabled);
+       LTTNG_ASSERT(session->rotation_pending_check_timer_enabled);
 
-       DBG("Disabling session rotation pending check timer on session %" PRIu64, session.id);
-       ret = timer_stop(&session.rotation_pending_check_timer,
+       DBG("Disabling session rotation pending check timer on session %" PRIu64, session->id);
+       ret = timer_stop(&session->rotation_pending_check_timer,
                         LTTNG_SESSIOND_SIG_PENDING_ROTATION_CHECK);
        if (ret == -1) {
                ERR("Failed to stop rotate_pending_check timer");
        } else {
-               session.rotation_pending_check_timer_enabled = false;
+               session->rotation_pending_check_timer_enabled = false;
                /*
                 * The timer's reference to the session can be released safely.
                 */
-               session_put(&session);
+               session_put(&session.get());
        }
 
        return ret;
 }
 
 /*
- * Call with session and session_list locks held.
+ * Call with session_list lock held.
  */
-int timer_session_rotation_schedule_timer_start(struct ltt_session *session,
+int timer_session_rotation_schedule_timer_start(const ltt_session::locked_ref& session,
                                                unsigned int interval_us)
 {
        int ret;
 
-       if (!session_get(session)) {
+       if (!session_get(&session.get())) {
                ret = -1;
                goto end;
        }
@@ -272,7 +273,7 @@ int timer_session_rotation_schedule_timer_start(struct ltt_session *session,
            interval_us,
            USEC_UNIT);
        ret = timer_start(&session->rotation_schedule_timer,
-                         session,
+                         &session.get(),
                          interval_us,
                          LTTNG_SESSIOND_SIG_SCHEDULED_ROTATION,
                          /* one-shot */ false);
@@ -287,12 +288,10 @@ end:
 /*
  * Call with session and session_list locks held.
  */
-int timer_session_rotation_schedule_timer_stop(struct ltt_session *session)
+int timer_session_rotation_schedule_timer_stop(const ltt_session::locked_ref& session)
 {
        int ret = 0;
 
-       LTTNG_ASSERT(session);
-
        if (!session->rotation_schedule_timer_enabled) {
                goto end;
        }
@@ -306,7 +305,7 @@ int timer_session_rotation_schedule_timer_stop(struct ltt_session *session)
 
        session->rotation_schedule_timer_enabled = false;
        /* The timer's reference to the session can be released safely. */
-       session_put(session);
+       session_put(&session.get());
        ret = 0;
 end:
        return ret;
index c291ae6d250db28adf56ae21b079391b683f7a95..7a5cc02321bafc4c49924a98b838238033b44fc5 100644 (file)
@@ -22,16 +22,16 @@ struct timer_thread_parameters {
 int timer_signal_init();
 
 /* Start a session's rotation pending check timer (one-shot mode). */
-int timer_session_rotation_pending_check_start(struct ltt_session *session,
+int timer_session_rotation_pending_check_start(const ltt_session::locked_ref& session,
                                               unsigned int interval_us);
 /* Stop a session's rotation pending check timer. */
-int timer_session_rotation_pending_check_stop(ltt_session& session);
+int timer_session_rotation_pending_check_stop(const ltt_session::locked_ref& session);
 
 /* Start a session's rotation schedule timer. */
-int timer_session_rotation_schedule_timer_start(struct ltt_session *session,
+int timer_session_rotation_schedule_timer_start(const ltt_session::locked_ref& session,
                                                unsigned int interval_us);
 /* Stop a session's rotation schedule timer. */
-int timer_session_rotation_schedule_timer_stop(struct ltt_session *session);
+int timer_session_rotation_schedule_timer_stop(const ltt_session::locked_ref& session);
 
 bool launch_timer_thread(struct timer_thread_parameters *timer_thread_parameters);
 
index 2439d1e99c4572a2d10284aec9553637907a9cd9..8f0375bc5c5f2d5e6d969ccd8f191f4bc305dbf3 100644 (file)
@@ -505,49 +505,49 @@ static void save_per_pid_lost_discarded_counters(struct ust_app_channel *ua_chan
 
        lttng::urcu::read_lock_guard read_lock;
 
-       ltt_session::ref session;
        try {
-               session = ltt_session::find_session(ua_chan->session->tracing_id);
+               const auto session = ltt_session::find_session(ua_chan->session->tracing_id);
+
+               if (!session->ust_session) {
+                       /*
+                        * Not finding the session is not an error because there are
+                        * multiple ways the channels can be torn down.
+                        *
+                        * 1) The session daemon can initiate the destruction of the
+                        *    ust app session after receiving a destroy command or
+                        *    during its shutdown/teardown.
+                        * 2) The application, since we are in per-pid tracing, is
+                        *    unregistering and tearing down its ust app session.
+                        *
+                        * Both paths are protected by the session list lock which
+                        * ensures that the accounting of lost packets and discarded
+                        * events is done exactly once. The session is then unpublished
+                        * from the session list, resulting in this condition.
+                        */
+                       return;
+               }
+
+               if (ua_chan->attr.overwrite) {
+                       consumer_get_lost_packets(ua_chan->session->tracing_id,
+                                                 ua_chan->key,
+                                                 session->ust_session->consumer,
+                                                 &lost);
+               } else {
+                       consumer_get_discarded_events(ua_chan->session->tracing_id,
+                                                     ua_chan->key,
+                                                     session->ust_session->consumer,
+                                                     &discarded);
+               }
+               uchan = trace_ust_find_channel_by_name(session->ust_session->domain_global.channels,
+                                                      ua_chan->name);
+               if (!uchan) {
+                       ERR("Missing UST channel to store discarded counters");
+                       return;
+               }
        } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
                DBG_FMT("Failed to save per-pid lost/discarded counters: {}, location='{}'",
                        ex.what(),
                        ex.source_location);
-       }
-
-       if (!session || !session->ust_session) {
-               /*
-                * Not finding the session is not an error because there are
-                * multiple ways the channels can be torn down.
-                *
-                * 1) The session daemon can initiate the destruction of the
-                *    ust app session after receiving a destroy command or
-                *    during its shutdown/teardown.
-                * 2) The application, since we are in per-pid tracing, is
-                *    unregistering and tearing down its ust app session.
-                *
-                * Both paths are protected by the session list lock which
-                * ensures that the accounting of lost packets and discarded
-                * events is done exactly once. The session is then unpublished
-                * from the session list, resulting in this condition.
-                */
-               return;
-       }
-
-       if (ua_chan->attr.overwrite) {
-               consumer_get_lost_packets(ua_chan->session->tracing_id,
-                                         ua_chan->key,
-                                         session->ust_session->consumer,
-                                         &lost);
-       } else {
-               consumer_get_discarded_events(ua_chan->session->tracing_id,
-                                             ua_chan->key,
-                                             session->ust_session->consumer,
-                                             &discarded);
-       }
-       uchan = trace_ust_find_channel_by_name(session->ust_session->domain_global.channels,
-                                              ua_chan->name);
-       if (!uchan) {
-               ERR("Missing UST channel to store discarded counters");
                return;
        }
 
@@ -3446,7 +3446,6 @@ static int create_channel_per_uid(struct ust_app *app,
        int ret;
        struct buffer_reg_uid *reg_uid;
        struct buffer_reg_channel *buf_reg_chan;
-       ltt_session::ref session;
        enum lttng_error_code notification_ret;
 
        LTTNG_ASSERT(app);
@@ -3457,6 +3456,10 @@ static int create_channel_per_uid(struct ust_app *app,
 
        DBG("UST app creating channel %s with per UID buffers", ua_chan->name);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_SESSION_LIST_LOCKED();
+
        reg_uid = buffer_reg_uid_find(usess->id, app->abi.bits_per_long, app->uid);
        /*
         * The session creation handles the creation of this global registry
@@ -3477,11 +3480,6 @@ static int create_channel_per_uid(struct ust_app *app,
                goto error;
        }
 
-       /* Guaranteed to exist; will not throw. */
-       session = ltt_session::find_session(ua_sess->tracing_id);
-       ASSERT_LOCKED(session->_lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /*
         * Create the buffers on the consumer side. This call populates the
         * ust app channel object with all streams and data object.
@@ -3566,7 +3564,6 @@ static int create_channel_per_pid(struct ust_app *app,
        int ret;
        lsu::registry_session *registry;
        enum lttng_error_code cmd_ret;
-       ltt_session::ref session;
        uint64_t chan_reg_key;
 
        LTTNG_ASSERT(app);
@@ -3582,6 +3579,11 @@ static int create_channel_per_pid(struct ust_app *app,
        /* The UST app session lock is held, registry shall not be null. */
        LTTNG_ASSERT(registry);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_LOCKED(session->_lock);
+       ASSERT_SESSION_LIST_LOCKED();
+
        /* Create and add a new channel registry to session. */
        try {
                registry->add_channel(ua_chan->key);
@@ -3593,11 +3595,6 @@ static int create_channel_per_pid(struct ust_app *app,
                goto error;
        }
 
-       /* Guaranteed to exist; will not throw. */
-       session = ltt_session::find_session(ua_sess->tracing_id);
-       ASSERT_LOCKED(session->_lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /* Create and get channel on the consumer side. */
        ret = do_consumer_create_channel(usess, ua_sess, ua_chan, app->abi.bits_per_long, registry);
        if (ret < 0) {
@@ -3890,7 +3887,6 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        int ret = 0;
        struct ust_app_channel *metadata;
        struct consumer_socket *socket;
-       ltt_session::ref session;
 
        LTTNG_ASSERT(ua_sess);
        LTTNG_ASSERT(app);
@@ -3901,6 +3897,11 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
        /* The UST app session is held registry shall not be null. */
        LTTNG_ASSERT(locked_registry);
 
+       /* Guaranteed to exist; will not throw. */
+       const auto session = ltt_session::find_session(ua_sess->tracing_id);
+       ASSERT_LOCKED(session->_lock);
+       ASSERT_SESSION_LIST_LOCKED();
+
        /* Metadata already exists for this registry or it was closed previously */
        if (locked_registry->_metadata_key || locked_registry->_metadata_closed) {
                ret = 0;
@@ -3939,11 +3940,6 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
         */
        locked_registry->_metadata_key = metadata->key;
 
-       /* Guaranteed to exist; will not throw. */
-       session = ltt_session::find_session(ua_sess->tracing_id);
-       ASSERT_LOCKED(session->_lock);
-       ASSERT_SESSION_LIST_LOCKED();
-
        /*
         * Ask the metadata channel creation to the consumer. The metadata object
         * will be created by the consumer and kept their. However, the stream is
@@ -7560,7 +7556,7 @@ int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
+enum lttng_error_code ust_app_rotate_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code cmd_ret = LTTNG_OK;
@@ -7821,7 +7817,7 @@ error:
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
+enum lttng_error_code ust_app_clear_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code cmd_ret = LTTNG_OK;
@@ -7984,7 +7980,7 @@ end:
  * daemon as the same "offset" in a metadata stream will no longer point
  * to the same content.
  */
-enum lttng_error_code ust_app_open_packets(struct ltt_session *session)
+enum lttng_error_code ust_app_open_packets(const ltt_session::locked_ref& session)
 {
        enum lttng_error_code ret = LTTNG_OK;
        struct lttng_ht_iter iter;
index 7a3f875915659833d22d6b2eb2795ed4292ad93a..f292753c09f7495b72e11809992ba63a7b6aaa50 100644 (file)
@@ -426,11 +426,11 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                                          uint64_t *discarded,
                                          uint64_t *lost);
 int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess);
-enum lttng_error_code ust_app_rotate_session(struct ltt_session *session);
+enum lttng_error_code ust_app_rotate_session(const ltt_session::locked_ref& session);
 enum lttng_error_code ust_app_create_channel_subdirectories(const struct ltt_ust_session *session);
 int ust_app_release_object(struct ust_app *app, struct lttng_ust_abi_object_data *data);
-enum lttng_error_code ust_app_clear_session(struct ltt_session *session);
-enum lttng_error_code ust_app_open_packets(struct ltt_session *session);
+enum lttng_error_code ust_app_clear_session(const ltt_session::locked_ref& session);
+enum lttng_error_code ust_app_open_packets(const ltt_session::locked_ref& session);
 
 int ust_app_setup_event_notifier_group(struct ust_app *app);
 
@@ -705,7 +705,7 @@ static inline int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess
        return 0;
 }
 
-static inline enum lttng_error_code ust_app_rotate_session(struct ltt_session *session
+static inline enum lttng_error_code ust_app_rotate_session(const ltt_session::locked_ref& session
                                                           __attribute__((unused)))
 {
        return LTTNG_ERR_UNK;
@@ -724,13 +724,13 @@ static inline int ust_app_release_object(struct ust_app *app __attribute__((unus
        return 0;
 }
 
-static inline enum lttng_error_code ust_app_clear_session(struct ltt_session *session
+static inline enum lttng_error_code ust_app_clear_session(const ltt_session::locked_ref& session
                                                          __attribute__((unused)))
 {
        return LTTNG_ERR_UNK;
 }
 
-static inline enum lttng_error_code ust_app_open_packets(struct ltt_session *session
+static inline enum lttng_error_code ust_app_open_packets(const ltt_session::locked_ref& session
                                                         __attribute__((unused)))
 {
        return LTTNG_ERR_UNK;
index b4d3c00a498b2644d34c7b7bccdf9a26d1ee2938..6960e60664d05cf4b947d1a588bceeca1d82bebb 100644 (file)
@@ -64,7 +64,7 @@ int loglevels_match(int a_loglevel_type,
        return match;
 }
 
-const char *session_get_base_path(const struct ltt_session *session)
+const char *session_get_base_path(const ltt_session::locked_ref& session)
 {
        return consumer_output_get_base_path(session->consumer);
 }
index 83117f426f46dff1b606e2bf7ef12c5876a98553..2f9bf8e62d302fca85ab449d0c56e3872482de95 100644 (file)
@@ -8,8 +8,9 @@
 #ifndef _LTT_UTILS_H
 #define _LTT_UTILS_H
 
+#include "session.hpp"
+
 struct lttng_ht;
-struct ltt_session;
 struct consumer_output;
 
 const char *get_home_dir();
@@ -19,7 +20,7 @@ int loglevels_match(int a_loglevel_type,
                    int b_loglevel_type,
                    int b_loglevel_value,
                    int loglevel_all_type);
-const char *session_get_base_path(const struct ltt_session *session);
+const char *session_get_base_path(const ltt_session::locked_ref& session);
 const char *consumer_output_get_base_path(const struct consumer_output *output);
 
 #endif /* _LTT_UTILS_H */
index 2a2db974a73663a6c1d4fda8e674833d83764e96..799e9be2205e994ffb054f8285935d31b1419524 100644 (file)
 
 #include <sstream>
 
-lttng::cli::no_default_session_error::no_default_session_error(const lttng::source_location &location) :
+lttng::cli::no_default_session_error::no_default_session_error(
+       const lttng::source_location& location) :
        runtime_error(fmt::format("No default session found in `{}/.lttngrc`",
-                                   utils_get_home_dir() ?: "LTTNG_HOME"),
+                                 utils_get_home_dir() ?: "LTTNG_HOME"),
                      location)
 {
 }
index 3b24d2e887fadf7112533985b37d02578178ce51..f384e3d28ce281fb0da54d23b851885b18d7b340 100644 (file)
@@ -15,9 +15,8 @@
 #include <stdexcept>
 #include <string>
 
-#define LTTNG_THROW_CLI_NO_DEFAULT_SESSION()        \
-       throw lttng::cli::no_default_session_error( \
-               LTTNG_SOURCE_LOCATION())
+#define LTTNG_THROW_CLI_NO_DEFAULT_SESSION() \
+       throw lttng::cli::no_default_session_error(LTTNG_SOURCE_LOCATION())
 
 namespace lttng {
 namespace cli {
index 8170e6e5add57dc5c66e459b9612e2bbbb2a2c4a..257347ce2ff2dc278329038164b0821891b6adcb 100644 (file)
@@ -99,6 +99,7 @@ libcommon_lgpl_la_SOURCES = \
        log-level-rule.cpp \
        make-unique.hpp \
        make-unique-wrapper.hpp \
+       meta-helpers.hpp \
        mi-lttng.cpp mi-lttng.hpp \
        notification.cpp \
        payload.cpp payload.hpp \
@@ -106,6 +107,7 @@ libcommon_lgpl_la_SOURCES = \
        pthread-lock.hpp \
        random.cpp random.hpp \
        readwrite.cpp readwrite.hpp \
+       reference.hpp \
        runas.cpp runas.hpp \
        scope-exit.hpp \
        session-descriptor.cpp \
index 50520c55cfd177eff7e8116f500b91438550ae54..4375f815931910f4a5bc9a919db8e89875c30c27 100644 (file)
@@ -21,8 +21,7 @@ lttng::ctl::error::error(const std::string& msg,
 lttng::posix_error::posix_error(const std::string& msg,
                                unsigned int errno_code,
                                const lttng::source_location& location) :
-       std::system_error(errno_code, std::generic_category()),
-       lttng::runtime_error(msg, location)
+       std::system_error(errno_code, std::generic_category()), lttng::runtime_error(msg, location)
 {
 }
 
@@ -33,8 +32,8 @@ lttng::runtime_error::runtime_error(const std::string& msg,
 }
 
 lttng::allocation_failure::allocation_failure(const std::string& msg,
-std::size_t allocation_size_,
-                                           const lttng::source_location& location) :
+                                             std::size_t allocation_size_,
+                                             const lttng::source_location& location) :
        lttng::runtime_error(msg, location), allocation_size(allocation_size_)
 {
 }
index a0a4b541a2fd64bc7c01da8babd6b5c01bb54d5c..bfb5d6bb27bc4537e4a4e3c6d35d4c38f4316797 100644 (file)
@@ -9,6 +9,7 @@
 #define LTTNG_MAKE_UNIQUE_WRAPPER_H
 
 #include <common/macros.hpp>
+#include <common/meta-helpers.hpp>
 
 #include <memory>
 
@@ -39,21 +40,6 @@ namespace lttng {
  */
 
 namespace memory {
-template <typename WrappedType, void (*DeleterFunction)(WrappedType *)>
-struct create_deleter_class {
-       struct deleter {
-               void operator()(WrappedType *instance) const
-               {
-                       DeleterFunction(instance);
-               }
-       };
-
-       std::unique_ptr<WrappedType, deleter> operator()(WrappedType *instance) const
-       {
-               return std::unique_ptr<WrappedType, deleter>(instance);
-       }
-};
-
 /*
  * 'free' is a utility function for use with make_unique_wrapper. It makes it easier to
  * wrap raw pointers that have to be deleted with `free`. Using libc's 'free' as
diff --git a/src/common/meta-helpers.hpp b/src/common/meta-helpers.hpp
new file mode 100644 (file)
index 0000000..20000a1
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_META_HELPERS_HPP
+#define LTTNG_META_HELPERS_HPP
+
+#include <memory>
+
+/*
+ * Collection of meta-programming helpers.
+ *
+ * @see type-traits.hpp
+ */
+namespace lttng {
+namespace memory {
+template <typename WrappedType, void (*DeleterFunction)(WrappedType *)>
+struct create_deleter_class {
+       struct deleter {
+               void operator()(WrappedType *instance) const
+               {
+                       DeleterFunction(instance);
+               }
+       };
+
+       std::unique_ptr<WrappedType, deleter> operator()(WrappedType *instance) const
+       {
+               return std::unique_ptr<WrappedType, deleter>(instance);
+       }
+};
+} /* namespace memory */
+} /* namespace lttng */
+
+#endif /* LTTNG_META_HELPERS_HPP */
diff --git a/src/common/reference.hpp b/src/common/reference.hpp
new file mode 100644 (file)
index 0000000..ccf5f4e
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_REFERENCE_H
+#define LTTNG_REFERENCE_H
+
+#include <algorithm>
+#include <utility>
+
+namespace lttng {
+
+template <typename ReferencedType, typename CustomDeleter>
+class non_copyable_reference {
+public:
+       explicit non_copyable_reference(ReferencedType& instance) noexcept : _value(&instance)
+       {
+       }
+
+       non_copyable_reference(non_copyable_reference&& other) noexcept : _value(other._value)
+       {
+               other._value = nullptr;
+       }
+
+       non_copyable_reference() = delete;
+       non_copyable_reference(const non_copyable_reference&) = delete;
+       non_copyable_reference& operator=(non_copyable_reference&&) = delete;
+       non_copyable_reference& operator=(const non_copyable_reference&) = delete;
+
+       ReferencedType& get() const noexcept
+       {
+               return *_value;
+       }
+
+       ReferencedType *operator->() const noexcept
+       {
+               return _value;
+       }
+
+       ReferencedType& operator*() const noexcept
+       {
+               return *_value;
+       }
+
+       ~non_copyable_reference()
+       {
+               if (!_value) {
+                       return;
+               }
+
+               typename CustomDeleter::deleter del;
+               del(_value);
+       }
+
+private:
+       ReferencedType *_value = nullptr;
+};
+
+} /* namespace lttng */
+
+#endif /* LTTNG_REFERENCE_H */
index af98c7b7e9e7293337110404d1ff493208db9f88..f972c44bbb18e723667c2bb493d697f8b6e3b3e6 100644 (file)
@@ -133,7 +133,7 @@ static int create_one_session(const char *name)
 /*
  * Test deletion of 1 session
  */
-static int destroy_one_session(struct ltt_session *session)
+static int destroy_one_session(ltt_session::ref session)
 {
        int ret;
        char session_name[NAME_MAX];
@@ -141,8 +141,14 @@ static int destroy_one_session(struct ltt_session *session)
        strncpy(session_name, session->name, sizeof(session_name));
        session_name[sizeof(session_name) - 1] = '\0';
 
-       session_destroy(session);
-       session_put(session);
+       /* Reference of the session list. */
+       ltt_session *weak_session_ptr = &session.get();
+       {
+               /* Drop the reference that stems from the look-up. */
+               const ltt_session::ref reference_to_drop = std::move(session);
+       }
+
+       session_destroy(weak_session_ptr);
 
        ret = find_session_name(session_name);
        if (ret < 0) {
@@ -207,25 +213,20 @@ static void test_validate_session()
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::ref session;
 
        try {
-               session = ltt_session::find_session(SESSION1);
-       } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
-       }
-
-       ok(session, "Validating session: session found");
+               const auto session = ltt_session::find_session(SESSION1);
+               pass("Validating session: session found");
 
-       if (session) {
                ok(session->kernel_session == nullptr && strlen(session->name),
                   "Validating session: basic sanity check");
-       } else {
+
+               session->lock();
+               session->unlock();
+       } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
+               fail("Validating session: session found");
                skip(1, "Skipping session validation check as session was not found");
-               return;
        }
-
-       session->lock();
-       session->unlock();
 }
 
 static void test_destroy_session()
@@ -238,20 +239,18 @@ static void test_destroy_session()
         * sessions.
         */
        const auto list_lock = lttng::sessiond::lock_session_list();
-       ltt_session::ref session;
 
        try {
-               session = ltt_session::find_session(SESSION1);
-       } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
-       }
+               auto session = ltt_session::find_session(SESSION1);
 
-       ok(session, "Destroying session: session found");
+               pass("Destroying session: session found");
 
-       if (session) {
-               ok(destroy_one_session(session.release()) == 0,
+               ok(destroy_one_session(std::move(session)) == 0,
                   "Destroying session: %s destroyed",
                   SESSION1);
-       } else {
+
+       } catch (const lttng::sessiond::exceptions::session_not_found_error& ex) {
+               fail("Destroying session: session found");
                skip(1, "Skipping session destruction as it was not found");
        }
 }
@@ -307,8 +306,11 @@ static void test_large_session_number()
        const auto list_lock = lttng::sessiond::lock_session_list();
        for (i = 0; i < MAX_SESSIONS; i++) {
                cds_list_for_each_entry_safe (iter, tmp, &session_list->head, list) {
-                       LTTNG_ASSERT(session_get(iter));
-                       ret = destroy_one_session(iter);
+                       ret = destroy_one_session([iter]() {
+                               session_get(iter);
+                               return ltt_session::ref(*iter);
+                       }());
+
                        if (ret < 0) {
                                diag("session %d destroy failed", i);
                                ++failed;
This page took 0.091945 seconds and 4 git commands to generate.