Add lttng_trace_format::sptr to ltt_session
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.cpp
index fe9656a89b8b59e1585f7693c3ca7db9cd3bf7ee..d5f46188895fa7e7af29d18dddb855677938a274 100644 (file)
@@ -9,6 +9,7 @@
 
 #define _LGPL_SOURCE
 #include <algorithm>
+#include <exception>
 #include <inttypes.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -2751,7 +2752,7 @@ int cmd_start_trace(struct ltt_session *session)
                goto error;
        }
 
-       session->active = 1;
+       session->active = true;
        session->rotated_after_last_stop = false;
        session->cleared_after_last_stop = false;
        if (session->output_traces && !session->current_trace_chunk) {
@@ -2846,9 +2847,9 @@ int cmd_start_trace(struct ltt_session *session)
 error:
        if (ret == LTTNG_OK) {
                /* Flag this after a successful start. */
-               session->has_been_started |= 1;
+               session->has_been_started = true;
        } else {
-               session->active = 0;
+               session->active = false;
                /* Restore initial state on error. */
                session->rotated_after_last_stop =
                                session_rotated_after_last_stop;
@@ -3107,6 +3108,8 @@ enum lttng_error_code cmd_create_session_from_descriptor(
        const char *session_name;
        struct ltt_session *new_session = NULL;
        enum lttng_session_descriptor_status descriptor_status;
+       const lttng_trace_format_descriptor *trace_format_descriptor = NULL;
+       lttng::trace_format_descriptor::uptr trace_format_descriptor_ptr;
 
        session_lock_list();
        if (home_path) {
@@ -3130,12 +3133,52 @@ enum lttng_error_code cmd_create_session_from_descriptor(
                goto end;
        }
 
-       ret_code = session_create(session_name, creds->uid, creds->gid,
+       descriptor_status = lttng_session_descriptor_get_trace_format_descriptor(
+                       descriptor, &trace_format_descriptor);
+       if (descriptor_status != LTTNG_SESSION_DESCRIPTOR_STATUS_OK) {
+               ret_code = LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       try {
+               trace_format_descriptor_ptr =
+                               reinterpret_cast<const lttng::trace_format_descriptor *>(
+                                               trace_format_descriptor)
+                                               ->clone();
+       } catch (std::exception& e) {
+               ERR("%s", e.what());
+               ret_code = LTTNG_ERR_UNK;
+               goto end;
+       }
+
+       ret_code = session_create(session_name, creds->uid, creds->gid, trace_format_descriptor_ptr,
                        &new_session);
        if (ret_code != LTTNG_OK) {
                goto end;
        }
 
+       ret_code = notification_thread_command_add_session(the_notification_thread_handle,
+                       new_session->id, new_session->name, new_session->uid, new_session->gid);
+       if (ret_code != LTTNG_OK) {
+               goto end;
+       }
+
+       /* Announce the session's destruction to the notification thread when it is destroyed. */
+       ret = session_add_destroy_notifier(
+                       new_session,
+                       [](const struct ltt_session *session,
+                                       void *user_data __attribute__((unused))) {
+                               (void) notification_thread_command_remove_session(
+                                               the_notification_thread_handle, session->id);
+                       },
+                       NULL);
+       if (ret) {
+               PERROR("Failed to add notification thread command to session's destroy notifiers: session name = %s",
+                               new_session->name);
+               ret = LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
        if (!session_name) {
                ret = lttng_session_descriptor_set_session_name(descriptor,
                                new_session->name);
@@ -3924,23 +3967,38 @@ end:
  * The session list lock MUST be acquired before calling this function. Use
  * session_lock_list() and session_unlock_list().
  */
-void cmd_list_lttng_sessions(struct lttng_session *sessions,
-               size_t session_count, uid_t uid, gid_t gid)
+enum lttng_error_code cmd_list_lttng_sessions(
+               struct lttng_payload *reply_payload, uid_t uid, gid_t gid)
 {
-       int ret;
-       unsigned int i = 0;
+       int buffer_resize_ret;
+       enum lttng_error_code ret_code = LTTNG_OK;
+       struct lttcomm_list_command_header reply_command_header = {};
+       size_t reply_command_header_offset;
        struct ltt_session *session;
        struct ltt_session_list *list = session_get_list();
-       struct lttng_session_extended *extended =
-                       (typeof(extended)) (&sessions[session_count]);
+       int ret;
+       unsigned int i = 0;
+
+       assert(reply_payload);
+
+       /* Reserve space for command reply header. */
+       reply_command_header_offset = reply_payload->buffer.size;
+       buffer_resize_ret = lttng_dynamic_buffer_set_size(&reply_payload->buffer,
+                       reply_command_header_offset + sizeof(struct lttcomm_list_command_header));
+       if (buffer_resize_ret) {
+               ret_code = LTTNG_ERR_NOMEM;
+               goto error;
+       }
 
        DBG("Getting all available session for UID %d GID %d",
                        uid, gid);
-       /*
-        * Iterate over session list and append data after the control struct in
-        * the buffer.
-        */
+
        cds_list_for_each_entry(session, &list->head, list) {
+               struct lttng_session tmp_session = {};
+               struct lttng_session_extended tmp_extended = {};
+
+               tmp_session.extended.ptr = &tmp_extended;
+
                if (!session_get(session)) {
                        continue;
                }
@@ -3959,10 +4017,10 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
                if (session->consumer->type == CONSUMER_DST_NET ||
                                (ksess && ksess->consumer->type == CONSUMER_DST_NET) ||
                                (usess && usess->consumer->type == CONSUMER_DST_NET)) {
-                       ret = build_network_session_path(sessions[i].path,
-                                       sizeof(sessions[i].path), session);
+                       ret = build_network_session_path(
+                                       tmp_session.path, sizeof(tmp_session.path), session);
                } else {
-                       ret = snprintf(sessions[i].path, sizeof(sessions[i].path), "%s",
+                       ret = snprintf(tmp_session.path, sizeof(tmp_session.path), "%s",
                                        session->consumer->dst.session_root_path);
                }
                if (ret < 0) {
@@ -3971,16 +4029,33 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions,
                        continue;
                }
 
-               strncpy(sessions[i].name, session->name, NAME_MAX);
-               sessions[i].name[NAME_MAX - 1] = '\0';
-               sessions[i].enabled = session->active;
-               sessions[i].snapshot_mode = session->snapshot_mode;
-               sessions[i].live_timer_interval = session->live_timer;
-               extended[i].creation_time.value = (uint64_t) session->creation_time;
-               extended[i].creation_time.is_set = 1;
+               strncpy(tmp_session.name, session->name, NAME_MAX);
+               tmp_session.name[NAME_MAX - 1] = '\0';
+               tmp_session.enabled = session->active;
+               tmp_session.snapshot_mode = session->snapshot_mode;
+               tmp_session.live_timer_interval = session->live_timer;
+               LTTNG_OPTIONAL_SET(&tmp_extended.creation_time, (uint64_t) session->creation_time);
+               ret = lttng_session_serialize(&tmp_session, reply_payload);
+               if (ret) {
+                       ret_code = LTTNG_ERR_FATAL;
+                       goto error;
+               }
                i++;
                session_put(session);
        }
+
+       if (i > UINT32_MAX) {
+               ret_code = LTTNG_ERR_OVERFLOW;
+               goto error;
+       }
+
+       /* Update command reply header. */
+       reply_command_header.count = (uint32_t) i;
+       memcpy(reply_payload->buffer.data + reply_command_header_offset, &reply_command_header,
+                       sizeof(reply_command_header));
+       ret_code = LTTNG_OK;
+error:
+       return ret_code;
 }
 
 /*
@@ -5609,8 +5684,7 @@ int cmd_rotate_session(struct ltt_session *session,
        chunk_being_archived = NULL;
        if (!quiet_rotation) {
                ret = notification_thread_command_session_rotation_ongoing(
-                               the_notification_thread_handle, session->name,
-                               session->uid, session->gid,
+                               the_notification_thread_handle, session->id,
                                ongoing_rotation_chunk_id);
                if (ret != LTTNG_OK) {
                        ERR("Failed to notify notification thread that a session rotation is ongoing for session %s",
This page took 0.028853 seconds and 5 git commands to generate.