#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"
static pthread_mutex_t kconsumerd_pid_mutex; /* Mutex to control kconsumerd pid assignation */
+static int modprobe_remove_kernel_modules(void);
+
/*
* Pointer initialized before thread creation.
*
DBG("Closing kernel fd");
close(kernel_tracer_fd);
+
+ DBG("Unloading kernel modules");
+ modprobe_remove_kernel_modules();
}
/*
/* 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;
*/
static int modprobe_kernel_modules(void)
{
- int ret = 0, i = 0;
+ int ret = 0, i;
char modprobe[256];
- while (kernel_modules_list[i] != NULL) {
- ret = snprintf(modprobe, sizeof(modprobe), "/sbin/modprobe %s",
- kernel_modules_list[i]);
+ for (i = 0; i < ARRAY_SIZE(kernel_modules_list); i++) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe %s%s",
+ kernel_modules_list[i].required ? "" : "--quiet ",
+ kernel_modules_list[i].name);
if (ret < 0) {
perror("snprintf modprobe");
goto error;
}
+ modprobe[sizeof(modprobe) - 1] = '\0';
ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe for module %s",
+ kernel_modules_list[i].name);
+ } else if (kernel_modules_list[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to load module %s",
+ kernel_modules_list[i].name);
+ } else {
+ DBG("Modprobe successfully %s",
+ kernel_modules_list[i].name);
+ }
+ }
+
+error:
+ return ret;
+}
+
+/*
+ * modprobe_remove_kernel_modules
+ * Remove modules in reverse load order.
+ */
+static int modprobe_remove_kernel_modules(void)
+{
+ int ret = 0, i;
+ char modprobe[256];
+
+ for (i = ARRAY_SIZE(kernel_modules_list) - 1; i >= 0; i--) {
+ ret = snprintf(modprobe, sizeof(modprobe),
+ "/sbin/modprobe --remove --quiet %s",
+ kernel_modules_list[i].name);
if (ret < 0) {
- ERR("Unable to load module %s", kernel_modules_list[i]);
+ perror("snprintf modprobe --remove");
+ goto error;
+ }
+ modprobe[sizeof(modprobe) - 1] = '\0';
+ ret = system(modprobe);
+ if (ret == -1) {
+ ERR("Unable to launch modprobe --remove for module %s",
+ kernel_modules_list[i].name);
+ } else if (kernel_modules_list[i].required
+ && WEXITSTATUS(ret) != 0) {
+ ERR("Unable to remove module %s",
+ kernel_modules_list[i].name);
+ } else {
+ DBG("Modprobe removal successful %s",
+ kernel_modules_list[i].name);
}
- DBG("Modprobe successfully %s", kernel_modules_list[i]);
- i++;
}
error:
}
if (snprintf(chan->name, NAME_MAX, "%s", name) < 0) {
- perror("snprintf defautl channel name");
+ perror("snprintf channel name");
return NULL;
}
}
}
+/*
+ * 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)
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:
+ case LTTNG_CALIBRATE:
break;
default:
- DBG("Getting session %s by name", cmd_ctx->lsm->session_name);
- cmd_ctx->session = find_session_by_name(cmd_ctx->lsm->session_name);
+ DBG("Getting session %s by name", cmd_ctx->lsm->session.name);
+ cmd_ctx->session = find_session_by_name(cmd_ctx->lsm->session.name);
if (cmd_ctx->session == NULL) {
/* If session name not found */
- if (cmd_ctx->lsm->session_name != NULL) {
+ if (cmd_ctx->lsm->session.name != NULL) {
ret = LTTCOMM_SESS_NOT_FOUND;
} else { /* If no session name specified */
ret = LTTCOMM_SELECT_SESS;
}
/*
- * Check kernel command for kernel session.
+ * Check domain type for specific "pre-action".
*/
- switch (cmd_ctx->lsm->cmd_type) {
- case LTTNG_KERNEL_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:
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
/* 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 &&
- cmd_ctx->session->kernel_session == NULL) {
-
- ret = create_kernel_session(cmd_ctx->session);
- if (ret < 0) {
- ret = LTTCOMM_KERN_SESS_FAIL;
- goto error;
- }
-
- /* Start the kernel consumer daemon */
- if (kconsumerd_pid == 0) {
- ret = start_kconsumerd();
+ switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_CREATE_SESSION:
+ case LTTNG_LIST_SESSIONS:
+ case LTTNG_LIST_TRACEPOINTS:
+ case LTTNG_CALIBRATE:
+ break;
+ default:
+ if (cmd_ctx->session->kernel_session == NULL) {
+ ret = create_kernel_session(cmd_ctx->session);
if (ret < 0) {
+ ret = LTTCOMM_KERN_SESS_FAIL;
goto error;
}
- }
- }
- }
-#ifdef DISABLED
- /* Connect to ust apps if available pid */
- if (cmd_ctx->lsm->pid > 0) {
- /* Connect to app using ustctl API */
- cmd_ctx->ust_sock = ust_connect_app(cmd_ctx->lsm->pid);
- if (cmd_ctx->ust_sock < 0) {
- ret = LTTCOMM_NO_TRACEABLE;
- goto error;
+ /* Start the kernel consumer daemon */
+ if (kconsumerd_pid == 0) {
+ ret = start_kconsumerd();
+ if (ret < 0) {
+ goto error;
+ }
+ }
+ }
}
+ break;
+ default:
+ break;
}
-#endif /* DISABLED */
/* 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;
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
goto error;
}
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_DISABLE_CHANNEL:
+ case LTTNG_DISABLE_CHANNEL:
{
- struct ltt_kernel_channel *chan;
+ struct ltt_kernel_channel *kchan;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
- } else if (chan->enabled == 1) {
- ret = kernel_disable_channel(chan);
- if (ret < 0) {
- if (ret != EEXIST) {
- ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL;
- }
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
goto error;
+ } else if (kchan->enabled == 1) {
+ ret = kernel_disable_channel(kchan);
+ if (ret < 0) {
+ if (ret != EEXIST) {
+ ret = LTTCOMM_KERN_CHAN_DISABLE_FAIL;
+ }
+ goto error;
+ }
}
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
}
- kernel_wait_quiescent(kernel_tracer_fd);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_DISABLE_EVENT:
+ case LTTNG_DISABLE_EVENT:
{
- struct ltt_kernel_channel *chan;
- struct ltt_kernel_event *ev;
+ struct ltt_kernel_channel *kchan;
+ struct ltt_kernel_event *kevent;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
- }
-
- ev = get_kernel_event_by_name(cmd_ctx->lsm->u.disable.name, chan);
- if (ev != NULL) {
- DBG("Disabling kernel event %s for channel %s.",
- cmd_ctx->lsm->u.disable.name, cmd_ctx->lsm->u.disable.channel_name);
- ret = kernel_disable_event(ev);
- if (ret < 0) {
- ret = LTTCOMM_KERN_ENABLE_FAIL;
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
goto error;
}
+
+ kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.disable.name, kchan);
+ if (kevent != NULL) {
+ DBG("Disabling kernel event %s for channel %s.", kevent->event->name,
+ kchan->channel->name);
+ ret = kernel_disable_event(kevent);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_ENABLE_FAIL;
+ goto error;
+ }
+ }
+
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
}
- kernel_wait_quiescent(kernel_tracer_fd);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_DISABLE_ALL_EVENT:
+ case LTTNG_DISABLE_ALL_EVENT:
{
- struct ltt_kernel_channel *chan;
- struct ltt_kernel_event *ev;
+ struct ltt_kernel_channel *kchan;
+ struct ltt_kernel_event *kevent;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- DBG("Disabling all enabled kernel events");
-
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
- goto error;
- }
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ DBG("Disabling all enabled kernel events");
+ kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.disable.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ goto error;
+ }
- /* For each event in the kernel session */
- cds_list_for_each_entry(ev, &chan->events_list.head, list) {
- DBG("Disabling kernel event %s for channel %s.",
- ev->event->name, cmd_ctx->lsm->u.disable.channel_name);
- ret = kernel_disable_event(ev);
- if (ret < 0) {
- continue;
+ /* For each event in the kernel session */
+ cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
+ DBG("Disabling kernel event %s for channel %s.",
+ kevent->event->name, kchan->channel->name);
+ ret = kernel_disable_event(kevent);
+ if (ret < 0) {
+ continue;
+ }
}
+
+ /* Quiescent wait after event disable */
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
}
- /* Quiescent wait after event disable */
- kernel_wait_quiescent(kernel_tracer_fd);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_ENABLE_CHANNEL:
+ case LTTNG_ENABLE_CHANNEL:
{
- struct ltt_kernel_channel *chan;
+ struct ltt_kernel_channel *kchan;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
goto setup_error;
}
- chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
- cmd_ctx->session->kernel_session);
- if (chan == NULL) {
- /* Channel not found, creating it */
- DBG("Creating kernel channel");
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ kchan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ /* Channel not found, creating it */
+ DBG("Creating kernel channel");
- ret = kernel_create_channel(cmd_ctx->session->kernel_session,
- &cmd_ctx->lsm->u.channel.chan, cmd_ctx->session->path);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CHAN_FAIL;
- goto error;
- }
+ ret = kernel_create_channel(cmd_ctx->session->kernel_session,
+ &cmd_ctx->lsm->u.channel.chan, cmd_ctx->session->path);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CHAN_FAIL;
+ goto error;
+ }
- /* Notify kernel thread that there is a new channel */
- ret = notify_kernel_pollfd();
- if (ret < 0) {
- ret = LTTCOMM_FATAL;
- goto error;
- }
- } else if (chan->enabled == 0) {
- ret = kernel_enable_channel(chan);
- if (ret < 0) {
- if (ret != EEXIST) {
- ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL;
+ /* Notify kernel thread that there is a new channel */
+ ret = notify_kernel_pollfd();
+ if (ret < 0) {
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
+ } else if (kchan->enabled == 0) {
+ ret = kernel_enable_channel(kchan);
+ if (ret < 0) {
+ if (ret != EEXIST) {
+ ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL;
+ }
+ goto error;
}
- goto error;
}
+
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
}
- kernel_wait_quiescent(kernel_tracer_fd);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_ENABLE_EVENT:
+ case LTTNG_ENABLE_EVENT:
{
char *channel_name;
struct ltt_kernel_channel *kchan;
- struct ltt_kernel_event *ev;
+ struct ltt_kernel_event *kevent;
struct lttng_channel *chan;
/* Setup lttng message with no payload */
channel_name = cmd_ctx->lsm->u.enable.channel_name;
- do {
- kchan = get_kernel_channel_by_name(channel_name,
- cmd_ctx->session->kernel_session);
- if (kchan == NULL) {
- DBG("Channel not found. Creating channel %s", channel_name);
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ do {
+ kchan = get_kernel_channel_by_name(channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ DBG("Channel not found. Creating channel %s", channel_name);
+
+ chan = init_default_channel(channel_name);
+ if (chan == NULL) {
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
- chan = init_default_channel(channel_name);
- if (chan == NULL) {
- ret = LTTCOMM_FATAL;
- goto error;
+ ret = kernel_create_channel(cmd_ctx->session->kernel_session,
+ chan, cmd_ctx->session->path);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CHAN_FAIL;
+ goto error;
+ }
}
+ } while (kchan == NULL);
- ret = kernel_create_channel(cmd_ctx->session->kernel_session,
- chan, cmd_ctx->session->path);
- if (ret < 0) {
- ret = LTTCOMM_KERN_CHAN_FAIL;
+ kevent = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan);
+ if (kevent == NULL) {
+ DBG("Creating kernel event %s for channel %s.",
+ cmd_ctx->lsm->u.enable.event.name, channel_name);
+ ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, kchan);
+ } else {
+ DBG("Enabling kernel event %s for channel %s.",
+ kevent->event->name, channel_name);
+ ret = kernel_enable_event(kevent);
+ if (ret == -EEXIST) {
+ ret = LTTCOMM_KERN_EVENT_EXIST;
goto error;
}
}
- } while (kchan == NULL);
- ev = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, kchan);
- if (ev == NULL) {
- DBG("Creating kernel event %s for channel %s.",
- cmd_ctx->lsm->u.enable.event.name, channel_name);
- ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, kchan);
- } else {
- DBG("Enabling kernel event %s for channel %s.",
- cmd_ctx->lsm->u.enable.event.name, channel_name);
- ret = kernel_enable_event(ev);
- if (ret == -EEXIST) {
- ret = LTTCOMM_KERN_EVENT_EXIST;
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_ENABLE_FAIL;
goto error;
}
- }
- if (ret < 0) {
- ret = LTTCOMM_KERN_ENABLE_FAIL;
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
goto error;
}
-
- kernel_wait_quiescent(kernel_tracer_fd);
ret = LTTCOMM_OK;
break;
}
- case LTTNG_KERNEL_ENABLE_ALL_EVENT:
+ case LTTNG_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 ltt_kernel_event *kevent;
+ struct lttng_event *event_list;
struct lttng_channel *chan;
/* Setup lttng message with no payload */
channel_name = cmd_ctx->lsm->u.enable.channel_name;
- do {
- kchan = get_kernel_channel_by_name(channel_name,
- cmd_ctx->session->kernel_session);
- if (kchan == NULL) {
- DBG("Channel not found. Creating channel %s", channel_name);
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ do {
+ kchan = get_kernel_channel_by_name(channel_name,
+ cmd_ctx->session->kernel_session);
+ if (kchan == NULL) {
+ DBG("Channel not found. Creating channel %s", channel_name);
+
+ chan = init_default_channel(channel_name);
+ if (chan == NULL) {
+ ret = LTTCOMM_FATAL;
+ goto error;
+ }
- chan = init_default_channel(channel_name);
- if (chan == NULL) {
- ret = LTTCOMM_FATAL;
- goto error;
+ ret = kernel_create_channel(cmd_ctx->session->kernel_session,
+ chan, cmd_ctx->session->path);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CHAN_FAIL;
+ goto error;
+ }
}
+ } while (kchan == NULL);
- ret = kernel_create_channel(cmd_ctx->session->kernel_session,
- chan, cmd_ctx->session->path);
+ /* For each event in the kernel session */
+ cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
+ DBG("Enabling kernel event %s for channel %s.",
+ kevent->event->name, channel_name);
+ ret = kernel_enable_event(kevent);
if (ret < 0) {
- ret = LTTCOMM_KERN_CHAN_FAIL;
- goto error;
+ continue;
}
}
- } while (kchan == NULL);
- /* For each event in the kernel session */
- cds_list_for_each_entry(ev, &kchan->events_list.head, list) {
- DBG("Enabling kernel event %s for channel %s.",
- ev->event->name, channel_name);
- ret = kernel_enable_event(ev);
- if (ret < 0) {
- continue;
+ size = kernel_list_events(kernel_tracer_fd, &event_list);
+ if (size < 0) {
+ ret = LTTCOMM_KERN_LIST_FAIL;
+ goto error;
}
- }
- size = kernel_list_events(kernel_tracer_fd, &event_list);
- if (size < 0) {
- ret = LTTCOMM_KERN_LIST_FAIL;
- 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);
- if (ev == NULL) {
- strncpy(ev_attr.name, event, LTTNG_SYM_NAME_LEN);
- /* Default event type for enable all */
- ev_attr.type = LTTNG_EVENT_TRACEPOINT;
- /* Enable each single tracepoint event */
- ret = kernel_create_event(&ev_attr, kchan);
- if (ret < 0) {
- /* Ignore error here and continue */
+ for (i = 0; i < size; i++) {
+ kevent = get_kernel_event_by_name(event_list[i].name, kchan);
+ if (kevent == NULL) {
+ /* Default event type for enable all */
+ event_list[i].type = LTTNG_EVENT_TRACEPOINT;
+ /* Enable each single tracepoint event */
+ 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);
- free(event_list);
+ /* Quiescent wait after event enable */
+ kernel_wait_quiescent(kernel_tracer_fd);
+ break;
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
+ }
- /* Quiescent wait after event enable */
- kernel_wait_quiescent(kernel_tracer_fd);
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;
}
/* For each channel */
- cds_list_for_each_entry(chan, &cmd_ctx->session->kernel_session->channel_list.head, list) {
+ cds_list_for_each_entry(chan,
+ &cmd_ctx->session->kernel_session->channel_list.head, list) {
if (chan->stream_count == 0) {
ret = kernel_open_channel_stream(chan);
if (ret < 0) {
goto setup_error;
}
- ret = create_session(cmd_ctx->lsm->session_name, cmd_ctx->lsm->path);
+ ret = create_session(cmd_ctx->lsm->session.name, cmd_ctx->lsm->session.path);
if (ret < 0) {
if (ret == -EEXIST) {
ret = LTTCOMM_EXIST_SESS;
/* Clean kernel session teardown */
teardown_kernel_session(cmd_ctx->session);
- ret = destroy_session(cmd_ctx->lsm->session_name);
+ ret = destroy_session(cmd_ctx->lsm->session.name);
if (ret < 0) {
ret = LTTCOMM_FATAL;
goto error;
ret = LTTCOMM_OK;
break;
}
- /*
- case LTTNG_LIST_TRACES:
+ case LTTNG_LIST_DOMAINS:
{
- unsigned int trace_count;
+ size_t nb_dom = 0;
- trace_count = get_trace_count_per_session(cmd_ctx->session);
- if (trace_count == 0) {
- ret = LTTCOMM_NO_TRACE;
- goto error;
+ if (cmd_ctx->session->kernel_session != NULL) {
+ nb_dom++;
}
- ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_trace) * trace_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_traces_per_session(cmd_ctx->session,
- (struct lttng_trace *)(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_CREATE_TRACE:
- {
- ret = setup_lttng_msg(cmd_ctx, 0);
- if (ret < 0) {
- goto setup_error;
- }
-
- ret = ust_create_trace(cmd_ctx);
- if (ret < 0) {
- goto error;
- }
- break;
- }
- */
- case LTTNG_LIST_TRACEABLE_APPS:
+ case LTTNG_LIST_CHANNELS:
{
- unsigned int app_count;
-
- app_count = get_app_count();
- DBG("Traceable application count : %d", app_count);
- if (app_count == 0) {
- ret = LTTCOMM_NO_APPS;
- goto 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 = setup_lttng_msg(cmd_ctx, sizeof(pid_t) * app_count);
+ ret = setup_lttng_msg(cmd_ctx,
+ sizeof(struct lttng_channel) * nb_chan);
if (ret < 0) {
goto setup_error;
}
- get_app_list_pids((pid_t *)(cmd_ctx->llm->payload));
+ list_lttng_channels(cmd_ctx->session,
+ (struct lttng_channel *)(cmd_ctx->llm->payload));
ret = LTTCOMM_OK;
break;
}
- /*
- case UST_START_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;
- ret = ust_start_trace(cmd_ctx);
- if (ret < 0) {
- goto setup_error;
- }
- break;
- }
- case UST_STOP_TRACE:
- {
- ret = setup_lttng_msg(cmd_ctx, 0);
- if (ret < 0) {
- goto setup_error;
+ 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;
}
ret = LTTCOMM_OK;
break;
}
+
+ case LTTNG_CALIBRATE:
+ {
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ goto setup_error;
+ }
+
+ switch (cmd_ctx->lsm->domain.type) {
+ case LTTNG_DOMAIN_KERNEL:
+ {
+ struct lttng_kernel_calibrate kcalibrate;
+
+ kcalibrate.type = cmd_ctx->lsm->u.calibrate.type;
+ ret = kernel_calibrate(kernel_tracer_fd, &kcalibrate);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_ENABLE_FAIL;
+ goto error;
+ }
+ break;
+ }
+ default:
+ /* TODO: Userspace tracing */
+ ret = LTTCOMM_NOT_IMPLEMENTED;
+ goto error;
+ }
+ ret = LTTCOMM_OK;
+ break;
+ }
+
default:
/* Undefined command */
ret = setup_lttng_msg(cmd_ctx, 0);