From 19e708528b7ebd740485ca05056e56e6835d43a7 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 29 Jun 2011 13:27:09 -0400 Subject: [PATCH] Add enable kernel event using the enable ioctl Two helper functions are added which are get an event by name and a channel by name. The disable and enable event command was modified to use these two functions. Overall, it's now possible to enable/disable at will kernel events. Signed-off-by: David Goulet --- ltt-sessiond/kernel-ctl.c | 50 +++++++++++++++++-------- ltt-sessiond/kernel-ctl.h | 5 ++- ltt-sessiond/main.c | 79 ++++++++++++++++++++------------------- ltt-sessiond/trace.c | 53 ++++++++++++++++++++++++++ ltt-sessiond/trace.h | 8 ++++ 5 files changed, 138 insertions(+), 57 deletions(-) diff --git a/ltt-sessiond/kernel-ctl.c b/ltt-sessiond/kernel-ctl.c index 2f1864d64..16b85bdb5 100644 --- a/ltt-sessiond/kernel-ctl.c +++ b/ltt-sessiond/kernel-ctl.c @@ -124,7 +124,7 @@ error: * Create a kernel event, enable it to the kernel tracer and add it to the * channel event list of the kernel session. */ -int kernel_create_event(struct ltt_kernel_channel *channel, struct lttng_event *ev) +int kernel_create_event(struct lttng_event *ev, struct ltt_kernel_channel *channel) { int ret; struct ltt_kernel_event *event; @@ -161,29 +161,47 @@ error: } /* - * kernel_disable_event + * kernel_enable_event * - * Disable a kernel event for a specific channel. + * Enable a kernel event. */ -int kernel_disable_event(char *event_name, struct ltt_kernel_channel *channel) +int kernel_enable_event(struct ltt_kernel_event *event) { int ret; - struct ltt_kernel_event *iter; - cds_list_for_each_entry(iter, &channel->events_list.head, list) { - if (strcmp(iter->event->name, event_name) == 0) { - ret = kernctl_disable(iter->fd); - if (ret < 0) { - perror("disable event ioctl"); - goto error; - } + ret = kernctl_enable(event->fd); + if (ret < 0) { + perror("enable event ioctl"); + goto error; + } - iter->enabled = 0; - DBG("Kernel event %s disabled (fd: %d)", iter->event->name, iter->fd); - break; - } + event->enabled = 1; + DBG("Kernel event %s enabled (fd: %d)", event->event->name, event->fd); + + return 0; + +error: + return -1; +} + +/* + * kernel_disable_event + * + * Disable a kernel event. + */ +int kernel_disable_event(struct ltt_kernel_event *event) +{ + int ret; + + ret = kernctl_disable(event->fd); + if (ret < 0) { + perror("disable event ioctl"); + goto error; } + event->enabled = 0; + DBG("Kernel event %s disabled (fd: %d)", event->event->name, event->fd); + return 0; error: diff --git a/ltt-sessiond/kernel-ctl.h b/ltt-sessiond/kernel-ctl.h index adc930d1c..d36cd6d10 100644 --- a/ltt-sessiond/kernel-ctl.h +++ b/ltt-sessiond/kernel-ctl.h @@ -32,8 +32,9 @@ int kernel_create_session(struct ltt_session *session, int tracer_fd); int kernel_create_channel(struct ltt_kernel_session *session, struct lttng_channel *chan); -int kernel_create_event(struct ltt_kernel_channel *channel, struct lttng_event *ev); -int kernel_disable_event(char *event_name, struct ltt_kernel_channel *channel); +int kernel_create_event(struct lttng_event *ev, struct ltt_kernel_channel *channel); +int kernel_disable_event(struct ltt_kernel_event *event); +int kernel_enable_event(struct ltt_kernel_event *event); int kernel_open_metadata(struct ltt_kernel_session *session); int kernel_open_metadata_stream(struct ltt_kernel_session *session); int kernel_open_channel_stream(struct ltt_kernel_channel *channel); diff --git a/ltt-sessiond/main.c b/ltt-sessiond/main.c index 4da3caba0..5a8119f91 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -875,8 +875,8 @@ static int process_client_msg(struct command_ctx *cmd_ctx) } case LTTNG_KERNEL_DISABLE_EVENT: { - int found = 0; struct ltt_kernel_channel *chan; + struct ltt_kernel_event *ev; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -884,34 +884,32 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_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.disable.channel_name, chan->channel->name) == 0) { - DBG("Disabling kernel event %s for channel %s.", - cmd_ctx->lsm->u.disable.name, cmd_ctx->lsm->u.disable.channel_name); + 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; + } - ret = kernel_disable_event(cmd_ctx->lsm->u.disable.name, chan); - if (ret < 0) { - ret = LTTCOMM_KERN_DISABLE_FAIL; - goto error; - } - found = 1; - break; + 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; + goto error; } } - if (!found) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; - } else { - kernel_wait_quiescent(kernel_tracer_fd); - ret = LTTCOMM_OK; - } + kernel_wait_quiescent(kernel_tracer_fd); + ret = LTTCOMM_OK; break; } case LTTNG_KERNEL_ENABLE_EVENT: { - int found = 0; struct ltt_kernel_channel *chan; + struct ltt_kernel_event *ev; /* Setup lttng message with no payload */ ret = setup_lttng_msg(cmd_ctx, 0); @@ -919,28 +917,31 @@ static int process_client_msg(struct command_ctx *cmd_ctx) goto setup_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) { - DBG("Creating kernel event %s for channel %s.", - cmd_ctx->lsm->u.enable.event.name, cmd_ctx->lsm->u.enable.channel_name); - - ret = kernel_create_event(chan, &cmd_ctx->lsm->u.enable.event); - if (ret < 0) { - ret = LTTCOMM_KERN_ENABLE_FAIL; - goto error; - } - found = 1; - break; - } + 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; } - if (!found) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; + 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); + ret = kernel_create_event(&cmd_ctx->lsm->u.enable.event, chan); } else { - kernel_wait_quiescent(kernel_tracer_fd); - ret = LTTCOMM_OK; + DBG("Enabling kernel event %s for channel %s.", + cmd_ctx->lsm->u.enable.event.name, cmd_ctx->lsm->u.enable.channel_name); + ret = kernel_enable_event(ev); + } + + if (ret < 0) { + ret = LTTCOMM_KERN_ENABLE_FAIL; + goto error; } + + kernel_wait_quiescent(kernel_tracer_fd); + ret = LTTCOMM_OK; break; } case LTTNG_KERNEL_ENABLE_ALL_EVENT: @@ -983,7 +984,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx) /* Default event type for enable all */ ev.type = LTTNG_EVENT_TRACEPOINTS; /* Enable each single tracepoint event */ - ret = kernel_create_event(chan, &ev); + ret = kernel_create_event(&ev, chan); if (ret < 0) { ret = LTTCOMM_KERN_ENABLE_FAIL; goto error; diff --git a/ltt-sessiond/trace.c b/ltt-sessiond/trace.c index e0051cd1c..eb7d0e152 100644 --- a/ltt-sessiond/trace.c +++ b/ltt-sessiond/trace.c @@ -27,6 +27,59 @@ #include "ltt-sessiond.h" #include "trace.h" +/* + * get_kernel_channel_by_name + * + * Find the channel name for the given kernel session. + */ +struct ltt_kernel_channel *get_kernel_channel_by_name( + char *name, struct ltt_kernel_session *session) +{ + struct ltt_kernel_channel *chan; + + if (session == NULL) { + ERR("Undefine session"); + goto error; + } + + cds_list_for_each_entry(chan, &session->channel_list.head, list) { + if (strcmp(name, chan->channel->name) == 0) { + DBG("Found channel by name %s", name); + return chan; + } + } + +error: + return NULL; +} + +/* + * get_kernel_event_by_name + * + * Find the event name for the given channel. + */ +struct ltt_kernel_event *get_kernel_event_by_name( + char *name, struct ltt_kernel_channel *channel) +{ + struct ltt_kernel_event *ev; + + if (channel == NULL) { + ERR("Undefine channel"); + goto error; + } + + cds_list_for_each_entry(ev, &channel->events_list.head, list) { + if (strcmp(name, ev->event->name) == 0) { + DBG("Found event by name %s for channel %s", name, + channel->channel->name); + return ev; + } + } + +error: + return NULL; +} + /* * trace_create_kernel_session * diff --git a/ltt-sessiond/trace.h b/ltt-sessiond/trace.h index 8da147230..427b05b88 100644 --- a/ltt-sessiond/trace.h +++ b/ltt-sessiond/trace.h @@ -101,6 +101,14 @@ struct ltt_ust_marker { char *channel; }; +/* + * Get functions. + */ +struct ltt_kernel_event *get_kernel_event_by_name( + char *name, struct ltt_kernel_channel *channel); +struct ltt_kernel_channel *get_kernel_channel_by_name( + char *name, struct ltt_kernel_session *session); + /* * Create functions malloc() the data structure. */ -- 2.34.1