Implement syscall wildcard support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 5 Nov 2014 00:12:04 +0000 (19:12 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 10 Apr 2015 20:41:20 +0000 (16:41 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lttng-abi.c
lttng-abi.h
lttng-events.c
lttng-events.h
lttng-probes.c
lttng-syscalls.c

index eaa2f63f5af57991e2f5ab67460d93e2e60b7dc4..ede2ae79bd7b15c45ec4ef3864a048cc85f2e006 100644 (file)
@@ -929,74 +929,51 @@ int lttng_abi_create_event(struct file *channel_file,
        default:
                break;
        }
-       switch (event_param->instrumentation) {
-       default:
-               event_fd = lttng_get_unused_fd();
-               if (event_fd < 0) {
-                       ret = event_fd;
-                       goto fd_error;
-               }
-               event_file = anon_inode_getfile("[lttng_event]",
-                                               &lttng_event_fops,
-                                               NULL, O_RDWR);
-               if (IS_ERR(event_file)) {
-                       ret = PTR_ERR(event_file);
-                       goto file_error;
-               }
-               if (event_param->instrumentation == LTTNG_KERNEL_TRACEPOINT) {
-                       struct lttng_enabler *enabler;
-
-                       if (event_param->name[strlen(event_param->name) - 1] == '*') {
-                               enabler = lttng_enabler_create(LTTNG_ENABLER_WILDCARD,
-                                       event_param, channel);
-                       } else {
-                               enabler = lttng_enabler_create(LTTNG_ENABLER_NAME,
-                                       event_param, channel);
-                       }
-                       priv = enabler;
+       event_fd = lttng_get_unused_fd();
+       if (event_fd < 0) {
+               ret = event_fd;
+               goto fd_error;
+       }
+       event_file = anon_inode_getfile("[lttng_event]",
+                                       &lttng_event_fops,
+                                       NULL, O_RDWR);
+       if (IS_ERR(event_file)) {
+               ret = PTR_ERR(event_file);
+               goto file_error;
+       }
+       if (event_param->instrumentation == LTTNG_KERNEL_TRACEPOINT
+                       || event_param->instrumentation == LTTNG_KERNEL_SYSCALL) {
+               struct lttng_enabler *enabler;
+
+               if (event_param->name[strlen(event_param->name) - 1] == '*') {
+                       enabler = lttng_enabler_create(LTTNG_ENABLER_WILDCARD,
+                               event_param, channel);
                } else {
-                       struct lttng_event *event;
-
-                       /*
-                        * We tolerate no failure path after event creation. It
-                        * will stay invariant for the rest of the session.
-                        */
-                       event = lttng_event_create(channel, event_param,
-                                       NULL, NULL,
-                                       event_param->instrumentation);
-                       WARN_ON_ONCE(!event);
-                       if (IS_ERR(event)) {
-                               ret = PTR_ERR(event);
-                               goto event_error;
-                       }
-                       priv = event;
+                       enabler = lttng_enabler_create(LTTNG_ENABLER_NAME,
+                               event_param, channel);
                }
-               event_file->private_data = priv;
-               fd_install(event_fd, event_file);
-               /* The event holds a reference on the channel */
-               atomic_long_inc(&channel_file->f_count);
-               break;
-       case LTTNG_KERNEL_SYSCALL:
-               ret = lttng_syscalls_register(channel, NULL);
-               if (ret)
-                       goto fd_error;
-               event_fd = 0;
-               if (event_param->u.syscall.enable) {
-                       ret = lttng_syscall_filter_enable(channel,
-                               !strcmp(event_param->name, "*") ?
-                                       NULL : event_param->name);
-                       if (ret)
-                               goto fd_error;
+               priv = enabler;
+       } else {
+               struct lttng_event *event;
 
-               } else {
-                       ret = lttng_syscall_filter_disable(channel,
-                               !strcmp(event_param->name, "*") ?
-                                       NULL : event_param->name);
-                       if (ret)
-                               goto fd_error;
+               /*
+                * We tolerate no failure path after event creation. It
+                * will stay invariant for the rest of the session.
+                */
+               event = lttng_event_create(channel, event_param,
+                               NULL, NULL,
+                               event_param->instrumentation);
+               WARN_ON_ONCE(!event);
+               if (IS_ERR(event)) {
+                       ret = PTR_ERR(event);
+                       goto event_error;
                }
-               break;
+               priv = event;
        }
+       event_file->private_data = priv;
+       fd_install(event_fd, event_file);
+       /* The event holds a reference on the channel */
+       atomic_long_inc(&channel_file->f_count);
        return event_fd;
 
 event_error:
index a2e34ff7f87a594d969746477f4d20d8551cb41d..7239f76f5f41f5eb63cce30f808a5d1339d3228c 100644 (file)
@@ -86,10 +86,6 @@ struct lttng_kernel_function_tracer {
        char symbol_name[LTTNG_KERNEL_SYM_NAME_LEN];
 } __attribute__((packed));
 
-struct lttng_kernel_syscall {
-       char enable;
-} __attribute__((packed));
-
 /*
  * For syscall tracing, name = "*" means "enable all".
  */
@@ -105,7 +101,6 @@ struct lttng_kernel_event {
                struct lttng_kernel_kretprobe kretprobe;
                struct lttng_kernel_kprobe kprobe;
                struct lttng_kernel_function_tracer ftrace;
-               struct lttng_kernel_syscall syscall;
                char padding[LTTNG_KERNEL_EVENT_PADDING2];
        } u;
 } __attribute__((packed));
index 3616e010410134ee3021260cbf3d7de1bb018610..d09d4c2e81fa9560da8767863f31f0aca19358aa 100644 (file)
@@ -481,6 +481,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
        case LTTNG_KERNEL_KRETPROBE:
        case LTTNG_KERNEL_FUNCTION:
        case LTTNG_KERNEL_NOOP:
+       case LTTNG_KERNEL_SYSCALL:
                event_name = event_param->name;
                break;
        default:
@@ -614,6 +615,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
                WARN_ON_ONCE(!ret);
                break;
        case LTTNG_KERNEL_NOOP:
+       case LTTNG_KERNEL_SYSCALL:
                event->enabled = 1;
                event->registered = 0;
                event->desc = event_desc;
@@ -711,6 +713,7 @@ int _lttng_event_unregister(struct lttng_event *event)
                ret = 0;
                break;
        case LTTNG_KERNEL_NOOP:
+       case LTTNG_KERNEL_SYSCALL:
                ret = 0;
                break;
        default:
@@ -744,6 +747,7 @@ void _lttng_event_destroy(struct lttng_event *event)
                lttng_ftrace_destroy_private(event);
                break;
        case LTTNG_KERNEL_NOOP:
+       case LTTNG_KERNEL_SYSCALL:
                break;
        default:
                WARN_ON_ONCE(1);
@@ -1025,6 +1029,8 @@ static
 int lttng_event_match_enabler(struct lttng_event *event,
                struct lttng_enabler *enabler)
 {
+       if (enabler->event_param.instrumentation != event->instrumentation)
+               return 0;
        if (lttng_desc_match_enabler(event->desc, enabler)
                        && event->chan == enabler->chan)
                return 1;
@@ -1046,13 +1052,8 @@ struct lttng_enabler_ref *lttng_event_enabler_ref(struct lttng_event *event,
        return NULL;
 }
 
-/*
- * Create struct lttng_event if it is missing and present in the list of
- * tracepoint probes.
- * Should be called with sessions mutex held.
- */
 static
-void lttng_create_event_if_missing(struct lttng_enabler *enabler)
+void lttng_create_tracepoint_if_missing(struct lttng_enabler *enabler)
 {
        struct lttng_session *session = enabler->chan->session;
        struct lttng_probe_desc *probe_desc;
@@ -1109,6 +1110,36 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler)
        }
 }
 
+static
+void lttng_create_syscall_if_missing(struct lttng_enabler *enabler)
+{
+       int ret;
+
+       ret = lttng_syscalls_register(enabler->chan, NULL);
+       WARN_ON_ONCE(ret);
+}
+
+/*
+ * Create struct lttng_event if it is missing and present in the list of
+ * tracepoint probes.
+ * Should be called with sessions mutex held.
+ */
+static
+void lttng_create_event_if_missing(struct lttng_enabler *enabler)
+{
+       switch (enabler->event_param.instrumentation) {
+       case LTTNG_KERNEL_TRACEPOINT:
+               lttng_create_tracepoint_if_missing(enabler);
+               break;
+       case LTTNG_KERNEL_SYSCALL:
+               lttng_create_syscall_if_missing(enabler);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+}
+
 /*
  * Create events associated with an enabler (if not already present),
  * and add backward reference from the event to the enabler.
index 567449615cce756284795659679da2ca6f5b2af7..c360af0b0ebb7c7a659900fb18be0fea969f6ce3 100644 (file)
@@ -460,6 +460,11 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan,
                                void *filter,
                                const struct lttng_event_desc *event_desc,
                                enum lttng_kernel_instrumentation itype);
+struct lttng_event *_lttng_event_create(struct lttng_channel *chan,
+                               struct lttng_kernel_event *event_param,
+                               void *filter,
+                               const struct lttng_event_desc *event_desc,
+                               enum lttng_kernel_instrumentation itype);
 struct lttng_event *lttng_event_compat_old_create(struct lttng_channel *chan,
                struct lttng_kernel_old_event *old_event_param,
                void *filter,
index d2723969ef7d887d818ce670a2ad8218aba46a45..b5a7fc8024401da8d19d0f132a122bd63c1c64c9 100644 (file)
@@ -103,7 +103,7 @@ void lttng_lazy_probe_register(struct lttng_probe_desc *desc)
        /* We should be added at the head of the list */
        list_add(&desc->head, probe_list);
 desc_added:
-       printk(KERN_DEBUG "just registered probe %s containing %u events\n",
+       pr_debug("LTTng: just registered probe %s containing %u events\n",
                desc->provider, desc->nr_events);
 }
 
@@ -167,7 +167,7 @@ int lttng_probe_register(struct lttng_probe_desc *desc)
        }
        list_add(&desc->lazy_init_head, &lazy_probe_init);
        desc->lazy = 1;
-       printk(KERN_DEBUG "adding probe %s containing %u events to lazy registration list\n",
+       pr_debug("LTTng: adding probe %s containing %u events to lazy registration list\n",
                desc->provider, desc->nr_events);
        /*
         * If there is at least one active session, we need to register
@@ -189,7 +189,7 @@ void lttng_probe_unregister(struct lttng_probe_desc *desc)
                list_del(&desc->head);
        else
                list_del(&desc->lazy_init_head);
-       printk(KERN_DEBUG "just unregistered probe %s\n", desc->provider);
+       pr_debug("LTTng: just unregistered probe %s\n", desc->provider);
        lttng_unlock_sessions();
 }
 EXPORT_SYMBOL_GPL(lttng_probe_unregister);
index ee09a0419498a07f0dc06a0bb0f56afcc8a3771a..2ddc9d1227c862305036344a607946aabdbc2de4 100644 (file)
@@ -666,7 +666,10 @@ void syscall_exit_probe(void *__data, struct pt_regs *regs, long ret)
        }
 }
 
-/* noinline to diminish caller stack size */
+/*
+ * noinline to diminish caller stack size.
+ * Should be called with sessions lock held.
+ */
 static
 int fill_table(const struct trace_syscall_entry *table, size_t table_len,
        struct lttng_event **chan_table, struct lttng_channel *chan,
@@ -715,8 +718,8 @@ int fill_table(const struct trace_syscall_entry *table, size_t table_len,
                strncat(ev.name, desc->name,
                        LTTNG_KERNEL_SYM_NAME_LEN - strlen(ev.name) - 1);
                ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
-               ev.instrumentation = LTTNG_KERNEL_NOOP;
-               chan_table[i] = lttng_event_create(chan, &ev, filter,
+               ev.instrumentation = LTTNG_KERNEL_SYSCALL;
+               chan_table[i] = _lttng_event_create(chan, &ev, filter,
                                                desc, ev.instrumentation);
                WARN_ON_ONCE(!chan_table[i]);
                if (IS_ERR(chan_table[i])) {
@@ -732,6 +735,9 @@ int fill_table(const struct trace_syscall_entry *table, size_t table_len,
        return 0;
 }
 
+/*
+ * Should be called with sessions lock held.
+ */
 int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
 {
        struct lttng_kernel_event ev;
@@ -779,8 +785,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
                memset(&ev, 0, sizeof(ev));
                strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
                ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
-               ev.instrumentation = LTTNG_KERNEL_NOOP;
-               chan->sc_unknown = lttng_event_create(chan, &ev, filter,
+               ev.instrumentation = LTTNG_KERNEL_SYSCALL;
+               chan->sc_unknown = _lttng_event_create(chan, &ev, filter,
                                                desc,
                                                ev.instrumentation);
                WARN_ON_ONCE(!chan->sc_unknown);
@@ -796,8 +802,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
                memset(&ev, 0, sizeof(ev));
                strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
                ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
-               ev.instrumentation = LTTNG_KERNEL_NOOP;
-               chan->sc_compat_unknown = lttng_event_create(chan, &ev, filter,
+               ev.instrumentation = LTTNG_KERNEL_SYSCALL;
+               chan->sc_compat_unknown = _lttng_event_create(chan, &ev, filter,
                                                desc,
                                                ev.instrumentation);
                WARN_ON_ONCE(!chan->sc_unknown);
@@ -813,8 +819,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
                memset(&ev, 0, sizeof(ev));
                strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
                ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
-               ev.instrumentation = LTTNG_KERNEL_NOOP;
-               chan->compat_sc_exit_unknown = lttng_event_create(chan, &ev,
+               ev.instrumentation = LTTNG_KERNEL_SYSCALL;
+               chan->compat_sc_exit_unknown = _lttng_event_create(chan, &ev,
                                                filter, desc,
                                                ev.instrumentation);
                WARN_ON_ONCE(!chan->compat_sc_exit_unknown);
@@ -830,8 +836,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
                memset(&ev, 0, sizeof(ev));
                strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN);
                ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
-               ev.instrumentation = LTTNG_KERNEL_NOOP;
-               chan->sc_exit_unknown = lttng_event_create(chan, &ev, filter,
+               ev.instrumentation = LTTNG_KERNEL_SYSCALL;
+               chan->sc_exit_unknown = _lttng_event_create(chan, &ev, filter,
                                                desc, ev.instrumentation);
                WARN_ON_ONCE(!chan->sc_exit_unknown);
                if (IS_ERR(chan->sc_exit_unknown)) {
This page took 0.033492 seconds and 4 git commands to generate.