#include "trace.h"
#include "traceable-app.h"
+/*
+ * TODO:
+ * teardown: signal SIGTERM handler -> write into pipe. Threads waits
+ * with epoll on pipe and on other pipes/sockets for commands. Main
+ * simply waits on pthread join.
+ */
+
/* Const values */
const char default_home_dir[] = DEFAULT_HOME_DIR;
const char default_tracing_group[] = DEFAULT_TRACING_GROUP;
/* Static functions */
static int check_existing_daemon(void);
-static int connect_app(pid_t pid);
+static int ust_connect_app(pid_t pid);
static int init_daemon_socket(void);
static int notify_apps(const char* name);
static int process_client_msg(int sock, struct lttcomm_session_msg*);
static int apps_sock;
static int kconsumerd_err_sock;
-static struct ltt_session *current_session;
+/* Extern in session.h */
+struct ltt_session *current_session;
/*
* thread_manage_kconsumerd
int sock, ret;
/* TODO: Something more elegant is needed but fine for now */
+ /* FIXME: change all types to either uint8_t, uint32_t, uint64_t
+ * for 32-bit vs 64-bit compat processes. */
+ /* replicate in ust with version number */
struct {
int reg; /* 1:register, 0:unregister */
pid_t pid;
DBG("[thread] Manage apps started");
- /* Notify all applications to register */
- notify_apps(default_global_apps_pipe);
-
ret = lttcomm_listen_unix_sock(apps_sock);
if (ret < 0) {
goto error;
}
+ /* Notify all applications to register */
+ notify_apps(default_global_apps_pipe);
+
while (1) {
/* Blocking call, waiting for transmission */
sock = lttcomm_accept_unix_sock(apps_sock);
}
/*
- * connect_app
+ * ust_connect_app
*
* Return a socket connected to the libust communication socket
* of the application identified by the pid.
* If the pid is not found in the traceable list,
* return -1 to indicate error.
*/
-static int connect_app(pid_t pid)
+static int ust_connect_app(pid_t pid)
{
int sock;
struct ltt_traceable_app *lta;
return ret;
}
-/*
- * ust_create_trace
- *
- * Create an userspace trace using pid.
- * This trace is then appended to the current session
- * ust trace list.
- */
-static int ust_create_trace(pid_t pid)
-{
- int sock, ret;
- struct ltt_ust_trace *trace;
-
- DBG("Creating trace for pid %d", pid);
-
- trace = malloc(sizeof(struct ltt_ust_trace));
- if (trace == NULL) {
- perror("malloc");
- ret = -1;
- goto error;
- }
-
- /* Init */
- trace->pid = pid;
- trace->shmid = 0;
- /* NOTE: to be removed. Trace name will no longer be
- * required for LTTng userspace tracer. For now, we set it
- * to 'auto' for API compliance.
- */
- snprintf(trace->name, 5, "auto");
-
- /* Connect to app using ustctl API */
- sock = connect_app(pid);
- if (sock < 0) {
- ret = LTTCOMM_NO_TRACEABLE;
- goto error;
- }
-
- ret = ustctl_create_trace(sock, trace->name);
- if (ret < 0) {
- ret = LTTCOMM_CREATE_FAIL;
- goto error;
- }
-
- /* Check if current session is valid */
- if (current_session) {
- cds_list_add(&trace->list, ¤t_session->ust_traces);
- current_session->ust_trace_count++;
- }
-
-error:
- return ret;
-}
-
-/*
- * ust_start_trace
- *
- * Start a trace. This trace, identified by the pid, must be
- * in the current session ust_traces list.
- */
-static int ust_start_trace(pid_t pid)
-{
- int sock, ret;
- struct ltt_ust_trace *trace;
-
- DBG("Starting trace for pid %d", pid);
-
- trace = find_session_ust_trace_by_pid(current_session, pid);
- if (trace == NULL) {
- ret = LTTCOMM_NO_TRACE;
- goto error;
- }
-
- /* Connect to app using ustctl API */
- sock = connect_app(pid);
- if (sock < 0) {
- ret = LTTCOMM_NO_TRACEABLE;
- goto error;
- }
-
- ret = ustctl_start_trace(sock, "auto");
- if (ret < 0) {
- ret = LTTCOMM_START_FAIL;
- goto error;
- }
-
-error:
- return ret;
-}
-
-/*
- * ust_stop_trace
- *
- * Stop a trace. This trace, identified by the pid, must be
- * in the current session ust_traces list.
- */
-static int ust_stop_trace(pid_t pid)
-{
- int sock, ret;
- struct ltt_ust_trace *trace;
-
- DBG("Stopping trace for pid %d", pid);
-
- trace = find_session_ust_trace_by_pid(current_session, pid);
- if (trace == NULL) {
- ret = LTTCOMM_NO_TRACE;
- goto error;
- }
-
- /* Connect to app using ustctl API */
- sock = connect_app(pid);
- if (sock < 0) {
- ret = LTTCOMM_NO_TRACEABLE;
- goto error;
- }
-
- ret = ustctl_stop_trace(sock, trace->name);
- if (ret < 0) {
- ret = LTTCOMM_STOP_FAIL;
- goto error;
- }
-
-error:
- return ret;
-}
-
/*
* copy_common_data
*
*/
static int process_client_msg(int sock, struct lttcomm_session_msg *lsm)
{
- int ret;
- int buf_size;
+ int ust_sock, ret, buf_size;
size_t header_size;
char *send_buf = NULL;
struct lttcomm_lttng_header llh;
copy_common_data(&llh, lsm);
/* Check command that needs a session */
- if (lsm->cmd_type != LTTNG_CREATE_SESSION &&
- lsm->cmd_type != LTTNG_LIST_SESSIONS &&
- lsm->cmd_type != UST_LIST_APPS)
- {
+ switch (lsm->cmd_type) {
+ case LTTNG_CREATE_SESSION:
+ case LTTNG_LIST_SESSIONS:
+ case UST_LIST_APPS:
+ break;
+ default:
current_session = find_session_by_uuid(lsm->session_id);
if (current_session == NULL) {
ret = LTTCOMM_SELECT_SESS;
goto end;
}
+ break;
}
/* Default return code.
header_size = sizeof(struct lttcomm_lttng_header);
+ /* Connect to ust apps if available pid */
+ if (lsm->pid != 0) {
+ /* Connect to app using ustctl API */
+ ust_sock = ust_connect_app(lsm->pid);
+ if (ust_sock < 0) {
+ ret = LTTCOMM_NO_TRACEABLE;
+ goto end;
+ }
+ }
+
/* Process by command type */
switch (lsm->cmd_type) {
- case LTTNG_CREATE_SESSION:
- {
- ret = create_session(lsm->session_name, &llh.session_id);
- if (ret < 0) {
- if (ret == -1) {
- ret = LTTCOMM_EXIST_SESS;
- } else {
- ret = LTTCOMM_FATAL;
- }
- goto end;
- }
-
- buf_size = setup_data_buffer(&send_buf, 0, &llh);
- if (buf_size < 0) {
+ case LTTNG_CREATE_SESSION:
+ {
+ ret = create_session(lsm->session_name, &llh.session_id);
+ if (ret < 0) {
+ if (ret == -1) {
+ ret = LTTCOMM_EXIST_SESS;
+ } else {
ret = LTTCOMM_FATAL;
- goto end;
}
-
- break;
+ goto end;
}
- case LTTNG_DESTROY_SESSION:
- {
- ret = destroy_session(&lsm->session_id);
- if (ret < 0) {
- ret = LTTCOMM_NO_SESS;
- } else {
- ret = LTTCOMM_OK;
- }
- /* No auxiliary data so only send the llh struct. */
+ buf_size = setup_data_buffer(&send_buf, 0, &llh);
+ if (buf_size < 0) {
+ ret = LTTCOMM_FATAL;
goto end;
}
- case LTTNG_LIST_TRACES:
- {
- unsigned int trace_count = get_trace_count_per_session(current_session);
- if (trace_count == 0) {
- ret = LTTCOMM_NO_TRACE;
- goto end;
- }
+ break;
+ }
+ case LTTNG_DESTROY_SESSION:
+ {
+ ret = destroy_session(&lsm->session_id);
+ if (ret < 0) {
+ ret = LTTCOMM_NO_SESS;
+ } else {
+ ret = LTTCOMM_OK;
+ }
- buf_size = setup_data_buffer(&send_buf,
- sizeof(struct lttng_trace) * trace_count, &llh);
- if (buf_size < 0) {
- ret = LTTCOMM_FATAL;
- goto end;
- }
+ /* No auxiliary data so only send the llh struct. */
+ goto end;
+ }
+ case LTTNG_LIST_TRACES:
+ {
+ unsigned int trace_count = get_trace_count_per_session(current_session);
- get_traces_per_session(current_session, (struct lttng_trace *)(send_buf + header_size));
- break;
+ if (trace_count == 0) {
+ ret = LTTCOMM_NO_TRACE;
+ goto end;
}
- case UST_CREATE_TRACE:
- {
- ret = ust_create_trace(lsm->pid);
- if (ret < 0) {
- /* If -1 is returned from ust_create_trace, malloc
- * failed so it's pretty much a fatal error.
- */
- ret = LTTCOMM_FATAL;
- goto end;
- }
- /* No auxiliary data so only send the llh struct. */
+ buf_size = setup_data_buffer(&send_buf,
+ sizeof(struct lttng_trace) * trace_count, &llh);
+ if (buf_size < 0) {
+ ret = LTTCOMM_FATAL;
goto end;
}
- case UST_LIST_APPS:
- {
- unsigned int app_count = get_app_count();
- /* Stop right now if no apps */
- if (app_count == 0) {
- ret = LTTCOMM_NO_APPS;
- goto end;
- }
-
- /* Setup data buffer and details for transmission */
- buf_size = setup_data_buffer(&send_buf,
- sizeof(pid_t) * app_count, &llh);
- if (buf_size < 0) {
- ret = LTTCOMM_FATAL;
- goto end;
- }
- get_app_list_pids((pid_t *)(send_buf + header_size));
-
- break;
+ get_traces_per_session(current_session, (struct lttng_trace *)(send_buf + header_size));
+ break;
+ }
+ case UST_CREATE_TRACE:
+ {
+ ret = ust_create_trace(ust_sock, lsm->pid);
+ if (ret < 0) {
+ /* If -1 is returned from ust_create_trace, malloc
+ * failed so it's pretty much a fatal error.
+ */
+ ret = LTTCOMM_FATAL;
+ goto end;
}
- case UST_START_TRACE:
- {
- ret = ust_start_trace(lsm->pid);
- /* No auxiliary data so only send the llh struct. */
+ /* No auxiliary data so only send the llh struct. */
+ goto end;
+ }
+ case UST_LIST_APPS:
+ {
+ unsigned int app_count = get_app_count();
+ /* Stop right now if no apps */
+ if (app_count == 0) {
+ ret = LTTCOMM_NO_APPS;
goto end;
}
- case UST_STOP_TRACE:
- {
- ret = ust_stop_trace(lsm->pid);
- /* No auxiliary data so only send the llh struct. */
+ /* Setup data buffer and details for transmission */
+ buf_size = setup_data_buffer(&send_buf,
+ sizeof(pid_t) * app_count, &llh);
+ if (buf_size < 0) {
+ ret = LTTCOMM_FATAL;
goto end;
}
- case LTTNG_LIST_SESSIONS:
- {
- unsigned int session_count = get_session_count();
- /* Stop right now if no session */
- if (session_count == 0) {
- ret = LTTCOMM_NO_SESS;
- goto end;
- }
- /* Setup data buffer and details for transmission */
- buf_size = setup_data_buffer(&send_buf,
- (sizeof(struct lttng_session) * session_count), &llh);
- if (buf_size < 0) {
- ret = LTTCOMM_FATAL;
- goto end;
- }
+ get_app_list_pids((pid_t *)(send_buf + header_size));
+
+ break;
+ }
+ case UST_START_TRACE:
+ {
+ ret = ust_start_trace(ust_sock, lsm->pid);
- get_lttng_session((struct lttng_session *)(send_buf + header_size));
+ /* No auxiliary data so only send the llh struct. */
+ goto end;
+ }
+ case UST_STOP_TRACE:
+ {
+ ret = ust_stop_trace(ust_sock, lsm->pid);
- break;
+ /* No auxiliary data so only send the llh struct. */
+ goto end;
+ }
+ case LTTNG_LIST_SESSIONS:
+ {
+ unsigned int session_count = get_session_count();
+ /* Stop right now if no session */
+ if (session_count == 0) {
+ ret = LTTCOMM_NO_SESS;
+ goto end;
}
- default:
- {
- /* Undefined command */
- ret = LTTCOMM_UND;
+
+ /* Setup data buffer and details for transmission */
+ buf_size = setup_data_buffer(&send_buf,
+ (sizeof(struct lttng_session) * session_count), &llh);
+ if (buf_size < 0) {
+ ret = LTTCOMM_FATAL;
goto end;
}
+
+ get_lttng_session((struct lttng_session *)(send_buf + header_size));
+
+ break;
+ }
+ default:
+ /* Undefined command */
+ ret = LTTCOMM_UND;
+ goto end;
}
ret = send_unix_sock(sock, send_buf, buf_size);
/*
* set_permissions
*
- * Set the tracing group gid onto the client socket.
+ * Set the tracing group gid onto the client socket.
+ *
+ * Race window between mkdir and chown is OK because we are going from
+ * less permissive (root.root) to more permissive (root.tracing).
*/
static int set_permissions(void)
{
/* We do not goto error because we must not
* cleanup() because a daemon is already running.
*/
- return EXIT_FAILURE;
+ exit(EXIT_FAILURE);
}
if (set_signal_handler() < 0) {
}
cleanup();
- return 0;
+ exit(EXIT_SUCCESS);
error:
cleanup();
-
- return EXIT_FAILURE;
+ exit(EXIT_FAILURE);
}