From: David Goulet Date: Wed, 29 Jun 2011 16:48:35 +0000 (-0400) Subject: Add disable kernel event support X-Git-Tag: v2.0-pre1~74 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=e953ef25cbc11fb112aa2e23bf2d44867fe585ed;p=lttng-tools.git Add disable kernel event support Signed-off-by: David Goulet --- diff --git a/ltt-sessiond/kernel-ctl.c b/ltt-sessiond/kernel-ctl.c index 3925c6ba5..2f1864d64 100644 --- a/ltt-sessiond/kernel-ctl.c +++ b/ltt-sessiond/kernel-ctl.c @@ -136,11 +136,12 @@ int kernel_create_event(struct ltt_kernel_channel *channel, struct lttng_event * ret = kernctl_create_event(channel->fd, event->event); if (ret < 0) { - ERR("Unable to enable event %s for channel %s", ev->name, channel->channel->name); - goto error; + perror("create event ioctl"); + goto free_event; } event->fd = ret; + event->enabled = 1; /* Prevent fd duplication after execlp() */ ret = fcntl(event->fd, F_SETFD, FD_CLOEXEC); if (ret < 0) { @@ -149,7 +150,39 @@ int kernel_create_event(struct ltt_kernel_channel *channel, struct lttng_event * /* Add event to event list */ cds_list_add(&event->list, &channel->events_list.head); - DBG("Event %s enabled (fd: %d)", ev->name, event->fd); + DBG("Event %s created (fd: %d)", ev->name, event->fd); + + return 0; + +free_event: + free(event); +error: + return -1; +} + +/* + * kernel_disable_event + * + * Disable a kernel event for a specific channel. + */ +int kernel_disable_event(char *event_name, struct ltt_kernel_channel *channel) +{ + 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; + } + + iter->enabled = 0; + DBG("Kernel event %s disabled (fd: %d)", iter->event->name, iter->fd); + break; + } + } return 0; diff --git a/ltt-sessiond/kernel-ctl.h b/ltt-sessiond/kernel-ctl.h index e100c1b08..adc930d1c 100644 --- a/ltt-sessiond/kernel-ctl.h +++ b/ltt-sessiond/kernel-ctl.h @@ -33,6 +33,7 @@ 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_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 05114e1f2..1c6b6da6f 100644 --- a/ltt-sessiond/main.c +++ b/ltt-sessiond/main.c @@ -876,6 +876,41 @@ static int process_client_msg(struct command_ctx *cmd_ctx) ret = LTTCOMM_OK; break; } + case LTTNG_KERNEL_DISABLE_EVENT: + { + int found = 0; + struct ltt_kernel_channel *chan; + + /* Setup lttng message with no payload */ + ret = setup_lttng_msg(cmd_ctx, 0); + if (ret < 0) { + 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); + + ret = kernel_disable_event(cmd_ctx->lsm->u.disable.name, chan); + if (ret < 0) { + ret = LTTCOMM_KERN_DISABLE_FAIL; + goto error; + } + found = 1; + break; + } + } + + if (!found) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; + } else { + kernel_wait_quiescent(kernel_tracer_fd); + ret = LTTCOMM_OK; + } + break; + } case LTTNG_KERNEL_ENABLE_EVENT: { int found = 0; diff --git a/ltt-sessiond/trace.h b/ltt-sessiond/trace.h index 8fdef2a37..8da147230 100644 --- a/ltt-sessiond/trace.h +++ b/ltt-sessiond/trace.h @@ -44,6 +44,7 @@ struct ltt_kernel_channel_list { /* Kernel event */ struct ltt_kernel_event { int fd; + int enabled; struct lttng_kernel_event *event; struct cds_list_head list; }; diff --git a/lttng/Makefile.am b/lttng/Makefile.am index fcea4668a..a2afb9fad 100644 --- a/lttng/Makefile.am +++ b/lttng/Makefile.am @@ -5,7 +5,7 @@ bin_PROGRAMS = lttng lttng_SOURCES = conf.c commands/start.c commands/add_channel.c \ commands/list.c commands/create.c commands/destroy.c \ commands/stop.c commands/enable_events.c \ - utils.c lttng.c + commands/disable_events.c utils.c lttng.c lttng_LDADD = \ $(top_builddir)/liblttngctl/liblttngctl.la diff --git a/lttng/cmd.h b/lttng/cmd.h index 02ebfcc1d..d932d2eb0 100644 --- a/lttng/cmd.h +++ b/lttng/cmd.h @@ -44,5 +44,6 @@ extern int cmd_add_channel(int argc, const char **argv); extern int cmd_start(int argc, const char **argv); extern int cmd_stop(int argc, const char **argv); extern int cmd_enable_events(int argc, const char **argv); +extern int cmd_disable_events(int argc, const char **argv); #endif /* _LTTNG_CMD_H */ diff --git a/lttng/commands/disable_events.c b/lttng/commands/disable_events.c new file mode 100644 index 000000000..5bfe5d55b --- /dev/null +++ b/lttng/commands/disable_events.c @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2011 - David Goulet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include "cmd.h" +#include "conf.h" +#include "utils.h" + +static char *opt_event_list; +static char *opt_kernel; +static char *opt_cmd_name; +static char *opt_channel_name; +static int opt_pid_all; +static int opt_userspace; +static int opt_disable_all; +static pid_t opt_pid; + +enum { + OPT_HELP = 1, + OPT_USERSPACE, +}; + +static struct poptOption long_options[] = { + /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ + {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, + {"all-events", 'a', POPT_ARG_VAL, &opt_disable_all, 1, 0, 0}, + {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0}, + {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0}, + {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, 0, OPT_USERSPACE, 0, 0}, + {"all", 0, POPT_ARG_VAL, &opt_pid_all, 1, 0, 0}, + {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0} +}; + +/* + * usage + */ +static void usage(FILE *ofp) +{ + fprintf(ofp, "usage: lttng disable-event NAME[,NAME2,...] [options]\n"); + fprintf(ofp, "\n"); + fprintf(ofp, " -h, --help Show this help\n"); + fprintf(ofp, " -c, --channel Apply on this channel\n"); + fprintf(ofp, " -a, --all-events Enable all tracepoints\n"); + fprintf(ofp, " -k, --kernel Apply for the kernel tracer\n"); + fprintf(ofp, " -u, --userspace [CMD] Apply for the user-space tracer\n"); + fprintf(ofp, " --all If -u, apply on all traceable apps\n"); + fprintf(ofp, " -p, --pid PID If -u, apply on a specific PID\n"); + fprintf(ofp, "\n"); +} + +/* + * disable_events + * + * Disabling event using the lttng API. + */ +static int disable_events(void) +{ + int err, ret = CMD_SUCCESS; + char *event_name, *channel_name; + struct lttng_event ev; + + if (set_session_name() < 0) { + ret = CMD_ERROR; + goto error; + } + + if (opt_channel_name == NULL) { + err = asprintf(&channel_name, DEFAULT_CHANNEL_NAME); + if (err < 0) { + ret = CMD_FATAL; + goto error; + } + } else { + channel_name = opt_channel_name; + } + + if (opt_disable_all) { + if (opt_kernel) { + ret = lttng_kernel_disable_event(NULL, channel_name); + goto error; + } + + /* TODO: User-space tracer */ + } + + /* Strip event list */ + event_name = strtok(opt_event_list, ","); + while (event_name != NULL) { + /* Kernel tracer action */ + if (opt_kernel) { + DBG("Disabling kernel event %s for channel %s", + event_name, channel_name); + + /* Copy name and type of the event */ + strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); + ret = lttng_kernel_disable_event(event_name, channel_name); + if (ret < 0) { + MSG("Unable to disable event %s for channel %s", + event_name, channel_name); + } else { + MSG("Kernel event %s disabled for channel %s", + event_name, channel_name); + } + } else if (opt_userspace) { /* User-space tracer action */ + /* + * TODO: Waiting on lttng UST 2.0 + */ + if (opt_pid_all) { + } else if (opt_pid != 0) { + } + ret = CMD_NOT_IMPLEMENTED; + goto error; + } else { + ERR("Please specify a tracer (kernel or user-space)"); + goto error; + } + + /* Next event */ + event_name = strtok(NULL, ","); + } + +error: + return ret; +} + +/* + * cmd_disable_events + * + * Disable event to trace session + */ +int cmd_disable_events(int argc, const char **argv) +{ + int opt, ret; + static poptContext pc; + + pc = poptGetContext(NULL, argc, argv, long_options, 0); + poptReadDefaultConfig(pc, 0); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case OPT_HELP: + usage(stderr); + ret = CMD_SUCCESS; + goto end; + case OPT_USERSPACE: + opt_userspace = 1; + opt_cmd_name = poptGetOptArg(pc); + break; + default: + usage(stderr); + ret = CMD_UNDEFINED; + goto end; + } + } + + opt_event_list = (char*) poptGetArg(pc); + if (opt_event_list == NULL && opt_disable_all == 0) { + ERR("Missing event name(s).\n"); + usage(stderr); + ret = CMD_SUCCESS; + goto end; + } + + ret = disable_events(); + +end: + return ret; +} diff --git a/lttng/lttng.c b/lttng/lttng.c index 5f0699119..84d10eb72 100644 --- a/lttng/lttng.c +++ b/lttng/lttng.c @@ -63,6 +63,7 @@ static struct cmd_struct commands[] = { { "start", cmd_start}, { "stop", cmd_stop}, { "enable-event", cmd_enable_events}, + { "disable-event", cmd_disable_events}, { NULL, NULL} /* Array closure */ };