syscall wildcards: apply syscall filtering
[lttng-modules.git] / lttng-events.c
index 3616e010410134ee3021260cbf3d7de1bb018610..430307686b10a3a2f4c2ae3403fc349db51e2592 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;
@@ -670,12 +672,29 @@ void register_event(struct lttng_event *event)
        const struct lttng_event_desc *desc;
        int ret;
 
-       WARN_ON_ONCE(event->instrumentation != LTTNG_KERNEL_TRACEPOINT);
        if (event->registered)
                return;
+
        desc = event->desc;
-       ret = lttng_wrapper_tracepoint_probe_register(desc->kname,
-               desc->probe_callback, event);
+       switch (event->instrumentation) {
+       case LTTNG_KERNEL_TRACEPOINT:
+               ret = lttng_wrapper_tracepoint_probe_register(desc->kname,
+                                                 desc->probe_callback,
+                                                 event);
+               break;
+       case LTTNG_KERNEL_SYSCALL:
+               ret = lttng_syscall_filter_enable(event->chan,
+                       desc->name);
+               break;
+       case LTTNG_KERNEL_KPROBE:
+       case LTTNG_KERNEL_KRETPROBE:
+       case LTTNG_KERNEL_FUNCTION:
+       case LTTNG_KERNEL_NOOP:
+               ret = 0;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+       }
        if (!ret)
                event->registered = 1;
 }
@@ -685,18 +704,18 @@ void register_event(struct lttng_event *event)
  */
 int _lttng_event_unregister(struct lttng_event *event)
 {
+       const struct lttng_event_desc *desc;
        int ret = -EINVAL;
 
        if (!event->registered)
                return 0;
 
+       desc = event->desc;
        switch (event->instrumentation) {
        case LTTNG_KERNEL_TRACEPOINT:
                ret = lttng_wrapper_tracepoint_probe_unregister(event->desc->kname,
                                                  event->desc->probe_callback,
                                                  event);
-               if (ret)
-                       return ret;
                break;
        case LTTNG_KERNEL_KPROBE:
                lttng_kprobes_unregister(event);
@@ -710,6 +729,10 @@ int _lttng_event_unregister(struct lttng_event *event)
                lttng_ftrace_unregister(event);
                ret = 0;
                break;
+       case LTTNG_KERNEL_SYSCALL:
+               ret = lttng_syscall_filter_disable(event->chan,
+                       desc->name);
+               break;
        case LTTNG_KERNEL_NOOP:
                ret = 0;
                break;
@@ -744,6 +767,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);
@@ -986,23 +1010,20 @@ fd_error:
  * Enabler management.
  */
 static
-int lttng_desc_match_wildcard_enabler(const struct lttng_event_desc *desc,
-               struct lttng_enabler *enabler)
+int lttng_match_enabler_wildcard(const char *desc_name,
+               const char *name)
 {
-       WARN_ON_ONCE(enabler->type != LTTNG_ENABLER_WILDCARD);
        /* Compare excluding final '*' */
-       if (strncmp(desc->name, enabler->event_param.name,
-                       strlen(enabler->event_param.name) - 1))
+       if (strncmp(desc_name, name, strlen(name) - 1))
                return 0;
        return 1;
 }
 
 static
-int lttng_desc_match_name_enabler(const struct lttng_event_desc *desc,
-               struct lttng_enabler *enabler)
+int lttng_match_enabler_name(const char *desc_name,
+               const char *name)
 {
-       WARN_ON_ONCE(enabler->type != LTTNG_ENABLER_NAME);
-       if (strcmp(desc->name, enabler->event_param.name))
+       if (strcmp(desc_name, name))
                return 0;
        return 1;
 }
@@ -1011,11 +1032,37 @@ static
 int lttng_desc_match_enabler(const struct lttng_event_desc *desc,
                struct lttng_enabler *enabler)
 {
+       const char *desc_name, *enabler_name;
+
+       enabler_name = enabler->event_param.name;
+       switch (enabler->event_param.instrumentation) {
+       case LTTNG_KERNEL_TRACEPOINT:
+               desc_name = desc->name;
+               break;
+       case LTTNG_KERNEL_SYSCALL:
+               desc_name = desc->name;
+               if (!strncmp(desc_name, "compat_", strlen("compat_")))
+                       desc_name += strlen("compat_");
+               if (!strncmp(desc_name, "syscall_exit_",
+                               strlen("syscall_exit_"))) {
+                       desc_name += strlen("syscall_exit_");
+               } else if (!strncmp(desc_name, "syscall_entry_",
+                               strlen("syscall_entry_"))) {
+                       desc_name += strlen("syscall_entry_");
+               } else {
+                       WARN_ON_ONCE(1);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -EINVAL;
+       }
        switch (enabler->type) {
        case LTTNG_ENABLER_WILDCARD:
-               return lttng_desc_match_wildcard_enabler(desc, enabler);
+               return lttng_match_enabler_wildcard(desc_name, enabler_name);
        case LTTNG_ENABLER_NAME:
-               return lttng_desc_match_name_enabler(desc, enabler);
+               return lttng_match_enabler_name(desc_name, enabler_name);
        default:
                return -EINVAL;
        }
@@ -1025,6 +1072,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 +1095,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 +1153,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.
@@ -1241,7 +1315,9 @@ void lttng_session_sync_enablers(struct lttng_session *session)
                struct lttng_enabler_ref *enabler_ref;
                int enabled = 0;
 
-               if (event->instrumentation == LTTNG_KERNEL_TRACEPOINT) {
+               switch (event->instrumentation) {
+               case LTTNG_KERNEL_TRACEPOINT:
+               case LTTNG_KERNEL_SYSCALL:
                        /* Enable events */
                        list_for_each_entry(enabler_ref,
                                        &event->enablers_ref_head, node) {
@@ -1250,7 +1326,8 @@ void lttng_session_sync_enablers(struct lttng_session *session)
                                        break;
                                }
                        }
-               } else {
+                       break;
+               default:
                        /* Not handled with lazy sync. */
                        continue;
                }
This page took 0.02599 seconds and 4 git commands to generate.