#define _LGPL_SOURCE
#include <algorithm>
+#include <exception>
#include <inttypes.h>
#include <stdio.h>
#include <sys/stat.h>
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) {
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;
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) {
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);
* 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;
}
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) {
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;
}
/*
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",