#include "traceable-app.h"
#include "lttng-kconsumerd.h"
#include "libustctl.h"
+#include "utils.h"
/*
* TODO:
/* Create all channel directories */
cds_list_for_each_entry(chan, &session->channel_list.head, list) {
DBG("Creating trace directory at %s", chan->pathname);
- // TODO: recursive create dir
- ret = mkdir(chan->pathname, S_IRWXU | S_IRWXG );
+ ret = mkdir_recursive(chan->pathname, S_IRWXU | S_IRWXG );
if (ret < 0) {
if (ret != EEXIST) {
- perror("mkdir trace path");
- ret = -errno;
+ ERR("Trace directory creation error");
goto error;
}
}
chan->attr.num_subbuf = DEFAULT_CHANNEL_SUBBUF_NUM;
chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
+ chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
error:
return chan;
* Check kernel command for kernel session.
*/
switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_KERNEL_ADD_CONTEXT:
case LTTNG_KERNEL_CREATE_CHANNEL:
case LTTNG_KERNEL_DISABLE_ALL_EVENT:
case LTTNG_KERNEL_DISABLE_CHANNEL:
/* Process by command type */
switch (cmd_ctx->lsm->cmd_type) {
+ case LTTNG_KERNEL_ADD_CONTEXT:
+ {
+ int found = 0, no_event = 0;
+ struct ltt_kernel_channel *chan;
+ struct ltt_kernel_event *event;
+
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 0) {
+ goto setup_error;
+ }
+
+ /* Check if event name is given */
+ if (strlen(cmd_ctx->lsm->u.context.event_name) == 0) {
+ no_event = 1;
+ }
+
+ 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,
+ &cmd_ctx->lsm->u.context.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,
+ &cmd_ctx->lsm->u.context.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;
+ goto error;
+ }
+
+ if (no_event) {
+ ret = kernel_add_channel_context(chan,
+ &cmd_ctx->lsm->u.context.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,
+ &cmd_ctx->lsm->u.context.ctx);
+ if (ret < 0) {
+ ret = LTTCOMM_KERN_CONTEXT_FAIL;
+ goto error;
+ }
+ }
+ }
+ }
+
+ if (!found && !no_event) {
+ ret = LTTCOMM_NO_EVENT;
+ goto error;
+ }
+
+ ret = LTTCOMM_OK;
+ break;
+ }
case LTTNG_KERNEL_CREATE_CHANNEL:
{
/* Setup lttng message with no payload */
ret = LTTCOMM_OK;
break;
}
+ case LTTNG_KERNEL_DISABLE_CHANNEL:
+ {
+ struct ltt_kernel_channel *chan;
+
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 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;
+ }
+ goto error;
+ }
+ }
+
+ kernel_wait_quiescent(kernel_tracer_fd);
+ ret = LTTCOMM_OK;
+ break;
+ }
case LTTNG_KERNEL_DISABLE_EVENT:
{
struct ltt_kernel_channel *chan;
ret = LTTCOMM_OK;
break;
}
+ case LTTNG_KERNEL_DISABLE_ALL_EVENT:
+ {
+ struct ltt_kernel_channel *chan;
+ struct ltt_kernel_event *ev;
+
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 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;
+ }
+
+ /* 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;
+ }
+ }
+
+ /* Quiescent wait after event disable */
+ kernel_wait_quiescent(kernel_tracer_fd);
+ ret = LTTCOMM_OK;
+ break;
+ }
+ case LTTNG_KERNEL_ENABLE_CHANNEL:
+ {
+ struct ltt_kernel_channel *chan;
+
+ /* Setup lttng message with no payload */
+ ret = setup_lttng_msg(cmd_ctx, 0);
+ if (ret < 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) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ goto error;
+ } else if (chan->enabled == 0) {
+ ret = kernel_enable_channel(chan);
+ if (ret < 0) {
+ if (ret != EEXIST) {
+ ret = LTTCOMM_KERN_CHAN_ENABLE_FAIL;
+ }
+ goto error;
+ }
+ }
+
+ kernel_wait_quiescent(kernel_tracer_fd);
+ ret = LTTCOMM_OK;
+ break;
+ }
case LTTNG_KERNEL_ENABLE_EVENT:
{
struct ltt_kernel_channel *chan;
ev = get_kernel_event_by_name(cmd_ctx->lsm->u.enable.event.name, chan);
if (ev == NULL) {
DBG("Creating kernel event %s for channel %s.",
- cmd_ctx->lsm->u.enable.event.name, cmd_ctx->lsm->u.enable.channel_name);
+ cmd_ctx->lsm->u.enable.event.name, chan->channel->name);
ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, chan);
} else {
DBG("Enabling kernel event %s for channel %s.",
- cmd_ctx->lsm->u.enable.event.name, cmd_ctx->lsm->u.enable.channel_name);
+ cmd_ctx->lsm->u.enable.event.name, chan->channel->name);
ret = kernel_enable_event(ev);
}
}
case LTTNG_KERNEL_ENABLE_ALL_EVENT:
{
- int pos, size, found;
+ int pos, size;
char *event_list, *event, *ptr;
struct ltt_kernel_channel *chan;
- struct lttng_event ev;
+ struct ltt_kernel_event *ev;
+ struct lttng_event ev_attr;
/* Setup lttng message with no payload */
ret = setup_lttng_msg(cmd_ctx, 0);
DBG("Enabling all kernel event");
- size = kernel_list_events(kernel_tracer_fd, &event_list);
- if (size < 0) {
- ret = LTTCOMM_KERN_LIST_FAIL;
+ chan = get_kernel_channel_by_name(cmd_ctx->lsm->u.enable.channel_name,
+ cmd_ctx->session->kernel_session);
+ if (chan == NULL) {
+ ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
goto error;
}
- /* Get channel by name and create event for that channel */
- cds_list_for_each_entry(chan, &cmd_ctx->session->kernel_session->channel_list.head, list) {
- if (strcmp(cmd_ctx->lsm->u.enable.channel_name, chan->channel->name) == 0) {
- found = 1;
- break;
+ /* For each event in the kernel session */
+ cds_list_for_each_entry(ev, &chan->events_list.head, list) {
+ DBG("Enabling kernel event %s for channel %s.",
+ ev->event->name, chan->channel->name);
+ ret = kernel_enable_event(ev);
+ if (ret < 0) {
+ continue;
}
}
- if (!found) {
- ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+ 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) {
- strncpy(ev.name, event, LTTNG_SYM_NAME_LEN);
- /* Default event type for enable all */
- ev.type = LTTNG_EVENT_TRACEPOINTS;
- /* Enable each single tracepoint event */
- ret = kernel_create_event(&ev, chan);
- if (ret < 0) {
- ret = LTTCOMM_KERN_ENABLE_FAIL;
- goto error;
+ ev = get_kernel_event_by_name(event, chan);
+ if (ev == NULL) {
+ strncpy(ev_attr.name, event, LTTNG_SYM_NAME_LEN);
+ /* Default event type for enable all */
+ ev_attr.type = LTTNG_EVENT_TRACEPOINTS;
+ /* Enable each single tracepoint event */
+ ret = kernel_create_event(&ev_attr, chan);
+ if (ret < 0) {
+ /* Ignore error here and continue */
+ }
}
+
/* Move pointer to the next line */
ptr += pos + 1;
free(event);