Implement support for lttng-modules syscall filtering
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 9 Sep 2014 22:56:13 +0000 (18:56 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Thu, 25 Sep 2014 15:36:07 +0000 (11:36 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
15 files changed:
include/lttng/event.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/event.c
src/bin/lttng-sessiond/event.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/main.c
src/bin/lttng/commands/disable_events.c
src/bin/lttng/commands/enable_events.c
src/common/kernel-ctl/kernel-ctl.c
src/common/kernel-ctl/kernel-ctl.h
src/common/lttng-kernel.h
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/lttng-ctl.c

index 40673a4d8f56bc525d0417fe9472093f43349344..b3bb2150766f4f2558707f086c251c8ec68b5258 100644 (file)
@@ -343,6 +343,23 @@ extern int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
 extern int lttng_disable_event(struct lttng_handle *handle,
                const char *name, const char *channel_name);
 
+/*
+ * Disable event(s) of a channel and domain.
+ *
+ * Takes a struct lttng_event as parameter.
+ * If channel_name is NULL, the default channel is used (channel0).
+ *
+ * Currently, @filter_expression must be NULL. (disabling specific
+ * filter expressions not implemented)
+ * Currently, only LTTNG_EVENT_ALL and LTTNG_EVENT_SYSCALL event types
+ * are implemented for field @ev.
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_disable_event_ext(struct lttng_handle *handle,
+               struct lttng_event *ev, const char *channel_name,
+               const char *filter_expression);
+
 #ifdef __cplusplus
 }
 #endif
index d2673a9019044a40af39341795c42f566d3ce03f..872a6cea160940c59e7a0d2bf6699dd7208a8ce3 100644 (file)
@@ -1000,9 +1000,18 @@ error:
  * Command LTTNG_DISABLE_EVENT processed by the client thread.
  */
 int cmd_disable_event(struct ltt_session *session, int domain,
-               char *channel_name, char *event_name)
+               char *channel_name,
+               struct lttng_event *event)
 {
        int ret;
+       char *event_name;
+
+       event_name = event->name;
+
+       if (event->loglevel_type || event->loglevel || event->enabled
+                       || event->pid || event->filter || event->exclusion) {
+               return LTTNG_ERR_UNK;
+       }
 
        rcu_read_lock();
 
@@ -1030,8 +1039,19 @@ int cmd_disable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_disable_tracepoint(kchan, event_name);
-               if (ret != LTTNG_OK) {
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+               case LTTNG_EVENT_TRACEPOINT:
+                       ret = event_kernel_disable_tracepoint(kchan, event_name);
+                       if (ret != LTTNG_OK) {
+                               goto error;
+                       }
+                       break;
+               case LTTNG_EVENT_SYSCALL:
+                       ret = event_kernel_disable_syscall(kchan, event_name);
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
                        goto error;
                }
 
@@ -1062,8 +1082,15 @@ int cmd_disable_event(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_ust_disable_tracepoint(usess, uchan, event_name);
-               if (ret != LTTNG_OK) {
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+                       ret = event_ust_disable_tracepoint(usess, uchan, event_name);
+                       if (ret != LTTNG_OK) {
+                               goto error;
+                       }
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
                        goto error;
                }
 
@@ -1079,6 +1106,14 @@ int cmd_disable_event(struct ltt_session *session, int domain,
 
                assert(usess);
 
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
+                       goto error;
+               }
+
                agt = trace_ust_find_agent(usess, domain);
                if (!agt) {
                        ret = -LTTNG_ERR_UST_EVENT_NOT_FOUND;
@@ -1113,9 +1148,13 @@ error:
  * Command LTTNG_DISABLE_ALL_EVENT processed by the client thread.
  */
 int cmd_disable_event_all(struct ltt_session *session, int domain,
-               char *channel_name)
+               char *channel_name,
+               struct lttng_event *event)
 {
        int ret;
+       char *event_name;
+
+       event_name = event->name;
 
        rcu_read_lock();
 
@@ -1143,8 +1182,18 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_kernel_disable_all(kchan);
-               if (ret != LTTNG_OK) {
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+                       ret = event_kernel_disable_all(kchan);
+                       if (ret != LTTNG_OK) {
+                               goto error;
+                       }
+                       break;
+               case LTTNG_EVENT_SYSCALL:
+                       ret = event_kernel_disable_syscall(kchan, event_name);
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
                        goto error;
                }
 
@@ -1175,8 +1224,15 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
                        goto error;
                }
 
-               ret = event_ust_disable_all_tracepoints(usess, uchan);
-               if (ret != 0) {
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+                       ret = event_ust_disable_all_tracepoints(usess, uchan);
+                       if (ret != 0) {
+                               goto error;
+                       }
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
                        goto error;
                }
 
@@ -1192,6 +1248,14 @@ int cmd_disable_event_all(struct ltt_session *session, int domain,
 
                assert(usess);
 
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
+                       goto error;
+               }
+
                agt = trace_ust_find_agent(usess, domain);
                if (!agt) {
                        ret = -LTTNG_ERR_UST_EVENT_NOT_FOUND;
@@ -1419,12 +1483,23 @@ int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain,
                        goto error;
                }
 
-               ret = event_kernel_enable_tracepoint(kchan, event);
-               if (ret != LTTNG_OK) {
-                       if (channel_created) {
-                               /* Let's not leak a useless channel. */
-                               kernel_destroy_channel(kchan);
+               switch (event->type) {
+               case LTTNG_EVENT_ALL:
+               case LTTNG_EVENT_TRACEPOINT:
+                       ret = event_kernel_enable_tracepoint(kchan, event);
+                       if (ret != LTTNG_OK) {
+                               if (channel_created) {
+                                       /* Let's not leak a useless channel. */
+                                       kernel_destroy_channel(kchan);
+                               }
+                               goto error;
                        }
+                       break;
+               case LTTNG_EVENT_SYSCALL:
+                       ret = event_kernel_enable_syscall(kchan, event->name);
+                       break;
+               default:
+                       ret = LTTNG_ERR_UNK;
                        goto error;
                }
 
@@ -1625,7 +1700,7 @@ int cmd_enable_event_all(struct ltt_session *session,
 
                switch (event_type) {
                case LTTNG_EVENT_SYSCALL:
-                       ret = event_kernel_enable_all_syscalls(kchan, kernel_tracer_fd);
+                       ret = event_kernel_enable_syscall(kchan, "");
                        break;
                case LTTNG_EVENT_TRACEPOINT:
                        /*
index 5de3590abf646becf6b3a8d52865175106596e7a..5312eca61714b02d73cca5d2a5d0ff4a4056080f 100644 (file)
@@ -43,9 +43,11 @@ int cmd_enable_channel(struct ltt_session *session,
 
 /* Event commands */
 int cmd_disable_event(struct ltt_session *session, int domain,
-               char *channel_name, char *event_name);
+               char *channel_name,
+               struct lttng_event *event);
 int cmd_disable_event_all(struct ltt_session *session, int domain,
-               char *channel_name);
+               char *channel_name,
+               struct lttng_event *event);
 int cmd_add_context(struct ltt_session *session, int domain,
                char *channel_name, struct lttng_event_context *ctx, int kwpipe);
 int cmd_set_filter(struct ltt_session *session, int domain,
index cdfc1a8649cd0c8c7242c745ad4733df4b6829fd..099cbd18db8ea42d767951f094df5dfd81856fbe 100644 (file)
@@ -57,21 +57,6 @@ static void add_unique_ust_event(struct lttng_ht *ht,
        assert(node_ptr == &event->node.node);
 }
 
-/*
- * Setup a lttng_event used to enable *all* syscall tracing.
- */
-static void init_syscalls_kernel_event(struct lttng_event *event)
-{
-       assert(event);
-
-       event->name[0] = '\0';
-       /*
-        * We use LTTNG_EVENT* here since the trace kernel creation will make the
-        * right changes for the kernel.
-        */
-       event->type = LTTNG_EVENT_SYSCALL;
-}
-
 /*
  * Disable kernel tracepoint event for a channel from the kernel session.
  */
@@ -104,6 +89,57 @@ error:
        return ret;
 }
 
+/*
+ * Enable kernel system call for a channel from the kernel session.
+ */
+int event_kernel_enable_syscall(struct ltt_kernel_channel *kchan,
+               char *syscall_name)
+{
+       int ret;
+
+       assert(kchan);
+
+       ret = kernel_enable_syscall(syscall_name, kchan);
+       if (ret < 0) {
+               ret = LTTNG_ERR_KERN_ENABLE_FAIL;
+               goto error;
+       }
+
+       DBG("Kernel event %s enable for channel %s.",
+                       syscall_name, kchan->channel->name);
+
+       ret = LTTNG_OK;
+
+error:
+       return ret;
+}
+
+/*
+ * Disable kernel system call for a channel from the kernel session.
+ */
+int event_kernel_disable_syscall(struct ltt_kernel_channel *kchan,
+               char *syscall_name)
+{
+       int ret;
+
+       assert(kchan);
+
+       ret = kernel_disable_syscall(syscall_name, kchan);
+       if (ret < 0) {
+               ret = LTTNG_ERR_KERN_DISABLE_FAIL;
+               goto error;
+       }
+
+       DBG("Kernel syscall %s disable for channel %s.",
+                       syscall_name[0] == '\0' ? "<all>" : syscall_name,
+                       kchan->channel->name);
+
+       ret = LTTNG_OK;
+
+error:
+       return ret;
+}
+
 /*
  * Disable kernel tracepoint events for a channel from the kernel session.
  */
@@ -126,15 +162,6 @@ int event_kernel_disable_all_tracepoints(struct ltt_kernel_channel *kchan)
        return ret;
 }
 
-/*
- * Disable kernel syscall events for a channel from the kernel session.
- */
-int event_kernel_disable_all_syscalls(struct ltt_kernel_channel *kchan)
-{
-       ERR("Cannot disable syscall tracing for existing session. Please destroy session instead.");
-       return LTTNG_OK;        /* Return OK so disable all succeeds */
-}
-
 /*
  * Disable all kernel event for a channel from the kernel session.
  */
@@ -147,7 +174,7 @@ int event_kernel_disable_all(struct ltt_kernel_channel *kchan)
        ret = event_kernel_disable_all_tracepoints(kchan);
        if (ret != LTTNG_OK)
                return ret;
-       ret = event_kernel_disable_all_syscalls(kchan);
+       ret = event_kernel_disable_syscall(kchan, "");
        return ret;
 }
 
@@ -245,36 +272,6 @@ end:
        return ret;
 }
 
-/*
- * Enable all kernel sycalls events of a channel of the kernel session.
- */
-int event_kernel_enable_all_syscalls(struct ltt_kernel_channel *kchan,
-               int kernel_tracer_fd)
-{
-       int ret;
-       struct lttng_event event;
-
-       assert(kchan);
-
-       init_syscalls_kernel_event(&event);
-
-       DBG("Enabling all syscall tracing");
-
-       ret = kernel_create_event(&event, kchan);
-       if (ret < 0) {
-               if (ret == -EEXIST) {
-                       ret = LTTNG_ERR_KERN_EVENT_EXIST;
-               } else {
-                       ret = LTTNG_ERR_KERN_ENABLE_FAIL;
-               }
-               goto end;
-       }
-
-       ret = LTTNG_OK;
-end:
-       return ret;
-}
-
 /*
  * Enable all kernel events of a channel of the kernel session.
  */
@@ -299,7 +296,7 @@ int event_kernel_enable_all(struct ltt_kernel_channel *kchan,
         * tracepoints did not fail. Future work will allow us to send back
         * multiple errors to the client in one API call.
         */
-       (void) event_kernel_enable_all_syscalls(kchan, kernel_tracer_fd);
+       (void) event_kernel_enable_syscall(kchan, "");
 
 end:
        return tp_ret;
index a82a3bbb8df0150aab4eb1ac9ed7f52bca14a606..501ee02d1eeb7d43a9e71c254a8a6e83f5d80763 100644 (file)
 
 int event_kernel_disable_tracepoint(struct ltt_kernel_channel *kchan,
                char *event_name);
-int event_kernel_disable_all_syscalls(struct ltt_kernel_channel *kchan);
+int event_kernel_disable_syscall(struct ltt_kernel_channel *kchan,
+               char *syscall_name);
 int event_kernel_disable_all_tracepoints(struct ltt_kernel_channel *kchan);
 int event_kernel_disable_all(struct ltt_kernel_channel *kchan);
 
 int event_kernel_enable_tracepoint(struct ltt_kernel_channel *kchan,
                struct lttng_event *event);
+int event_kernel_enable_syscall(struct ltt_kernel_channel *kchan,
+               char *syscall_name);
 int event_kernel_enable_all_tracepoints(struct ltt_kernel_channel *kchan,
                int kernel_tracer_fd);
-int event_kernel_enable_all_syscalls(struct ltt_kernel_channel *kchan,
-               int kernel_tracer_fd);
 int event_kernel_enable_all(struct ltt_kernel_channel *kchan,
                int kernel_tracer_fd);
 
@@ -43,6 +44,7 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
                struct lttng_event_exclusion *exclusion);
 int event_ust_disable_tracepoint(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan, char *event_name);
+
 int event_ust_enable_all_tracepoints(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan,
                char *filter_expression,
index 1fae30f0ad7372bdd2f439d10b1044181048f127..44e9539cb9e1e4dcd8c625fafcda90d024e6c629 100644 (file)
@@ -351,6 +351,18 @@ error:
        return ret;
 }
 
+int kernel_enable_syscall(const char *syscall_name,
+               struct ltt_kernel_channel *channel)
+{
+       return kernctl_enable_syscall(channel->fd, syscall_name);
+}
+
+int kernel_disable_syscall(const char *syscall_name,
+               struct ltt_kernel_channel *channel)
+{
+       return kernctl_disable_syscall(channel->fd, syscall_name);
+}
+
 /*
  * Create kernel metadata, open from the kernel tracer and add it to the
  * kernel session.
index 681301fc2f2c73ed971be54e920dcd8ade5adb32..291a66c783a522fd7b45218de281873c9a4e0928 100644 (file)
@@ -41,6 +41,10 @@ int kernel_disable_channel(struct ltt_kernel_channel *chan);
 int kernel_disable_event(struct ltt_kernel_event *event);
 int kernel_enable_event(struct ltt_kernel_event *event);
 int kernel_enable_channel(struct ltt_kernel_channel *chan);
+int kernel_enable_syscall(const char *syscall_name,
+               struct ltt_kernel_channel *channel);
+int kernel_disable_syscall(const char *syscall_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);
index 2a97c37f6859988360dd283d514429cc8a7f59c8..22dd28e1e9df1538baa242e595284580db67dc60 100644 (file)
@@ -3122,17 +3122,21 @@ skip_domain:
        }
        case LTTNG_DISABLE_EVENT:
        {
+               /* FIXME: passing packed structure to non-packed pointer */
+               /* TODO: handle filter */
                ret = cmd_disable_event(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                cmd_ctx->lsm->u.disable.channel_name,
-                               cmd_ctx->lsm->u.disable.name);
+                               &cmd_ctx->lsm->u.disable.event);
                break;
        }
        case LTTNG_DISABLE_ALL_EVENT:
        {
                DBG("Disabling all events");
 
+               /* FIXME: passing packed structure to non-packed pointer */
                ret = cmd_disable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type,
-                               cmd_ctx->lsm->u.disable.channel_name);
+                               cmd_ctx->lsm->u.disable.channel_name,
+                               &cmd_ctx->lsm->u.disable.event);
                break;
        }
        case LTTNG_ENABLE_CHANNEL:
index 7972d90a0762b1029354cf8ec84fa7add18decc5..1ce687aa422aebc2eb96e76e348b4552d3fdd565 100644 (file)
@@ -37,6 +37,7 @@ static int opt_userspace;
 static int opt_disable_all;
 static int opt_jul;
 static int opt_log4j;
+static int opt_event_type;
 #if 0
 /* Not implemented yet */
 static char *opt_cmd_name;
@@ -46,6 +47,7 @@ static pid_t opt_pid;
 enum {
        OPT_HELP = 1,
        OPT_USERSPACE,
+       OPT_SYSCALL,
        OPT_LIST_OPTIONS,
 };
 
@@ -61,6 +63,7 @@ static struct poptOption long_options[] = {
        {"jul",            'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0},
        {"log4j",          'l', POPT_ARG_VAL, &opt_log4j, 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},
@@ -90,6 +93,9 @@ static void usage(FILE *ofp)
        fprintf(ofp, "  -j, --jul                Apply for Java application using JUL\n");
        fprintf(ofp, "  -l, --log4j              Apply to Java application using LOG4j\n");
        fprintf(ofp, "\n");
+       fprintf(ofp, "Event options:\n");
+       fprintf(ofp, "      --syscall            System call event\n");
+       fprintf(ofp, "\n");
 }
 
 static
@@ -159,6 +165,7 @@ static int disable_events(char *session_name)
        int enabled = 1, success = 1;
        char *event_name, *channel_name = NULL;
        struct lttng_domain dom;
+       struct lttng_event event;
 
        memset(&dom, 0, sizeof(dom));
 
@@ -208,8 +215,18 @@ static int disable_events(char *session_name)
                }
        }
 
+       memset(&event, 0, sizeof(event));
+       switch (opt_event_type) {
+       case LTTNG_EVENT_SYSCALL:
+               event.type = LTTNG_EVENT_SYSCALL;
+               break;
+       default:
+               event.type = LTTNG_EVENT_ALL;
+               break;
+       }
+
        if (opt_disable_all) {
-               command_ret = lttng_disable_event(handle, NULL, channel_name);
+               command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
                if (command_ret < 0) {
                        ERR("%s", lttng_strerror(command_ret));
                        enabled = 1;
@@ -218,8 +235,10 @@ static int disable_events(char *session_name)
                } else {
                        enabled = 0;
                        success = 1;
-                       MSG("All %s events are disabled in channel %s",
-                                       get_domain_str(dom.type), print_channel_name(channel_name));
+                       MSG("All %s %s are disabled in channel %s",
+                                       get_domain_str(dom.type),
+                                       opt_event_type == LTTNG_EVENT_SYSCALL ? "system calls" : "events",
+                                       print_channel_name(channel_name));
                }
 
                if (lttng_opt_mi) {
@@ -235,9 +254,13 @@ static int disable_events(char *session_name)
                while (event_name != NULL) {
                        DBG("Disabling event %s", event_name);
 
-                       command_ret = lttng_disable_event(handle, event_name, channel_name);
+                       strncpy(event.name, event_name, sizeof(event.name));
+                       event.name[sizeof(event.name) - 1] = '\0';
+                       command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
                        if (command_ret < 0) {
-                               ERR("Event %s: %s (channel %s, session %s)", event_name,
+                               ERR("%s %s: %s (channel %s, session %s)",
+                                               opt_event_type == LTTNG_EVENT_SYSCALL ? "System call" : "Event",
+                                               event_name,
                                                lttng_strerror(command_ret),
                                                command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
                                                        ? print_raw_channel_name(channel_name)
@@ -246,13 +269,15 @@ static int disable_events(char *session_name)
                                warn = 1;
                                success = 0;
                                /*
-                                * If an error occurred we assume that
-                                * the event is still enabled.
+                                * If an error occurred we assume that the event is still
+                                * enabled.
                                 */
                                enabled = 1;
                        } else {
-                               MSG("%s event %s disabled in channel %s for session %s",
-                                               get_domain_str(dom.type), event_name,
+                               MSG("%s %s %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_channel_name(channel_name),
                                                session_name);
                                success = 1;
@@ -303,10 +328,14 @@ int cmd_disable_events(int argc, const char **argv)
        int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
        static poptContext pc;
        char *session_name = NULL;
+       int event_type = -1;
 
        pc = poptGetContext(NULL, argc, argv, long_options, 0);
        poptReadDefaultConfig(pc, 0);
 
+       /* Default event type */
+       opt_event_type = LTTNG_EVENT_ALL;
+
        while ((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case OPT_HELP:
@@ -315,6 +344,9 @@ int cmd_disable_events(int argc, const char **argv)
                case OPT_USERSPACE:
                        opt_userspace = 1;
                        break;
+               case OPT_SYSCALL:
+                       opt_event_type = LTTNG_EVENT_SYSCALL;
+                       break;
                case OPT_LIST_OPTIONS:
                        list_cmd_options(stdout, long_options);
                        goto end;
@@ -323,6 +355,17 @@ int cmd_disable_events(int argc, const char **argv)
                        ret = CMD_UNDEFINED;
                        goto end;
                }
+
+               /* Validate event type. Multiple event type are not supported. */
+               if (event_type == -1) {
+                       event_type = opt_event_type;
+               } else {
+                       if (event_type != opt_event_type) {
+                               ERR("Multiple event type not supported.");
+                               ret = CMD_ERROR;
+                               goto end;
+                       }
+               }
        }
 
        opt_event_list = (char*) poptGetArg(pc);
index a06dbb7600b0213fdd708e680bb234e0accc25a4..dc5f51debd8288c8d26b8517d152d156006c574d 100644 (file)
@@ -777,7 +777,8 @@ static int enable_events(char *session_name)
                                break;
                        case LTTNG_EVENT_SYSCALL:
                                if (opt_kernel) {
-                                       MSG("All kernel system calls are enabled in channel %s",
+                                       MSG("All %s system calls are enabled in channel %s",
+                                                       get_domain_str(dom.type),
                                                        print_channel_name(channel_name));
                                }
                                break;
index d153a1cff7dafbbc3460f7aac1baae55042263fd..ce8d8a0eb1f4ec4df60d388589be6ab209673b4f 100644 (file)
@@ -139,6 +139,30 @@ int kernctl_create_channel(int fd, struct lttng_channel_attr *chops)
        return ioctl(fd, LTTNG_KERNEL_CHANNEL, &channel);
 }
 
+int kernctl_enable_syscall(int fd, const char *syscall_name)
+{
+       struct lttng_kernel_event event;
+
+       memset(&event, 0, sizeof(event));
+       strncpy(event.name, syscall_name, sizeof(event.name));
+       event.name[sizeof(event.name) - 1] = '\0';
+       event.instrumentation = LTTNG_KERNEL_SYSCALL;
+       event.u.syscall.disable = 0;
+       return ioctl(fd, LTTNG_KERNEL_EVENT, &event);
+}
+
+int kernctl_disable_syscall(int fd, const char *syscall_name)
+{
+       struct lttng_kernel_event event;
+
+       memset(&event, 0, sizeof(event));
+       strncpy(event.name, syscall_name, sizeof(event.name));
+       event.name[sizeof(event.name) - 1] = '\0';
+       event.instrumentation = LTTNG_KERNEL_SYSCALL;
+       event.u.syscall.disable = 1;
+       return ioctl(fd, LTTNG_KERNEL_EVENT, &event);
+}
+
 int kernctl_create_stream(int fd)
 {
        return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_STREAM,
index 7c5f8bebefb55b2156b7214b9ef59476aef927a6..b67e8e356e44e247f7b19036c4430f71917729b8 100644 (file)
@@ -40,6 +40,8 @@ int kernctl_tracer_version(int fd, struct lttng_kernel_tracer_version *v);
 int kernctl_wait_quiescent(int fd);
 int kernctl_calibrate(int fd, struct lttng_kernel_calibrate *calibrate);
 
+int kernctl_enable_syscall(int fd, const char *syscall_name);
+int kernctl_disable_syscall(int fd, const char *syscall_name);
 
 /* Buffer operations */
 
index b242251907dce7746cc117cb5e4f6c3469499457..a7c9258a73f057c32095d3e6e21849e1d1377f2b 100644 (file)
@@ -97,6 +97,10 @@ struct lttng_kernel_function {
        char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN];
 } LTTNG_PACKED;
 
+struct lttng_kernel_syscall {
+       char disable;
+} __attribute__((packed));
+
 #define LTTNG_KERNEL_EVENT_PADDING1    16
 #define LTTNG_KERNEL_EVENT_PADDING2    LTTNG_KERNEL_SYM_NAME_LEN + 32
 struct lttng_kernel_event {
@@ -109,6 +113,7 @@ struct lttng_kernel_event {
                struct lttng_kernel_kretprobe kretprobe;
                struct lttng_kernel_kprobe kprobe;
                struct lttng_kernel_function ftrace;
+               struct lttng_kernel_syscall syscall;
                char padding[LTTNG_KERNEL_EVENT_PADDING2];
        } u;
 } LTTNG_PACKED;
index bae083dd83018e002afa36e2b648f586fca9bac1..ee3f992537f69a8c1287a3b31f9ce52553a023bc 100644 (file)
@@ -227,10 +227,6 @@ struct lttcomm_session_msg {
        struct lttng_session session;
        struct lttng_domain domain;
        union {
-               struct {
-                       char channel_name[LTTNG_SYMBOL_NAME_LEN];
-                       char name[NAME_MAX];
-               } LTTNG_PACKED disable;
                /* Event data */
                struct {
                        char channel_name[LTTNG_SYMBOL_NAME_LEN];
@@ -249,6 +245,20 @@ struct lttcomm_session_msg {
                         * - unsigned char filter_bytecode[bytecode_len]
                         */
                } LTTNG_PACKED enable;
+               struct {
+                       char channel_name[LTTNG_SYMBOL_NAME_LEN];
+                       struct lttng_event event LTTNG_PACKED;
+                       /* Length of following filter expression. */
+                       uint32_t expression_len;
+                       /* Length of following bytecode for filter. */
+                       uint32_t bytecode_len;
+                       /*
+                        * After this structure, the following variable-length
+                        * items are transmitted:
+                        * - unsigned char filter_expression[expression_len]
+                        * - unsigned char filter_bytecode[bytecode_len]
+                        */
+               } LTTNG_PACKED disable;
                /* Create channel */
                struct {
                        struct lttng_channel chan LTTNG_PACKED;
index cacae13bb84da3e4033a016c244cbfa970d7172c..c5aada5bec9b46af9e26ce74c606f1a74553a2bf 100644 (file)
@@ -926,6 +926,7 @@ int lttng_enable_event_with_exclusions(struct lttng_handle *handle,
        }
 
        lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+       /* FIXME: copying non-packed struct to packed struct. */
        memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
 
        lttng_ctl_copy_string(lsm.session.name, handle->session_name,
@@ -1039,19 +1040,34 @@ ask_sessiond:
        return ret;
 }
 
-/*
- *  Disable event(s) of a channel and domain.
- *  If no event name is specified, all events are disabled.
- *  If no channel name is specified, the default 'channel0' is used.
- *  Returns size of returned session payload data or a negative error code.
- */
-int lttng_disable_event(struct lttng_handle *handle, const char *name,
-               const char *channel_name)
+int lttng_disable_event_ext(struct lttng_handle *handle,
+               struct lttng_event *ev, const char *channel_name,
+               const char *original_filter_expression)
 {
        struct lttcomm_session_msg lsm;
+       char *varlen_data;
+       int ret = 0;
+       unsigned int free_filter_expression = 0;
+       struct filter_parser_ctx *ctx = NULL;
+       /*
+        * Cast as non-const since we may replace the filter expression
+        * by a dynamically allocated string. Otherwise, the original
+        * string is not modified.
+        */
+       char *filter_expression = (char *) original_filter_expression;
 
-       if (handle == NULL) {
-               return -LTTNG_ERR_INVALID;
+       if (handle == NULL || ev == NULL) {
+               ret = -LTTNG_ERR_INVALID;
+               goto error;
+       }
+
+       /* Empty filter string will always be rejected by the parser
+        * anyway, so treat this corner-case early to eliminate
+        * lttng_fmemopen error for 0-byte allocation.
+        */
+       if (filter_expression && filter_expression[0] == '\0') {
+               ret = -LTTNG_ERR_INVALID;
+               goto error;
        }
 
        memset(&lsm, 0, sizeof(lsm));
@@ -1065,20 +1081,132 @@ int lttng_disable_event(struct lttng_handle *handle, const char *name,
                                sizeof(lsm.u.disable.channel_name));
        }
 
-       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
-
-       if (name != NULL && *name != '*') {
-               lttng_ctl_copy_string(lsm.u.disable.name, name,
-                               sizeof(lsm.u.disable.name));
+       if (ev->name[0] != '\0') {
                lsm.cmd_type = LTTNG_DISABLE_EVENT;
        } else {
                lsm.cmd_type = LTTNG_DISABLE_ALL_EVENT;
        }
 
+       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+       /* FIXME: copying non-packed struct to packed struct. */
+       memcpy(&lsm.u.disable.event, ev, sizeof(lsm.u.disable.event));
+
        lttng_ctl_copy_string(lsm.session.name, handle->session_name,
                        sizeof(lsm.session.name));
+       lsm.u.disable.bytecode_len = 0;
 
-       return lttng_ctl_ask_sessiond(&lsm, NULL);
+       /*
+        * For the JUL domain, a filter is enforced except for the
+        * disable all event. This is done to avoid having the event in
+        * all sessions thus filtering by logger name.
+        */
+       if (filter_expression == NULL &&
+                       (handle->domain.type != LTTNG_DOMAIN_JUL &&
+                               handle->domain.type != LTTNG_DOMAIN_LOG4J)) {
+               goto ask_sessiond;
+       }
+
+       /*
+        * We have a filter, so we need to set up a variable-length
+        * memory block from where to send the data.
+        */
+
+       /* Parse filter expression */
+       if (filter_expression != NULL || handle->domain.type == LTTNG_DOMAIN_JUL
+                       || handle->domain.type == LTTNG_DOMAIN_LOG4J) {
+               if (handle->domain.type == LTTNG_DOMAIN_JUL ||
+                               handle->domain.type == LTTNG_DOMAIN_LOG4J) {
+                       char *jul_filter;
+
+                       /* Setup JUL filter if needed. */
+                       jul_filter = set_jul_filter(filter_expression, ev);
+                       if (!jul_filter) {
+                               if (!filter_expression) {
+                                       /* No JUL and no filter, just skip everything below. */
+                                       goto ask_sessiond;
+                               }
+                       } else {
+                               /*
+                                * With a JUL filter, the original filter has been added to it
+                                * thus replace the filter expression.
+                                */
+                               filter_expression = jul_filter;
+                               free_filter_expression = 1;
+                       }
+               }
+
+               ret = generate_filter(filter_expression, &lsm, &ctx);
+               if (ret) {
+                       goto filter_error;
+               }
+       }
+
+       varlen_data = zmalloc(lsm.u.disable.bytecode_len
+                       + lsm.u.disable.expression_len);
+       if (!varlen_data) {
+               ret = -LTTNG_ERR_EXCLUSION_NOMEM;
+               goto mem_error;
+       }
+
+       /* Add filter expression */
+       if (lsm.u.disable.expression_len != 0) {
+               memcpy(varlen_data,
+                       filter_expression,
+                       lsm.u.disable.expression_len);
+       }
+       /* Add filter bytecode next */
+       if (ctx && lsm.u.disable.bytecode_len != 0) {
+               memcpy(varlen_data
+                       + lsm.u.disable.expression_len,
+                       &ctx->bytecode->b,
+                       lsm.u.disable.bytecode_len);
+       }
+
+       ret = lttng_ctl_ask_sessiond_varlen(&lsm, varlen_data,
+                       lsm.u.disable.bytecode_len + lsm.u.disable.expression_len, NULL);
+       free(varlen_data);
+
+mem_error:
+       if (filter_expression && ctx) {
+               filter_bytecode_free(ctx);
+               filter_ir_free(ctx);
+               filter_parser_ctx_free(ctx);
+       }
+filter_error:
+       if (free_filter_expression) {
+               /*
+                * The filter expression has been replaced and must be freed as it is
+                * not the original filter expression received as a parameter.
+                */
+               free(filter_expression);
+       }
+error:
+       /*
+        * Return directly to the caller and don't ask the sessiond since something
+        * went wrong in the parsing of data above.
+        */
+       return ret;
+
+ask_sessiond:
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+       return ret;
+}
+
+/*
+ *  Disable event(s) of a channel and domain.
+ *  If no event name is specified, all events are disabled.
+ *  If no channel name is specified, the default 'channel0' is used.
+ *  Returns size of returned session payload data or a negative error code.
+ */
+int lttng_disable_event(struct lttng_handle *handle, const char *name,
+               const char *channel_name)
+{
+       struct lttng_event ev;
+
+       memset(&ev, 0, sizeof(ev));
+       ev.type = LTTNG_EVENT_ALL;
+       lttng_ctl_copy_string(ev.name, name, sizeof(ev.name));
+       return lttng_disable_event_ext(handle, &ev, channel_name, NULL);
 }
 
 /*
This page took 0.062843 seconds and 5 git commands to generate.