Fix: disable kernel event based on name and event type
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 21 Sep 2015 22:43:54 +0000 (18:43 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 22 Sep 2015 16:25:41 +0000 (12:25 -0400)
The -a argument is interpreted as a zero-length event name
instead of '*' which is actually a valid wildcard event
name by itself. This simplifies how a disable command is
handled by the session daemon.

The event type can now be passed as argument and is a
new criteria while disabling kernel events. The default
is to disable for all event types.

UST and agent domain do not yet support disabling by event
type.

e.g:
# Only disable kernel event of type tracepoint.
lttng disable -a -k --tracepoint

# Only disable the event with name '*' and type syscall.
lttng disable -k '*' --syscall

# Disable all kernel event of all type.
lttng disable -a -k

Fixes #925

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/event.c
src/bin/lttng-sessiond/event.h
src/bin/lttng/commands/disable_events.c
src/lib/lttng-ctl/lttng-ctl.c

index 4391b6a58c354c6445a8195c345bc7eb91b3a561..ab57fee86bee8f3a54ebb71001b6ecb9ebeced67 100644 (file)
@@ -1219,32 +1219,22 @@ int cmd_disable_event(struct ltt_session *session, int domain,
 
                switch (event->type) {
                case LTTNG_EVENT_ALL:
-                       ret = event_kernel_disable_event_all(kchan);
-                       if (ret != LTTNG_OK) {
-                               goto error_unlock;
-                       }
-                       break;
-               case LTTNG_EVENT_TRACEPOINT:    /* fall-through */
+               case LTTNG_EVENT_TRACEPOINT:
                case LTTNG_EVENT_SYSCALL:
-                       if (!strcmp(event_name, "*")) {
-                               ret = event_kernel_disable_event_type(kchan,
-                                       event->type);
+               case LTTNG_EVENT_PROBE:
+               case LTTNG_EVENT_FUNCTION:
+               case LTTNG_EVENT_FUNCTION_ENTRY:/* fall-through */
+                       if (event_name[0] == '\0') {
+                               ret = event_kernel_disable_event(kchan,
+                                       NULL, event->type);
                        } else {
                                ret = event_kernel_disable_event(kchan,
-                                       event_name);
+                                       event_name, event->type);
                        }
                        if (ret != LTTNG_OK) {
                                goto error_unlock;
                        }
                        break;
-               case LTTNG_EVENT_PROBE:
-               case LTTNG_EVENT_FUNCTION:
-               case LTTNG_EVENT_FUNCTION_ENTRY:
-                       ret = event_kernel_disable_event(kchan, event_name);
-                       if (ret != LTTNG_OK) {
-                               goto error_unlock;
-                       }
-                       break;
                default:
                        ret = LTTNG_ERR_UNK;
                        goto error_unlock;
@@ -1267,7 +1257,7 @@ int cmd_disable_event(struct ltt_session *session, int domain,
 
                /*
                 * If a non-default channel has been created in the
-                * session, explicitely require that -c chan_name needs
+                * session, explicitly require that -c chan_name needs
                 * to be provided.
                 */
                if (usess->has_non_default_channel && channel_name[0] == '\0') {
index 869aa2dd2c374098821dab3d4f411f64cc59f523..589d88eacca6d468c5e7187baf5998f37fe8da1d 100644 (file)
@@ -60,45 +60,15 @@ static void add_unique_ust_event(struct lttng_ht *ht,
 }
 
 /*
- * Disable kernel tracepoint event for a channel from the kernel session.
+ * Disable kernel tracepoint events for a channel from the kernel session of
+ * a specified event_name and event type.
+ * On type LTTNG_EVENT_ALL all events with event_name are disabled.
+ * If event_name is NULL all events of the specified type are disabled.
  */
 int event_kernel_disable_event(struct ltt_kernel_channel *kchan,
-               char *event_name)
+               char *event_name, enum lttng_event_type type)
 {
-       int ret;
-       struct ltt_kernel_event *kevent;
-
-       assert(kchan);
-
-       kevent = trace_kernel_get_event_by_name(event_name, kchan,
-                       LTTNG_EVENT_ALL);
-       if (kevent == NULL) {
-               ret = LTTNG_ERR_NO_EVENT;
-               goto error;
-       }
-
-       ret = kernel_disable_event(kevent);
-       if (ret < 0) {
-               ret = LTTNG_ERR_KERN_DISABLE_FAIL;
-               goto error;
-       }
-
-       DBG("Kernel event %s disable for channel %s.",
-                       kevent->event->name, kchan->channel->name);
-
-       ret = LTTNG_OK;
-
-error:
-       return ret;
-}
-
-/*
- * Disable kernel tracepoint events for a channel from the kernel session.
- */
-int event_kernel_disable_event_type(struct ltt_kernel_channel *kchan,
-               enum lttng_event_type type)
-{
-       int ret;
+       int ret, error = 0, found = 0;
        struct ltt_kernel_event *kevent;
 
        assert(kchan);
@@ -107,22 +77,26 @@ int event_kernel_disable_event_type(struct ltt_kernel_channel *kchan,
        cds_list_for_each_entry(kevent, &kchan->events_list.head, list) {
                if (type != LTTNG_EVENT_ALL && kevent->type != type)
                        continue;
+               if (event_name != NULL && strcmp(event_name, kevent->event->name)) {
+                       continue;
+               }
+               found++;
                ret = kernel_disable_event(kevent);
                if (ret < 0) {
-                       /* We continue disabling the rest */
+                       error = 1;
                        continue;
                }
        }
-       ret = LTTNG_OK;
-       return ret;
-}
+       DBG("Disable kernel event: found %d events with name: %s and type: %d",
+                       found, event_name ? event_name : "NULL", type);
 
-/*
- * Disable all kernel event for a channel from the kernel session.
- */
-int event_kernel_disable_event_all(struct ltt_kernel_channel *kchan)
-{
-       return event_kernel_disable_event_type(kchan, LTTNG_EVENT_ALL);
+       if (event_name != NULL && !found) {
+               ret = LTTNG_ERR_NO_EVENT;
+       } else {
+               ret = error ? LTTNG_ERR_KERN_DISABLE_FAIL : LTTNG_OK;
+       }
+
+       return ret;
 }
 
 /*
index 2afe159a648d6f2fc8c62c0c4f21d9808b527c24..61f92438b812bf084e667807dcbbd4e6dfa512d4 100644 (file)
 #include "trace-kernel.h"
 
 int event_kernel_disable_event(struct ltt_kernel_channel *kchan,
-               char *event_name);
-int event_kernel_disable_event_type(struct ltt_kernel_channel *kchan,
-               enum lttng_event_type type);
-int event_kernel_disable_event_all(struct ltt_kernel_channel *kchan);
+               char *event_name, enum lttng_event_type event_type);
 
 int event_kernel_enable_event(struct ltt_kernel_channel *kchan,
                struct lttng_event *event, char *filter_expression,
index 7e84f798a57f746598a8723a02329b7bf13390f8..3773a9dce6ed7f06ea9e86aa843ffd3e970747a5 100644 (file)
@@ -48,8 +48,11 @@ static pid_t opt_pid;
 
 enum {
        OPT_HELP = 1,
-       OPT_USERSPACE,
-       OPT_SYSCALL,
+       OPT_TYPE_SYSCALL,
+       OPT_TYPE_TRACEPOINT,
+       OPT_TYPE_PROBE,
+       OPT_TYPE_FUNCTION,
+       OPT_TYPE_ALL,
        OPT_LIST_OPTIONS,
 };
 
@@ -66,14 +69,12 @@ static struct poptOption long_options[] = {
        {"log4j",          'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0},
        {"python",         'p', POPT_ARG_VAL, &opt_python, 1, 0, 0},
        {"kernel",         'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
-       {"syscall",        0,   POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0},
-#if 0
-       /* Not implemented yet */
-       {"userspace",      'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0},
-       {"pid",            'p', POPT_ARG_INT, &opt_pid, 0, 0, 0},
-#else
-       {"userspace",      'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
-#endif
+       {"userspace",      'u', POPT_ARG_VAL, &opt_userspace, 1, 0, 0},
+       {"syscall",          0, POPT_ARG_NONE, 0, OPT_TYPE_SYSCALL, 0, 0},
+       {"probe",            0, POPT_ARG_NONE, 0, OPT_TYPE_PROBE, 0, 0},
+       {"tracepoint",       0, POPT_ARG_NONE, 0, OPT_TYPE_TRACEPOINT, 0, 0},
+       {"function",         0, POPT_ARG_NONE, 0, OPT_TYPE_FUNCTION, 0, 0},
+       {"all",              0, POPT_ARG_NONE, 0, OPT_TYPE_ALL, 0, 0},
        {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
        {0, 0, 0, 0, 0, 0, 0}
 };
@@ -97,8 +98,12 @@ static void usage(FILE *ofp)
        fprintf(ofp, "  -l, --log4j              Apply to Java application using LOG4j\n");
        fprintf(ofp, "  -p, --python             Apply to Python application using logging\n");
        fprintf(ofp, "\n");
-       fprintf(ofp, "Event options:\n");
+       fprintf(ofp, "Event type options (Only supported with kernel domain):\n");
+       fprintf(ofp, "      --all                All event types (default)\n");
+       fprintf(ofp, "      --tracepoint         Tracepoint event\n");
        fprintf(ofp, "      --syscall            System call event\n");
+       fprintf(ofp, "      --probe              Probe event\n");
+       fprintf(ofp, "      --function           Function event\n");
        fprintf(ofp, "\n");
 }
 
@@ -114,6 +119,27 @@ const char *print_raw_channel_name(const char *name)
        return name ? : "<default>";
 }
 
+static
+const char *print_event_type(const enum lttng_event_type ev_type)
+{
+       switch (ev_type) {
+       case LTTNG_EVENT_ALL:
+               return "any";
+       case LTTNG_EVENT_TRACEPOINT:
+               return "tracepoint";
+       case LTTNG_EVENT_PROBE:
+               return "probe";
+       case LTTNG_EVENT_FUNCTION:
+               return "function";
+       case LTTNG_EVENT_FUNCTION_ENTRY:
+               return "function entry";
+       case LTTNG_EVENT_SYSCALL:
+               return "syscall";
+       default:
+               return "";
+       }
+}
+
 /* Mi print a partial event.
  * enabled is 0 or 1
  * success is 0 or 1
@@ -224,14 +250,8 @@ static int disable_events(char *session_name)
        /* Set default loglevel to any/unknown */
        event.loglevel = -1;
 
-       switch (opt_event_type) {
-       case LTTNG_EVENT_SYSCALL:
-               event.type = LTTNG_EVENT_SYSCALL;
-               break;
-       default:
-               event.type = LTTNG_EVENT_ALL;
-               break;
-       }
+       /* opt_event_type contain the event type to disable at this point */
+       event.type = opt_event_type;
 
        if (opt_disable_all) {
                command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
@@ -243,9 +263,9 @@ static int disable_events(char *session_name)
                } else {
                        enabled = 0;
                        success = 1;
-                       MSG("All %s %s are disabled in channel %s",
+                       MSG("All %s events of type %s are disabled in channel %s",
                                        get_domain_str(dom.type),
-                                       opt_event_type == LTTNG_EVENT_SYSCALL ? "system calls" : "events",
+                                       print_event_type(opt_event_type),
                                        print_channel_name(channel_name));
                }
 
@@ -266,9 +286,9 @@ static int disable_events(char *session_name)
                        event.name[sizeof(event.name) - 1] = '\0';
                        command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
                        if (command_ret < 0) {
-                               ERR("%s %s: %s (channel %s, session %s)",
-                                               opt_event_type == LTTNG_EVENT_SYSCALL ? "System call" : "Event",
+                               ERR("%s of type %s : %s (channel %s, session %s)",
                                                event_name,
+                                               print_event_type(opt_event_type),
                                                lttng_strerror(command_ret),
                                                command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
                                                        ? print_raw_channel_name(channel_name)
@@ -282,10 +302,10 @@ static int disable_events(char *session_name)
                                 */
                                enabled = 1;
                        } else {
-                               MSG("%s %s %s disabled in channel %s for session %s",
+                               MSG("%s %s of type %s disabled in channel %s for session %s",
                                                get_domain_str(dom.type),
-                                               opt_event_type == LTTNG_EVENT_SYSCALL ? "system call" : "event",
                                                event_name,
+                                               print_event_type(opt_event_type),
                                                print_channel_name(channel_name),
                                                session_name);
                                success = 1;
@@ -349,12 +369,21 @@ int cmd_disable_events(int argc, const char **argv)
                case OPT_HELP:
                        usage(stdout);
                        goto end;
-               case OPT_USERSPACE:
-                       opt_userspace = 1;
-                       break;
-               case OPT_SYSCALL:
+               case OPT_TYPE_SYSCALL:
                        opt_event_type = LTTNG_EVENT_SYSCALL;
                        break;
+               case OPT_TYPE_TRACEPOINT:
+                       opt_event_type = LTTNG_EVENT_TRACEPOINT;
+                       break;
+               case OPT_TYPE_PROBE:
+                       opt_event_type = LTTNG_EVENT_PROBE;
+                       break;
+               case OPT_TYPE_FUNCTION:
+                       opt_event_type = LTTNG_EVENT_FUNCTION;
+                       break;
+               case OPT_TYPE_ALL:
+                       opt_event_type = LTTNG_EVENT_ALL;
+                       break;
                case OPT_LIST_OPTIONS:
                        list_cmd_options(stdout, long_options);
                        goto end;
@@ -383,6 +412,15 @@ int cmd_disable_events(int argc, const char **argv)
                goto end;
        }
 
+       /* Ust and agent only support ALL event type */
+       if ((opt_userspace || opt_jul || opt_log4j || opt_python)
+                       && opt_event_type != LTTNG_EVENT_ALL) {
+               ERR("UST and agent (-j | -l | -p) event(s) disabling based on event type is not supported.\n");
+               usage(stderr);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
        opt_event_list = (char*) poptGetArg(pc);
        if (opt_event_list == NULL && opt_disable_all == 0) {
                ERR("Missing event name(s).\n");
index 19b9e5117f3c6bf4696d74224f1de0d7f20e0fe9..615bf796f5aedae7ae607502b2a514f3d887d0e0 100644 (file)
@@ -1091,10 +1091,6 @@ int lttng_disable_event_ext(struct lttng_handle *handle,
        }
 
        lsm.cmd_type = LTTNG_DISABLE_EVENT;
-       if (ev->name[0] == '\0') {
-               /* Disable all events */
-               lttng_ctl_copy_string(ev->name, "*", sizeof(ev->name));
-       }
 
        lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
        /* FIXME: copying non-packed struct to packed struct. */
This page took 0.035012 seconds and 4 git commands to generate.