#include <urcu/list.h> /* URCU list library (-lurcu) */
#include <lttng/lttng.h>
+#include "context.h"
#include "liblttsessiondcomm.h"
#include "ltt-sessiond.h"
#include "lttngerr.h"
#include "lttng-kconsumerd.h"
#include "utils.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[] = LTTNG_DEFAULT_TRACING_GROUP;
/* Variables */
int opt_verbose; /* Not static for lttngerr.h */
int opt_quiet; /* Not static for lttngerr.h */
+
const char *progname;
const char *opt_tracing_group;
static int opt_sig_parent;
* mutex lock. The lock MUST be taken if you iterate over the list. The lock
* MUST NOT be taken if you call a public function in session.c.
*
- * The lock is nested inside the structure: session_list_ptr->lock.
+ * The lock is nested inside the structure: session_list_ptr->lock. Please use
+ * lock_session_list and unlock_session_list for lock acquisition.
*/
static struct ltt_session_list *session_list_ptr;
}
/*
- * teardown_kernel_session
- *
- * Complete teardown of a kernel session. This free all data structure related
- * to a kernel session and update counter.
+ * Complete teardown of a kernel session. This free all data structure related
+ * to a kernel session and update counter.
*/
static void teardown_kernel_session(struct ltt_session *session)
{
}
/*
- * Cleanup the daemon
+ * Cleanup the daemon
*/
static void cleanup()
{
int ret;
char *cmd;
- struct ltt_session *sess;
+ struct ltt_session *sess, *stmp;
DBG("Cleaning up");
pthread_mutex_destroy(&session_list_ptr->lock);
/* Cleanup ALL session */
- cds_list_for_each_entry(sess, &session_list_ptr->head, list) {
+ cds_list_for_each_entry_safe(sess, stmp, &session_list_ptr->head, list) {
teardown_kernel_session(sess);
// TODO complete session cleanup (including UST)
}
}
/*
- * send_unix_sock
- *
- * Send data on a unix socket using the liblttsessiondcomm API.
+ * Send data on a unix socket using the liblttsessiondcomm API.
*
- * Return lttcomm error code.
+ * Return lttcomm error code.
*/
static int send_unix_sock(int sock, void *buf, size_t len)
{
}
/*
- * clean_command_ctx
- *
- * Free memory of a command context structure.
+ * Free memory of a command context structure.
*/
static void clean_command_ctx(struct command_ctx **cmd_ctx)
{
}
/*
- * send_kconsumerd_channel_fds
- *
- * Send all stream fds of kernel channel to the consumer.
+ * Send all stream fds of kernel channel to the consumer.
*/
static int send_kconsumerd_channel_fds(int sock, struct ltt_kernel_channel *channel)
{
}
/*
- * send_kconsumerd_fds
- *
- * Send all stream fds of the kernel session to the consumer.
+ * Send all stream fds of the kernel session to the consumer.
*/
static int send_kconsumerd_fds(int sock, struct ltt_kernel_session *session)
{
#ifdef DISABLED
/*
- * ust_connect_app
+ * Return a socket connected to the libust communication socket of the
+ * application identified by the pid.
*
- * 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.
+ * If the pid is not found in the traceable list, return -1 to indicate error.
*/
static int ust_connect_app(pid_t pid)
{
#endif /* DISABLED */
/*
- * notify_apps
- *
- * Notify apps by writing 42 to a named pipe using name.
- * Every applications waiting for a ltt-sessiond will be notified
- * and re-register automatically to the session daemon.
+ * Notify apps by writing 42 to a named pipe using name. Every applications
+ * waiting for a ltt-sessiond will be notified and re-register automatically to
+ * the session daemon.
*
- * Return open or write error value.
+ * Return open or write error value.
*/
static int notify_apps(const char *name)
{
}
/*
- * setup_lttng_msg
+ * Setup the outgoing data buffer for the response (llm) by allocating the
+ * right amount of memory and copying the original information from the lsm
+ * structure.
*
- * Setup the outgoing data buffer for the response (llm) by allocating the
- * right amount of memory and copying the original information from the lsm
- * structure.
- *
- * Return total size of the buffer pointed by buf.
+ * Return total size of the buffer pointed by buf.
*/
static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size)
{
/* Copy common data */
cmd_ctx->llm->cmd_type = cmd_ctx->lsm->cmd_type;
- cmd_ctx->llm->pid = cmd_ctx->lsm->pid;
+ cmd_ctx->llm->pid = cmd_ctx->lsm->domain.attr.pid;
cmd_ctx->llm->data_size = size;
cmd_ctx->lttng_msg_size = sizeof(struct lttcomm_lttng_msg) + buf_size;
}
/*
- * update_kernel_pollfd
- *
- * Update the kernel pollfd set of all channel fd available over
- * all tracing session. Add the wakeup pipe at the end of the set.
+ * Update the kernel pollfd set of all channel fd available over all tracing
+ * session. Add the wakeup pipe at the end of the set.
*/
static int update_kernel_pollfd(void)
{
}
/*
- * update_kernel_stream
- *
- * Find the channel fd from 'fd' over all tracing session. When found, check
- * for new channel stream and send those stream fds to the kernel consumer.
+ * Find the channel fd from 'fd' over all tracing session. When found, check
+ * for new channel stream and send those stream fds to the kernel consumer.
*
- * Useful for CPU hotplug feature.
+ * Useful for CPU hotplug feature.
*/
static int update_kernel_stream(int fd)
{
}
/*
- * thread_manage_kernel
+ * This thread manage event coming from the kernel.
*
- * This thread manage event coming from the kernel.
- *
- * Features supported in this thread:
- * -) CPU Hotplug
+ * Features supported in this thread:
+ * -) CPU Hotplug
*/
static void *thread_manage_kernel(void *data)
{
}
/*
- * thread_manage_kconsumerd
- *
- * This thread manage the kconsumerd error sent
- * back to the session daemon.
+ * This thread manage the kconsumerd error sent back to the session daemon.
*/
static void *thread_manage_kconsumerd(void *data)
{
}
/*
- * thread_manage_apps
- *
* This thread manage the application socket communication
*/
static void *thread_manage_apps(void *data)
}
/*
- * spawn_kconsumerd_thread
- *
- * Start the thread_manage_kconsumerd. This must be done after a kconsumerd
- * exec or it will fails.
+ * Start the thread_manage_kconsumerd. This must be done after a kconsumerd
+ * exec or it will fails.
*/
static int spawn_kconsumerd_thread(void)
{
}
/*
- * spawn_kconsumerd
- *
- * Fork and exec a kernel consumer daemon (kconsumerd).
- *
- * NOTE: It is very important to fork a kconsumerd BEFORE opening any kernel
- * file descriptor using the libkernelctl or kernel-ctl functions. So, a
- * kernel consumer MUST only be spawned before creating a kernel session.
+ * Fork and exec a kernel consumer daemon (kconsumerd).
*
- * Return pid if successful else -1.
+ * Return pid if successful else -1.
*/
static pid_t spawn_kconsumerd(void)
{
int ret;
pid_t pid;
+ const char *verbosity;
DBG("Spawning kconsumerd");
/*
* Exec kconsumerd.
*/
- execlp("ltt-kconsumerd", "ltt-kconsumerd", "--verbose", NULL);
+ if (opt_verbose > 1) {
+ verbosity = "--verbose";
+ } else {
+ verbosity = "--quiet";
+ }
+ execl(INSTALL_BIN_PATH "/ltt-kconsumerd", "ltt-kconsumerd", verbosity, NULL);
if (errno != 0) {
perror("kernel start consumer exec");
}
}
/*
- * start_kconsumerd
- *
- * Spawn the kconsumerd daemon and session daemon thread.
+ * Spawn the kconsumerd daemon and session daemon thread.
*/
static int start_kconsumerd(void)
{
}
/*
- * modprobe_kernel_modules
+ * modprobe_kernel_modules
*/
static int modprobe_kernel_modules(void)
{
}
/*
- * mount_debugfs
+ * mount_debugfs
*/
static int mount_debugfs(char *path)
{
}
/*
- * init_kernel_tracer
- *
- * Setup necessary data for kernel tracer action.
+ * Setup necessary data for kernel tracer action.
*/
static void init_kernel_tracer(void)
{
}
/*
- * start_kernel_trace
- *
- * Start tracing by creating trace directory and sending FDs to the kernel
- * consumer.
+ * Start tracing by creating trace directory and sending FDs to the kernel
+ * consumer.
*/
static int start_kernel_trace(struct ltt_kernel_session *session)
{
- int ret;
+ int ret = 0;
if (session->kconsumer_fds_sent == 0) {
ret = send_kconsumerd_fds(kconsumerd_cmd_sock, session);
}
/*
- * init_default_channel
- *
- * Allocate a channel structure and fill it.
+ * Allocate a channel structure and fill it.
*/
-static struct lttng_channel *init_default_channel(void)
+static struct lttng_channel *init_default_channel(char *name)
{
struct lttng_channel *chan;
goto error;
}
- if (snprintf(chan->name, NAME_MAX, DEFAULT_CHANNEL_NAME) < 0) {
- perror("snprintf defautl channel name");
+ if (snprintf(chan->name, NAME_MAX, "%s", name) < 0) {
+ perror("snprintf channel name");
return NULL;
}
}
/*
- * create_kernel_session
- *
- * Create a kernel tracer session then create the default channel.
+ * Create a kernel tracer session then create the default channel.
*/
static int create_kernel_session(struct ltt_session *session)
{
}
/*
- * process_client_msg
- *
- * Process the command requested by the lttng client within the command
- * context structure. This function make sure that the return structure (llm)
- * is set and ready for transmission before returning.
+ * Fill lttng_channel array of all channels.
+ */
+static void list_lttng_channels(struct ltt_session *session,
+ struct lttng_channel *channels)
+{
+ int i = 0;
+ struct ltt_kernel_channel *kchan;
+
+ DBG("Listing channels for session %s", session->name);
+
+ /* Kernel channels */
+ if (session->kernel_session != NULL) {
+ cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head, list) {
+ /* Copy lttng_channel struct to array */
+ memcpy(&channels[i], kchan->channel, sizeof(struct lttng_channel));
+ channels[i].enabled = kchan->enabled;
+ i++;
+ }
+ }
+
+ /* TODO: Missing UST listing */
+}
+
+/*
+ * Fill lttng_event array of all events in the channel.
+ */
+static void list_lttng_events(struct ltt_kernel_channel *kchan,
+ struct lttng_event *events)
+{
+ /*
+ * TODO: This is ONLY kernel. Need UST support.
+ */
+ int i = 0;
+ struct ltt_kernel_event *event;
+
+ DBG("Listing events for channel %s", kchan->channel->name);
+
+ /* Kernel channels */
+ cds_list_for_each_entry(event, &kchan->events_list.head , list) {
+ strncpy(events[i].name, event->event->name, LTTNG_SYMBOL_NAME_LEN);
+ events[i].enabled = event->enabled;
+ switch (event->event->instrumentation) {
+ case LTTNG_KERNEL_TRACEPOINT:
+ events[i].type = LTTNG_EVENT_TRACEPOINT;
+ break;
+ case LTTNG_KERNEL_KPROBE:
+ case LTTNG_KERNEL_KRETPROBE:
+ events[i].type = LTTNG_EVENT_PROBE;
+ memcpy(&events[i].attr.probe, &event->event->u.kprobe,
+ sizeof(struct lttng_kernel_kprobe));
+ break;
+ case LTTNG_KERNEL_FUNCTION:
+ events[i].type = LTTNG_EVENT_FUNCTION;
+ memcpy(&events[i].attr.ftrace, &event->event->u.ftrace,
+ sizeof(struct lttng_kernel_function));
+ break;
+ }
+ i++;
+ }
+}
+
+/*
+ * Process the command requested by the lttng client within the command
+ * context structure. This function make sure that the return structure (llm)
+ * is set and ready for transmission before returning.
*
* Return any error encountered or 0 for success.
*/
static int process_client_msg(struct command_ctx *cmd_ctx)
{
- int ret;
+ int ret = LTTCOMM_OK;
DBG("Processing client command %d", cmd_ctx->lsm->cmd_type);
switch (cmd_ctx->lsm->cmd_type) {
case LTTNG_CREATE_SESSION:
case LTTNG_LIST_SESSIONS:
- case LTTNG_LIST_EVENTS:
- case LTTNG_KERNEL_LIST_EVENTS:
- case LTTNG_LIST_TRACEABLE_APPS:
+ case LTTNG_LIST_TRACEPOINTS:
break;
default:
DBG("Getting session %s by name", cmd_ctx->lsm->session_name);
* Check kernel command for kernel session.
*/
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_KERNEL_ADD_CONTEXT:
+ case LTTNG_ADD_CONTEXT:
case LTTNG_KERNEL_DISABLE_ALL_EVENT:
case LTTNG_KERNEL_DISABLE_CHANNEL:
case LTTNG_KERNEL_DISABLE_EVENT:
case LTTNG_KERNEL_ENABLE_ALL_EVENT:
case LTTNG_KERNEL_ENABLE_CHANNEL:
case LTTNG_KERNEL_ENABLE_EVENT:
- case LTTNG_KERNEL_LIST_EVENTS:
+ case LTTNG_LIST_TRACEPOINTS:
/* Kernel tracer check */
if (kernel_tracer_fd == 0) {
init_kernel_tracer();
}
/* Need a session for kernel command */
- if (cmd_ctx->lsm->cmd_type != LTTNG_KERNEL_LIST_EVENTS &&
+ if (cmd_ctx->lsm->cmd_type != LTTNG_LIST_TRACEPOINTS &&
cmd_ctx->session->kernel_session == NULL) {
ret = create_kernel_session(cmd_ctx->session);
/* Process by command type */
switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_KERNEL_ADD_CONTEXT:
+ case LTTNG_ADD_CONTEXT:
{
- int found = 0, no_event = 0;
- struct ltt_kernel_channel *chan;
- struct ltt_kernel_event *event;
- struct lttng_kernel_context ctx;
+ struct lttng_kernel_context kctx;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- /* Check if event name is given */
- if (strlen(cmd_ctx->lsm->u.context.event_name) == 0) {
- no_event = 1;
- }
-
- /* Create Kernel context */
- ctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx;
- ctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type;
- ctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config;
- strncpy(ctx.u.perf_counter.name,
- cmd_ctx->lsm->u.context.ctx.u.perf_counter.name,
- sizeof(ctx.u.perf_counter.name));
-
- if (strlen(cmd_ctx->lsm->u.context.channel_name) == 0) {
- /* Go over all channels */
- DBG("Adding context to all channels");
- cds_list_for_each_entry(chan,
- &cmd_ctx->session->kernel_session->channel_list.head, list) {
- if (no_event) {
- ret = kernel_add_channel_context(chan, &ctx);
- if (ret < 0) {
- continue;
- }
- } else {
- event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan);
- if (event != NULL) {
- ret = kernel_add_event_context(event, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- found = 1;
- break;
- }
- }
- }
- } else {
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.context.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ /* Create Kernel context */
+ kctx.ctx = cmd_ctx->lsm->u.context.ctx.ctx;
+ kctx.u.perf_counter.type = cmd_ctx->lsm->u.context.ctx.u.perf_counter.type;
+ kctx.u.perf_counter.config = cmd_ctx->lsm->u.context.ctx.u.perf_counter.config;
+ strncpy(kctx.u.perf_counter.name,
+ cmd_ctx->lsm->u.context.ctx.u.perf_counter.name,
+ LTTNG_SYMBOL_NAME_LEN);
+
+ /* Add kernel context to kernel tracer. See context.c */
+ ret = add_kernel_context(cmd_ctx->session->kernel_session, &kctx,
+ cmd_ctx->lsm->u.context.event_name,
+ cmd_ctx->lsm->u.context.channel_name);
+ if (ret != LTTCOMM_OK) {
goto error;
}
-
- if (no_event) {
- ret = kernel_add_channel_context(chan, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- } else {
- event = get_kernel_event_by_name(cmd_ctx->lsm->u.context.event_name, chan);
- if (event != NULL) {
- ret = kernel_add_event_context(event, &ctx);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CONTEXT_FAIL;
- goto error;
- }
- }
- }
- }
-
- if (!found && !no_event) {
- ret = LTTCOMM_NO_EVENT;
- goto error;
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
}
ret = LTTCOMM_OK;
kchan = get_kernel_channel_by_name(channel_name,
cmd_ctx->session->kernel_session);
if (kchan == NULL) {
- DBG("Creating default channel");
+ DBG("Channel not found. Creating channel %s", channel_name);
- chan = init_default_channel();
+ chan = init_default_channel(channel_name);
if (chan == NULL) {
ret = LTTCOMM_FATAL;
goto error;
}
case LTTNG_KERNEL_ENABLE_ALL_EVENT:
{
- int pos, size;
- char *event_list, *event, *ptr, *channel_name;
+ int size, i;
+ char *channel_name;
struct ltt_kernel_channel *kchan;
struct ltt_kernel_event *ev;
- struct lttng_event ev_attr;
+ struct lttng_event *event_list;
struct lttng_channel *chan;
/* Setup lttng message with no payload */
kchan = get_kernel_channel_by_name(channel_name,
cmd_ctx->session->kernel_session);
if (kchan == NULL) {
- DBG("Creating default channel");
+ DBG("Channel not found. Creating channel %s", channel_name);
- chan = init_default_channel();
+ chan = init_default_channel(channel_name);
if (chan == NULL) {
ret = LTTCOMM_FATAL;
goto error;
}
ret = kernel_create_channel(cmd_ctx->session->kernel_session,
- &cmd_ctx->lsm->u.channel.chan, cmd_ctx->session->path);
+ chan, cmd_ctx->session->path);
if (ret < 0) {
ret = LTTCOMM_KERN_CHAN_FAIL;
goto error;
goto error;
}
- ptr = event_list;
- while ((size = sscanf(ptr, "event { name = %m[^;]; };%n\n", &event, &pos)) == 1) {
- ev = get_kernel_event_by_name(event, kchan);
+ for (i = 0; i < size; i++) {
+ ev = get_kernel_event_by_name(event_list[i].name, kchan);
if (ev == NULL) {
- strncpy(ev_attr.name, event, LTTNG_SYM_NAME_LEN);
/* Default event type for enable all */
- ev_attr.type = LTTNG_EVENT_TRACEPOINT;
+ event_list[i].type = LTTNG_EVENT_TRACEPOINT;
/* Enable each single tracepoint event */
- ret = kernel_create_event(&ev_attr, kchan);
+ ret = kernel_create_event(&event_list[i], kchan);
if (ret < 0) {
/* Ignore error here and continue */
}
}
-
- /* Move pointer to the next line */
- ptr += pos + 1;
- free(event);
}
free(event_list);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_LIST_EVENTS:
+ case LTTNG_LIST_TRACEPOINTS:
{
- char *event_list;
- ssize_t size = 0;
-
- DBG("Listing kernel events");
-
- size = kernel_list_events(kernel_tracer_fd, &event_list);
- if (size < 0) {
- ret = LTTCOMM_KERN_LIST_FAIL;
- goto error;
+ struct lttng_event *events;
+ ssize_t nb_events = 0;
+
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ DBG("Listing kernel events");
+ nb_events = kernel_list_events(kernel_tracer_fd, &events);
+ if (nb_events < 0) {
+ ret = LTTCOMM_KERN_LIST_FAIL;
+ goto error;
+ }
+ break;
+ default:
+ /* TODO: Userspace listing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ break;
}
/*
* Setup lttng message with payload size set to the event list size in
* bytes and then copy list into the llm payload.
*/
- ret = setup_lttng_msg(cmd_ctx, size);
+ ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event) * nb_events);
if (ret < 0) {
+ free(events);
goto setup_error;
}
/* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, event_list, size);
+ memcpy(cmd_ctx->llm->payload, events,
+ sizeof(struct lttng_event) * nb_events);
- free(event_list);
+ free(events);
ret = LTTCOMM_OK;
break;
break;
}
/*
- case LTTNG_LIST_TRACES:
+ case UST_CREATE_TRACE:
{
- unsigned int trace_count;
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ goto setup_error;
+ }
- trace_count = get_trace_count_per_session(cmd_ctx->session);
- if (trace_count == 0) {
- ret = LTTCOMM_NO_TRACE;
+ ret = ust_create_trace(cmd_ctx);
+ if (ret < 0) {
goto error;
}
-
- ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_trace) * trace_count);
+ break;
+ }
+ case UST_START_TRACE:
+ {
+ ret = setup_lttng_msg(cmd_ctx, 0);
if (ret < 0) {
goto setup_error;
}
- get_traces_per_session(cmd_ctx->session,
- (struct lttng_trace *)(cmd_ctx->llm->payload));
-
- ret = LTTCOMM_OK;
+ ret = ust_start_trace(cmd_ctx);
+ if (ret < 0) {
+ goto setup_error;
+ }
break;
}
- */
- /*
- case UST_CREATE_TRACE:
+ case UST_STOP_TRACE:
{
ret = setup_lttng_msg(cmd_ctx, 0);
if (ret < 0) {
goto setup_error;
}
- ret = ust_create_trace(cmd_ctx);
+ ret = ust_stop_trace(cmd_ctx);
if (ret < 0) {
- goto error;
+ goto setup_error;
}
break;
}
*/
- case LTTNG_LIST_TRACEABLE_APPS:
+ case LTTNG_LIST_DOMAINS:
{
- unsigned int app_count;
+ size_t nb_dom = 0;
- app_count = get_app_count();
- DBG("Traceable application count : %d", app_count);
- if (app_count == 0) {
- ret = LTTCOMM_NO_APPS;
- goto error;
+ if (cmd_ctx->session->kernel_session != NULL) {
+ nb_dom++;
}
- ret = setup_lttng_msg(cmd_ctx, sizeof(pid_t) * app_count);
+ nb_dom += cmd_ctx->session->ust_trace_count;
+
+ ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_domain) * nb_dom);
if (ret < 0) {
goto setup_error;
}
- get_app_list_pids((pid_t *)(cmd_ctx->llm->payload));
+ ((struct lttng_domain *)(cmd_ctx->llm->payload))[0].type =
+ LTTNG_DOMAIN_KERNEL;
+ /* TODO: User-space tracer domain support */
ret = LTTCOMM_OK;
break;
}
- /*
- case UST_START_TRACE:
+ case LTTNG_LIST_CHANNELS:
{
- ret = setup_lttng_msg(cmd_ctx, 0);
- if (ret < 0) {
- goto setup_error;
+ /*
+ * TODO: Only kernel channels are listed here. UST listing
+ * is needed on lttng-ust 2.0 release.
+ */
+ size_t nb_chan = 0;
+ if (cmd_ctx->session->kernel_session != NULL) {
+ nb_chan += cmd_ctx->session->kernel_session->channel_count;
}
- ret = ust_start_trace(cmd_ctx);
+ ret = setup_lttng_msg(cmd_ctx,
+ sizeof(struct lttng_channel) * nb_chan);
if (ret < 0) {
goto setup_error;
}
+
+ list_lttng_channels(cmd_ctx->session,
+ (struct lttng_channel *)(cmd_ctx->llm->payload));
+
+ ret = LTTCOMM_OK;
break;
}
- case UST_STOP_TRACE:
+ case LTTNG_LIST_EVENTS:
{
- ret = setup_lttng_msg(cmd_ctx, 0);
- if (ret < 0) {
- goto setup_error;
+ /*
+ * TODO: Only kernel events are listed here. UST listing
+ * is needed on lttng-ust 2.0 release.
+ */
+ size_t nb_event = 0;
+ struct ltt_kernel_channel *kchan = NULL;
+
+ if (cmd_ctx->session->kernel_session != NULL) {
+ kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.list.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ goto error;
+ }
+ nb_event += kchan->event_count;
}
- ret = ust_stop_trace(cmd_ctx);
+ ret = setup_lttng_msg(cmd_ctx,
+ sizeof(struct lttng_event) * nb_event);
if (ret < 0) {
goto setup_error;
}
+
+ DBG("Listing events (%ld events)", nb_event);
+
+ list_lttng_events(kchan,
+ (struct lttng_event *)(cmd_ctx->llm->payload));
+
+ ret = LTTCOMM_OK;
break;
}
- */
case LTTNG_LIST_SESSIONS:
{
lock_session_list();
if (session_list_ptr->count == 0) {
ret = LTTCOMM_NO_SESSION;
+ unlock_session_list();
goto error;
}
ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) *
session_list_ptr->count);
if (ret < 0) {
+ unlock_session_list();
goto setup_error;
}
}
/*
- * thread_manage_clients
- *
- * This thread manage all clients request using the unix
- * client socket for communication.
+ * This thread manage all clients request using the unix client socket for
+ * communication.
*/
static void *thread_manage_clients(void *data)
{
opt_quiet = 1;
break;
case 'v':
- opt_verbose = 1;
+ /* Verbose level can increase using multiple -v */
+ opt_verbose += 1;
break;
default:
/* Unknown option or other error.
}
/*
- * init_daemon_socket
- *
- * Creates the two needed socket by the daemon.
+ * Creates the two needed socket by the daemon.
* apps_sock - The communication socket for all UST apps.
* client_sock - The communication of the cli tool (lttng).
*/
}
/*
- * check_existing_daemon
- *
- * Check if the global socket is available.
- * If yes, error is returned.
+ * Check if the global socket is available. If yes, error is returned.
*/
static int check_existing_daemon()
{
}
/*
- * 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
- * more permissive (root.root) to les permissive (root.tracing).
+ * Race window between mkdir and chown is OK because we are going from more
+ * permissive (root.root) to les permissive (root.tracing).
*/
static int set_permissions(void)
{
}
/*
- * create_kernel_poll_pipe
- *
- * Create the pipe used to wake up the kernel thread.
+ * Create the pipe used to wake up the kernel thread.
*/
static int create_kernel_poll_pipe(void)
{
}
/*
- * create_lttng_rundir
- *
- * Create the lttng run directory needed for all
- * global sockets and pipe.
+ * Create the lttng run directory needed for all global sockets and pipe.
*/
static int create_lttng_rundir(void)
{
}
/*
- * set_kconsumerd_sockets
- *
- * Setup sockets and directory needed by the kconsumerd
- * communication with the session daemon.
+ * Setup sockets and directory needed by the kconsumerd communication with the
+ * session daemon.
*/
static int set_kconsumerd_sockets(void)
{
}
/*
- * sighandler
- *
- * Signal handler for the daemon
+ * Signal handler for the daemon
*/
static void sighandler(int sig)
{
}
/*
- * set_signal_handler
- *
- * Setup signal handler for :
+ * Setup signal handler for :
* SIGINT, SIGTERM, SIGPIPE
*/
static int set_signal_handler(void)
}
/*
- * set_ulimit
- *
- * Set open files limit to unlimited. This daemon can open a large number of
- * file descriptors in order to consumer multiple kernel traces.
+ * Set open files limit to unlimited. This daemon can open a large number of
+ * file descriptors in order to consumer multiple kernel traces.
*/
static void set_ulimit(void)
{