#include <common/utils.h>
#include <lttng/userspace-probe-internal.h>
#include <lttng/event-internal.h>
+#include <lttng/session-internal.h>
+#include <lttng/session-descriptor-internal.h>
#include "client.h"
#include "lttng-sessiond.h"
static bool is_root;
static struct thread_state {
- pthread_cond_t cond;
- pthread_mutex_t lock;
- bool is_running;
-} thread_state = {
- .cond = PTHREAD_COND_INITIALIZER,
- .lock = PTHREAD_MUTEX_INITIALIZER,
- .is_running = false
-};
-
-void set_thread_state_running(void)
+ sem_t ready;
+ bool running;
+} thread_state;
+
+static void set_thread_status(bool running)
{
- pthread_mutex_lock(&thread_state.lock);
- thread_state.is_running = true;
- pthread_cond_broadcast(&thread_state.cond);
- pthread_mutex_unlock(&thread_state.lock);
+ DBG("Marking client thread's state as %s", running ? "running" : "error");
+ thread_state.running = running;
+ sem_post(&thread_state.ready);
}
-static void wait_thread_state_running(void)
+static bool wait_thread_status(void)
{
- pthread_mutex_lock(&thread_state.lock);
- while (!thread_state.is_running) {
- pthread_cond_wait(&thread_state.cond,
- &thread_state.lock);
+ DBG("Waiting for client thread to be ready");
+ sem_wait(&thread_state.ready);
+ if (thread_state.running) {
+ DBG("Client thread is ready");
+ } else {
+ ERR("Initialization of client thread failed");
}
- pthread_mutex_unlock(&thread_state.lock);
+
+ return thread_state.running;
}
/*
const size_t payload_offset = cmd_header_offset + cmd_header_len;
const size_t total_msg_size = header_len + cmd_header_len + payload_len;
+ free(cmd_ctx->llm);
cmd_ctx->llm = zmalloc(total_msg_size);
if (cmd_ctx->llm == NULL) {
}
/* Append correct directory to subdir */
- strncat(consumer->subdir, dir_name,
- sizeof(consumer->subdir) - strlen(consumer->subdir) - 1);
- DBG3("Copy session consumer subdir %s", consumer->subdir);
-
+ ret = lttng_strncpy(consumer->domain_subdir, dir_name,
+ sizeof(consumer->domain_subdir));
+ if (ret) {
+ ret = LTTNG_ERR_UNK;
+ goto error;
+ }
+ DBG3("Copy session consumer subdir %s", consumer->domain_subdir);
ret = LTTNG_OK;
error:
ret = kernel_create_session(session, kernel_tracer_fd);
if (ret < 0) {
ret = LTTNG_ERR_KERN_SESS_FAIL;
- goto error;
+ goto error_create;
}
/* Code flow safety */
error:
trace_kernel_destroy_session(session->kernel_session);
session->kernel_session = NULL;
+error_create:
return ret;
}
*sock_error = 0;
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_CREATE_SESSION:
- case LTTNG_CREATE_SESSION_SNAPSHOT:
- case LTTNG_CREATE_SESSION_LIVE:
+ case LTTNG_CREATE_SESSION_EXT:
case LTTNG_DESTROY_SESSION:
case LTTNG_LIST_SESSIONS:
case LTTNG_LIST_DOMAINS:
/* Commands that DO NOT need a session. */
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_CREATE_SESSION:
- case LTTNG_CREATE_SESSION_SNAPSHOT:
- case LTTNG_CREATE_SESSION_LIVE:
+ case LTTNG_CREATE_SESSION_EXT:
case LTTNG_LIST_SESSIONS:
case LTTNG_LIST_TRACEPOINTS:
case LTTNG_LIST_SYSCALLS:
if (need_tracing_session) {
if (cmd_ctx->session->kernel_session == NULL) {
ret = create_kernel_session(cmd_ctx->session);
- if (ret < 0) {
+ if (ret != LTTNG_OK) {
ret = LTTNG_ERR_KERN_SESS_FAIL;
goto error;
}
ret = cmd_stop_trace(cmd_ctx->session);
break;
}
- case LTTNG_CREATE_SESSION:
- {
- size_t nb_uri, len;
- struct lttng_uri *uris = NULL;
-
- nb_uri = cmd_ctx->lsm->u.uri.size;
- len = nb_uri * sizeof(struct lttng_uri);
-
- if (nb_uri > 0) {
- uris = zmalloc(len);
- if (uris == NULL) {
- ret = LTTNG_ERR_FATAL;
- goto error;
- }
-
- /* Receive variable len data */
- DBG("Waiting for %zu URIs from client ...", nb_uri);
- ret = lttcomm_recv_unix_sock(sock, uris, len);
- if (ret <= 0) {
- DBG("No URIs received from client... continuing");
- *sock_error = 1;
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
-
- if (nb_uri == 1 && uris[0].dtype != LTTNG_DST_PATH) {
- DBG("Creating session with ONE network URI is a bad call");
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
- }
-
- ret = cmd_create_session_uri(cmd_ctx->lsm->session.name, uris, nb_uri,
- &cmd_ctx->creds, 0);
-
- free(uris);
-
- break;
- }
case LTTNG_DESTROY_SESSION:
{
ret = cmd_destroy_session(cmd_ctx->session,
nr_sessions = lttng_sessions_count(
LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
- payload_len = sizeof(struct lttng_session) * nr_sessions;
+
+ payload_len = (sizeof(struct lttng_session) * nr_sessions) +
+ (sizeof(struct lttng_session_extended) * nr_sessions);
sessions_payload = zmalloc(payload_len);
if (!sessions_payload) {
goto setup_error;
}
- cmd_list_lttng_sessions(sessions_payload,
+ cmd_list_lttng_sessions(sessions_payload, nr_sessions,
LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
session_unlock_list();
cmd_ctx->lsm->u.snapshot_record.wait);
break;
}
- case LTTNG_CREATE_SESSION_SNAPSHOT:
+ case LTTNG_CREATE_SESSION_EXT:
{
- size_t nb_uri, len;
- struct lttng_uri *uris = NULL;
-
- nb_uri = cmd_ctx->lsm->u.uri.size;
- len = nb_uri * sizeof(struct lttng_uri);
-
- if (nb_uri > 0) {
- uris = zmalloc(len);
- if (uris == NULL) {
- ret = LTTNG_ERR_FATAL;
- goto error;
- }
-
- /* Receive variable len data */
- DBG("Waiting for %zu URIs from client ...", nb_uri);
- ret = lttcomm_recv_unix_sock(sock, uris, len);
- if (ret <= 0) {
- DBG("No URIs received from client... continuing");
- *sock_error = 1;
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
+ struct lttng_dynamic_buffer payload;
+ struct lttng_session_descriptor *return_descriptor = NULL;
- if (nb_uri == 1 && uris[0].dtype != LTTNG_DST_PATH) {
- DBG("Creating session with ONE network URI is a bad call");
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
+ lttng_dynamic_buffer_init(&payload);
+ ret = cmd_create_session(cmd_ctx, sock, &return_descriptor);
+ if (ret != LTTNG_OK) {
+ goto error;
}
- ret = cmd_create_session_snapshot(cmd_ctx->lsm->session.name, uris,
- nb_uri, &cmd_ctx->creds);
- free(uris);
- break;
- }
- case LTTNG_CREATE_SESSION_LIVE:
- {
- size_t nb_uri, len;
- struct lttng_uri *uris = NULL;
-
- nb_uri = cmd_ctx->lsm->u.uri.size;
- len = nb_uri * sizeof(struct lttng_uri);
-
- if (nb_uri > 0) {
- uris = zmalloc(len);
- if (uris == NULL) {
- ret = LTTNG_ERR_FATAL;
- goto error;
- }
-
- /* Receive variable len data */
- DBG("Waiting for %zu URIs from client ...", nb_uri);
- ret = lttcomm_recv_unix_sock(sock, uris, len);
- if (ret <= 0) {
- DBG("No URIs received from client... continuing");
- *sock_error = 1;
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
-
- if (nb_uri == 1 && uris[0].dtype != LTTNG_DST_PATH) {
- DBG("Creating session with ONE network URI is a bad call");
- ret = LTTNG_ERR_SESSION_FAIL;
- free(uris);
- goto error;
- }
+ ret = lttng_session_descriptor_serialize(return_descriptor,
+ &payload);
+ if (ret) {
+ ERR("Failed to serialize session descriptor in reply to \"create session\" command");
+ lttng_session_descriptor_destroy(return_descriptor);
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
}
-
- ret = cmd_create_session_uri(cmd_ctx->lsm->session.name, uris,
- nb_uri, &cmd_ctx->creds, cmd_ctx->lsm->u.session_live.timer_interval);
- free(uris);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, payload.data,
+ payload.size);
+ if (ret) {
+ lttng_session_descriptor_destroy(return_descriptor);
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ lttng_dynamic_buffer_reset(&payload);
+ lttng_session_descriptor_destroy(return_descriptor);
+ ret = LTTNG_OK;
break;
}
case LTTNG_SAVE_SESSION:
lttng_pipe_destroy(quit_pipe);
}
+static void thread_init_cleanup(void *data)
+{
+ set_thread_status(false);
+}
+
/*
* This thread manage all clients request using the unix client socket for
* communication.
is_root = (getuid() == 0);
+ pthread_cleanup_push(thread_init_cleanup, NULL);
client_sock = create_client_sock();
if (client_sock < 0) {
goto error_listen;
goto error;
}
+ /* Set state as running. */
+ set_thread_status(true);
+ pthread_cleanup_pop(0);
+
/* This testpoint is after we signal readiness to the parent. */
if (testpoint(sessiond_thread_manage_clients)) {
goto error;
health_code_update();
- /* Set state as running. */
- set_thread_state_running();
-
while (1) {
const struct cmd_completion_handler *cmd_completion_handler;
health_code_update();
- if (!revents) {
- /* No activity for this FD (poll implementation). */
- continue;
- }
-
if (pollfd == thread_quit_pipe_fd) {
err = 0;
goto exit;
struct lttng_thread *launch_client_thread(void)
{
+ bool thread_running;
struct lttng_pipe *client_quit_pipe;
struct lttng_thread *thread;
+ sem_init(&thread_state.ready, 0, 0);
client_quit_pipe = lttng_pipe_open(FD_CLOEXEC);
if (!client_quit_pipe) {
goto error;
* This thread is part of the threads that need to be fully
* initialized before the session daemon is marked as "ready".
*/
- wait_thread_state_running();
-
+ thread_running = wait_thread_status();
+ if (!thread_running) {
+ lttng_thread_put(thread);
+ thread = NULL;
+ }
return thread;
error:
cleanup_client_thread(client_quit_pipe);