From: Jonathan Rajotte Date: Tue, 18 May 2021 16:08:15 +0000 (-0400) Subject: Rename lttng_event_rule_syscall to lttng_event_rule_kernel_syscall X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=4f7da553ae57a6c947da2b9668c06418b2d50e99 Rename lttng_event_rule_syscall to lttng_event_rule_kernel_syscall Allow the usage of "kernel:syscall*" as the `--type` argument for add trigger. A later patch remove the notion of domain. Signed-off-by: Jonathan Rajotte Signed-off-by: Jérémie Galarneau Change-Id: Ib5c87ec937bb0acf9c5133532961dcc31e533884 --- diff --git a/include/Makefile.am b/include/Makefile.am index 53e519067..2f403fe0a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -153,7 +153,7 @@ lttngtriggerinclude_HEADERS= \ lttngeventruleinclude_HEADERS= \ lttng/event-rule/event-rule.h \ lttng/event-rule/kernel-probe.h \ - lttng/event-rule/syscall.h \ + lttng/event-rule/kernel-syscall.h \ lttng/event-rule/userspace-probe.h \ lttng/event-rule/tracepoint.h @@ -182,7 +182,7 @@ noinst_HEADERS = \ lttng/event-internal.h \ lttng/event-rule/event-rule-internal.h \ lttng/event-rule/kernel-probe-internal.h \ - lttng/event-rule/syscall-internal.h \ + lttng/event-rule/kernel-syscall-internal.h \ lttng/event-rule/tracepoint-internal.h \ lttng/event-rule/userspace-probe-internal.h \ lttng/health-internal.h \ diff --git a/include/lttng/event-rule/event-rule.h b/include/lttng/event-rule/event-rule.h index eec673e00..aac9f5913 100644 --- a/include/lttng/event-rule/event-rule.h +++ b/include/lttng/event-rule/event-rule.h @@ -17,7 +17,7 @@ struct lttng_event_rule; enum lttng_event_rule_type { LTTNG_EVENT_RULE_TYPE_UNKNOWN = -1, LTTNG_EVENT_RULE_TYPE_TRACEPOINT = 0, - LTTNG_EVENT_RULE_TYPE_SYSCALL = 1, + LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL = 1, LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE = 2, LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION = 3, LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE = 4, diff --git a/include/lttng/event-rule/kernel-syscall-internal.h b/include/lttng/event-rule/kernel-syscall-internal.h new file mode 100644 index 000000000..a5b62743c --- /dev/null +++ b/include/lttng/event-rule/kernel-syscall-internal.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 Jonathan Rajotte + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_EVENT_RULE_KERNEL_SYSCALL_INTERNAL_H +#define LTTNG_EVENT_RULE_KERNEL_SYSCALL_INTERNAL_H + +#include +#include +#include +#include + +struct lttng_event_rule_kernel_syscall { + struct lttng_event_rule parent; + enum lttng_event_rule_kernel_syscall_emission_site emission_site; + char *pattern; + char *filter_expression; + + /* Internal use only. */ + struct { + char *filter; + struct lttng_bytecode *bytecode; + } internal_filter; +}; + +struct lttng_event_rule_kernel_syscall_comm { + uint32_t emission_site; + /* Includes terminator `\0`. */ + uint32_t pattern_len; + /* Includes terminator `\0`. */ + uint32_t filter_expression_len; + /* + * Payload is composed of, in that order: + * - Pattern (null terminated), + * - Filter expression (null terminated). + */ + char payload[]; +} LTTNG_PACKED; + +LTTNG_HIDDEN +ssize_t lttng_event_rule_kernel_syscall_create_from_payload( + struct lttng_payload_view *view, + struct lttng_event_rule **rule); + +LTTNG_HIDDEN +const char *lttng_event_rule_kernel_syscall_emission_site_str( + enum lttng_event_rule_kernel_syscall_emission_site emission_site); +#endif /* LTTNG_EVENT_RULE_KERNEL_SYSCALL_INTERNAL_H */ diff --git a/include/lttng/event-rule/kernel-syscall.h b/include/lttng/event-rule/kernel-syscall.h new file mode 100644 index 000000000..1db691587 --- /dev/null +++ b/include/lttng/event-rule/kernel-syscall.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 Jonathan Rajotte + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_EVENT_RULE_KERNEL_SYSCALL_H +#define LTTNG_EVENT_RULE_KERNEL_SYSCALL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum lttng_event_rule_kernel_syscall_emission_site { + LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT = 0, + LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY = 1, + LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_EXIT = 2, + LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_UNKNOWN = -1, +}; + +/* + * Create a newly allocated kernel syscall event rule. + * + * The default pattern is '*'. + * The default emission site is LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT. + * + * Returns a new event rule on success, NULL on failure. This event rule must be + * destroyed using lttng_event_rule_destroy(). + */ +extern struct lttng_event_rule *lttng_event_rule_kernel_syscall_create(enum + lttng_event_rule_kernel_syscall_emission_site emission_site); + +/* + * Set the name pattern of a kernel syscall event rule. + * + * Pattern can contain wildcard '*'. See man lttng-enable-event. + * + * The pattern is copied internally. + * + * Returns LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID + * if invalid parameters are passed. + */ +extern enum lttng_event_rule_status lttng_event_rule_kernel_syscall_set_name_pattern( + struct lttng_event_rule *rule, const char *pattern); + +/* + * Get the name pattern of a kernel syscall event rule. + * + * The caller does not assume the ownership of the returned pattern. The + * pattern shall only only be used for the duration of the event rule's + * lifetime, or before a different pattern is set. + * + * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's pattern + * on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid + * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a pattern + * was not set prior to this call. + */ +extern enum lttng_event_rule_status lttng_event_rule_kernel_syscall_get_name_pattern( + const struct lttng_event_rule *rule, const char **pattern); + +/* + * Set the filter expression of a kernel syscall event rule. + * + * The expression is copied internally. + * + * Returns LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID + * if invalid parameters are passed. + */ +extern enum lttng_event_rule_status lttng_event_rule_kernel_syscall_set_filter( + struct lttng_event_rule *rule, const char *expression); + +/* + * Get the filter expression of a kernel syscall event rule. + * + * The caller does not assume the ownership of the returned filter expression. + * The filter expression shall only only be used for the duration of the event + * rule's lifetime, or before a different filter expression is set. + * + * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's filter + * expression on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid + * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a filter expression + * was not set prior to this call. + */ +extern enum lttng_event_rule_status lttng_event_rule_kernel_syscall_get_filter( + const struct lttng_event_rule *rule, const char **expression); + +/* + * Get the emission site of a kernel syscall event rule. + * + * Returns a enum lttng_event_rule_kernel_syscall_emission_site. + */ +extern enum lttng_event_rule_kernel_syscall_emission_site +lttng_event_rule_kernel_syscall_get_emission_site( + const struct lttng_event_rule *rule); + +#ifdef __cplusplus +} +#endif + +#endif /* LTTNG_EVENT_RULE_KERNEL_SYSCALL_H */ diff --git a/include/lttng/event-rule/syscall-internal.h b/include/lttng/event-rule/syscall-internal.h deleted file mode 100644 index 29f9e3316..000000000 --- a/include/lttng/event-rule/syscall-internal.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2019 Jonathan Rajotte - * - * SPDX-License-Identifier: LGPL-2.1-only - * - */ - -#ifndef LTTNG_EVENT_RULE_SYSCALL_INTERNAL_H -#define LTTNG_EVENT_RULE_SYSCALL_INTERNAL_H - -#include -#include -#include -#include - -struct lttng_event_rule_syscall { - struct lttng_event_rule parent; - enum lttng_event_rule_syscall_emission_site emission_site; - char *pattern; - char *filter_expression; - - /* Internal use only. */ - struct { - char *filter; - struct lttng_bytecode *bytecode; - } internal_filter; -}; - -struct lttng_event_rule_syscall_comm { - uint32_t emission_site; - /* Includes terminator `\0`. */ - uint32_t pattern_len; - /* Includes terminator `\0`. */ - uint32_t filter_expression_len; - /* - * Payload is composed of, in that order: - * - Pattern (null terminated), - * - Filter expression (null terminated). - */ - char payload[]; -} LTTNG_PACKED; - -LTTNG_HIDDEN -ssize_t lttng_event_rule_syscall_create_from_payload( - struct lttng_payload_view *view, - struct lttng_event_rule **rule); - -LTTNG_HIDDEN -const char *lttng_event_rule_syscall_emission_site_str( - enum lttng_event_rule_syscall_emission_site emission_site); -#endif /* LTTNG_EVENT_RULE_SYSCALL_INTERNAL_H */ diff --git a/include/lttng/event-rule/syscall.h b/include/lttng/event-rule/syscall.h deleted file mode 100644 index f9fd2aba3..000000000 --- a/include/lttng/event-rule/syscall.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2019 Jonathan Rajotte - * - * SPDX-License-Identifier: LGPL-2.1-only - * - */ - -#ifndef LTTNG_EVENT_RULE_SYSCALL_H -#define LTTNG_EVENT_RULE_SYSCALL_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum lttng_event_rule_syscall_emission_site { - LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT = 0, - LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY = 1, - LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT = 2, - LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN = -1, -}; - -/* - * Create a newly allocated syscall event rule. - * - * The default pattern is '*'. - * The default emission site is LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT. - * - * Returns a new event rule on success, NULL on failure. This event rule must be - * destroyed using lttng_event_rule_destroy(). - */ -extern struct lttng_event_rule *lttng_event_rule_syscall_create(enum - lttng_event_rule_syscall_emission_site emission_site); - -/* - * Set the name pattern of a syscall event rule. - * - * Pattern can contain wildcard '*'. See man lttng-enable-event. - * - * The pattern is copied internally. - * - * Returns LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID - * if invalid parameters are passed. - */ -extern enum lttng_event_rule_status lttng_event_rule_syscall_set_name_pattern( - struct lttng_event_rule *rule, const char *pattern); - -/* - * Get the name pattern of a syscall event rule. - * - * The caller does not assume the ownership of the returned pattern. The - * pattern shall only only be used for the duration of the event rule's - * lifetime, or before a different pattern is set. - * - * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's pattern - * on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid - * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a pattern - * was not set prior to this call. - */ -extern enum lttng_event_rule_status lttng_event_rule_syscall_get_name_pattern( - const struct lttng_event_rule *rule, const char **pattern); - -/* - * Set the filter expression of a syscall event rule. - * - * The expression is copied internally. - * - * Returns LTTNG_EVENT_RULE_STATUS_OK on success, LTTNG_EVENT_RULE_STATUS_INVALID - * if invalid parameters are passed. - */ -extern enum lttng_event_rule_status lttng_event_rule_syscall_set_filter( - struct lttng_event_rule *rule, const char *expression); - -/* - * Get the filter expression of a syscall event rule. - * - * The caller does not assume the ownership of the returned filter expression. - * The filter expression shall only only be used for the duration of the event - * rule's lifetime, or before a different filter expression is set. - * - * Returns LTTNG_EVENT_RULE_STATUS_OK and a pointer to the event rule's filter - * expression on success, LTTNG_EVENT_RULE_STATUS_INVALID if an invalid - * parameter is passed, or LTTNG_EVENT_RULE_STATUS_UNSET if a filter expression - * was not set prior to this call. - */ -extern enum lttng_event_rule_status lttng_event_rule_syscall_get_filter( - const struct lttng_event_rule *rule, const char **expression); - -/* - * Get the emission site of a syscall event rule. - * - * Returns a enum lttng_event_rule_syscall_emission_site. - */ -extern enum lttng_event_rule_syscall_emission_site -lttng_event_rule_syscall_get_emission_site( - const struct lttng_event_rule *rule); - -#ifdef __cplusplus -} -#endif - -#endif /* LTTNG_EVENT_RULE_SYSCALL_H */ diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 4736e8b34..fc242c511 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7ba6a4cd9..423bb0730 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -671,27 +671,27 @@ enum lttng_error_code trace_kernel_init_event_notifier_from_event_rule( ret_code = LTTNG_OK; break; } - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: { const enum lttng_event_rule_status status = - lttng_event_rule_syscall_get_name_pattern( + lttng_event_rule_kernel_syscall_get_name_pattern( rule, &name); - const enum lttng_event_rule_syscall_emission_site + const enum lttng_event_rule_kernel_syscall_emission_site emission_site = - lttng_event_rule_syscall_get_emission_site(rule); + lttng_event_rule_kernel_syscall_get_emission_site(rule); enum lttng_kernel_abi_syscall_entryexit entryexit; assert(status == LTTNG_EVENT_RULE_STATUS_OK); - assert(emission_site != LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN); + assert(emission_site != LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_UNKNOWN); switch(emission_site) { - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY: + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY: entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY; break; - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT: + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_EXIT: entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT; break; - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT: + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT: entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT; break; default: diff --git a/src/bin/lttng/commands/add_trigger.c b/src/bin/lttng/commands/add_trigger.c index 1cb35adc7..a1bfe240e 100644 --- a/src/bin/lttng/commands/add_trigger.c +++ b/src/bin/lttng/commands/add_trigger.c @@ -135,7 +135,9 @@ bool assign_event_rule_type(enum lttng_event_rule_type *dest, const char *arg) *dest = LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE; } else if (strcmp(arg, "function") == 0) { *dest = LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION; - } else if (strncmp(arg, "syscall", strlen("syscall")) == 0) { + } else if (strncmp(arg, "syscall", strlen("syscall")) == 0 || + strncmp(arg, "kernel:syscall", + strlen("kernel:syscall")) == 0) { /* * Matches the following: * - syscall @@ -143,10 +145,15 @@ bool assign_event_rule_type(enum lttng_event_rule_type *dest, const char *arg) * - syscall:exit * - syscall:entry+exit * - syscall:* + * - kernel:syscall + * - kernel:syscall:entry + * - kernel:syscall:exit + * - kernel:syscall:entry+exit + * - kernel:syscall:* * * Validation for the right side is left to further usage sites. */ - *dest = LTTNG_EVENT_RULE_TYPE_SYSCALL; + *dest = LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL; } else { ERR("Invalid `--type` value: %s", arg); goto error; @@ -189,16 +196,27 @@ end: } static bool parse_syscall_emission_site_from_type(const char *str, - enum lttng_event_rule_syscall_emission_site *type) + enum lttng_event_rule_kernel_syscall_emission_site *type) { bool ret = false; + const char kernel_prefix[] = "kernel:"; + const size_t kernel_prefix_len = sizeof(kernel_prefix) - 1; + + /* + * If the passed string is of the form "kernel:syscall*", move the + * pointer passed "kernel:". + */ + if (strncmp(str, kernel_prefix, kernel_prefix_len) == 0) { + str = &str[kernel_prefix_len]; + } + if (strcmp(str, "syscall") == 0 || strcmp(str, "syscall:entry+exit") == 0) { - *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT; + *type = LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT; } else if (strcmp(str, "syscall:entry") == 0) { - *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY; + *type = LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY; } else if (strcmp(str, "syscall:exit") == 0) { - *type = LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT; + *type = LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_EXIT; } else { goto error; } @@ -838,7 +856,7 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) */ switch (event_rule_type) { case LTTNG_EVENT_RULE_TYPE_TRACEPOINT: - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: if (!name) { name = strdup("*"); } @@ -917,7 +935,7 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE: case LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION: case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE: - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: if (domain_type != LTTNG_DOMAIN_KERNEL) { ERR("Event type not available for user-space tracing."); goto error; @@ -939,7 +957,7 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) if (filter && domain_type == LTTNG_DOMAIN_KERNEL) { switch (event_rule_type) { case LTTNG_EVENT_RULE_TYPE_TRACEPOINT: - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: break; default: ERR("Filter expressions are not supported for %s event rules.", @@ -1131,10 +1149,10 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) break; } - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: { enum lttng_event_rule_status event_rule_status; - enum lttng_event_rule_syscall_emission_site emission_site; + enum lttng_event_rule_kernel_syscall_emission_site emission_site; if (!parse_syscall_emission_site_from_type( event_rule_type_str, &emission_site)) { @@ -1142,13 +1160,13 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) goto error; } - res.er = lttng_event_rule_syscall_create(emission_site); + res.er = lttng_event_rule_kernel_syscall_create(emission_site); if (!res.er) { ERR("Failed to create syscall event rule."); goto error; } - event_rule_status = lttng_event_rule_syscall_set_name_pattern( + event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern( res.er, name); if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) { ERR("Failed to set syscall event rule's pattern to '%s'.", @@ -1157,7 +1175,7 @@ struct parse_event_rule_res parse_event_rule(int *argc, const char ***argv) } if (filter) { - event_rule_status = lttng_event_rule_syscall_set_filter( + event_rule_status = lttng_event_rule_kernel_syscall_set_filter( res.er, filter); if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) { ERR("Failed to set syscall event rule's filter to '%s'.", diff --git a/src/bin/lttng/commands/list_triggers.c b/src/bin/lttng/commands/list_triggers.c index 26dc201ec..10f76e843 100644 --- a/src/bin/lttng/commands/list_triggers.c +++ b/src/bin/lttng/commands/list_triggers.c @@ -18,8 +18,8 @@ #include "lttng/condition/event-rule-matches-internal.h" /* For lttng_domain_type_str(). */ #include "lttng/domain-internal.h" -/* For lttng_event_rule_syscall_emission_site_str() */ -#include "lttng/event-rule/syscall-internal.h" +/* For lttng_event_rule_kernel_syscall_emission_site_str() */ +#include "lttng/event-rule/kernel-syscall-internal.h" #include "../loglevel.h" #include @@ -389,22 +389,22 @@ void print_event_rule_syscall(const struct lttng_event_rule *event_rule) { const char *pattern, *filter; enum lttng_event_rule_status event_rule_status; - enum lttng_event_rule_syscall_emission_site emission_site; + enum lttng_event_rule_kernel_syscall_emission_site emission_site; - assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL); + assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL); emission_site = - lttng_event_rule_syscall_get_emission_site(event_rule); + lttng_event_rule_kernel_syscall_get_emission_site(event_rule); - event_rule_status = lttng_event_rule_syscall_get_name_pattern( + event_rule_status = lttng_event_rule_kernel_syscall_get_name_pattern( event_rule, &pattern); assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK); - _MSG(" rule: %s (type: syscall:%s", pattern, - lttng_event_rule_syscall_emission_site_str( + _MSG(" rule: %s (type: kernel:syscall:%s", pattern, + lttng_event_rule_kernel_syscall_emission_site_str( emission_site)); - event_rule_status = lttng_event_rule_syscall_get_filter( + event_rule_status = lttng_event_rule_kernel_syscall_get_filter( event_rule, &filter); if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) { _MSG(", filter: %s", filter); @@ -431,7 +431,7 @@ void print_event_rule(const struct lttng_event_rule *event_rule) case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE: print_event_rule_userspace_probe(event_rule); break; - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: print_event_rule_syscall(event_rule); break; default: diff --git a/src/common/Makefile.am b/src/common/Makefile.am index a38325d5a..32e9c02ab 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -66,7 +66,7 @@ libcommon_la_SOURCES = \ event-field-value.c \ event-rule/event-rule.c \ event-rule/kernel-probe.c \ - event-rule/syscall.c \ + event-rule/kernel-syscall.c \ event-rule/userspace-probe.c \ event-rule/tracepoint.c \ filter.c filter.h \ diff --git a/src/common/conditions/event-rule-matches.c b/src/common/conditions/event-rule-matches.c index bbde91aeb..b2abcc764 100644 --- a/src/common/conditions/event-rule-matches.c +++ b/src/common/conditions/event-rule-matches.c @@ -798,7 +798,7 @@ lttng_condition_event_rule_matches_append_capture_descriptor( switch(lttng_event_rule_get_type(rule)) { case LTTNG_EVENT_RULE_TYPE_TRACEPOINT: - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: /* Supported. */ status = LTTNG_CONDITION_STATUS_OK; break; diff --git a/src/common/event-rule/event-rule.c b/src/common/event-rule/event-rule.c index 841e182b3..0443c75e9 100644 --- a/src/common/event-rule/event-rule.c +++ b/src/common/event-rule/event-rule.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -40,7 +40,7 @@ enum lttng_domain_type lttng_event_rule_get_domain_type( assert(status == LTTNG_EVENT_RULE_STATUS_OK); break; } - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE: case LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION: case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE: @@ -181,9 +181,9 @@ ssize_t lttng_event_rule_create_from_payload( case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE: create_from_payload = lttng_event_rule_userspace_probe_create_from_payload; break; - case LTTNG_EVENT_RULE_TYPE_SYSCALL: + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: create_from_payload = - lttng_event_rule_syscall_create_from_payload; + lttng_event_rule_kernel_syscall_create_from_payload; break; default: ERR("Attempted to create event rule of unknown type (%i)", @@ -313,8 +313,8 @@ const char *lttng_event_rule_type_str(enum lttng_event_rule_type type) return "unknown"; case LTTNG_EVENT_RULE_TYPE_TRACEPOINT: return "tracepoint"; - case LTTNG_EVENT_RULE_TYPE_SYSCALL: - return "syscall"; + case LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL: + return "kernel syscall"; case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE: return "probe"; case LTTNG_EVENT_RULE_TYPE_KERNEL_FUNCTION: diff --git a/src/common/event-rule/kernel-syscall.c b/src/common/event-rule/kernel-syscall.c new file mode 100644 index 000000000..a2a77a3c4 --- /dev/null +++ b/src/common/event-rule/kernel-syscall.c @@ -0,0 +1,553 @@ +/* + * Copyright (C) 2019 Jonathan Rajotte + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IS_SYSCALL_EVENT_RULE(rule) \ + (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL) + +static void lttng_event_rule_kernel_syscall_destroy(struct lttng_event_rule *rule) +{ + struct lttng_event_rule_kernel_syscall *syscall; + + if (rule == NULL) { + return; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + free(syscall->pattern); + free(syscall->filter_expression); + free(syscall->internal_filter.filter); + free(syscall->internal_filter.bytecode); + free(syscall); +} + +static bool lttng_event_rule_kernel_syscall_validate( + const struct lttng_event_rule *rule) +{ + bool valid = false; + struct lttng_event_rule_kernel_syscall *syscall; + + if (!rule) { + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + /* Required field. */ + if (!syscall->pattern) { + ERR("Invalid syscall event rule: a pattern must be set."); + goto end; + } + + valid = true; +end: + return valid; +} + +static int lttng_event_rule_kernel_syscall_serialize( + const struct lttng_event_rule *rule, + struct lttng_payload *payload) +{ + int ret; + size_t pattern_len, filter_expression_len; + struct lttng_event_rule_kernel_syscall *syscall; + struct lttng_event_rule_kernel_syscall_comm syscall_comm; + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule)) { + ret = -1; + goto end; + } + + DBG("Serializing syscall event rule"); + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + pattern_len = strlen(syscall->pattern) + 1; + + if (syscall->filter_expression != NULL) { + filter_expression_len = strlen(syscall->filter_expression) + 1; + } else { + filter_expression_len = 0; + } + + syscall_comm.pattern_len = pattern_len; + syscall_comm.filter_expression_len = filter_expression_len; + syscall_comm.emission_site = syscall->emission_site; + + ret = lttng_dynamic_buffer_append( + &payload->buffer, &syscall_comm, sizeof(syscall_comm)); + if (ret) { + goto end; + } + + ret = lttng_dynamic_buffer_append( + &payload->buffer, syscall->pattern, pattern_len); + if (ret) { + goto end; + } + + ret = lttng_dynamic_buffer_append(&payload->buffer, + syscall->filter_expression, filter_expression_len); +end: + return ret; +} + +static bool lttng_event_rule_kernel_syscall_is_equal(const struct lttng_event_rule *_a, + const struct lttng_event_rule *_b) +{ + bool is_equal = false; + struct lttng_event_rule_kernel_syscall *a, *b; + + a = container_of(_a, struct lttng_event_rule_kernel_syscall, parent); + b = container_of(_b, struct lttng_event_rule_kernel_syscall, parent); + + if (!!a->filter_expression != !!b->filter_expression) { + goto end; + } + + assert(a->pattern); + assert(b->pattern); + if (strcmp(a->pattern, b->pattern)) { + goto end; + } + + if (a->filter_expression && b->filter_expression) { + if (strcmp(a->filter_expression, b->filter_expression)) { + goto end; + } + } else if (!!a->filter_expression != !!b->filter_expression) { + /* One is set and not the other. */ + goto end; + } + + is_equal = true; +end: + return is_equal; +} + +static enum lttng_error_code lttng_event_rule_kernel_syscall_generate_filter_bytecode( + struct lttng_event_rule *rule, + const struct lttng_credentials *creds) +{ + int ret; + enum lttng_error_code ret_code = LTTNG_OK; + struct lttng_event_rule_kernel_syscall *syscall; + enum lttng_event_rule_status status; + const char *filter; + struct lttng_bytecode *bytecode = NULL; + + assert(rule); + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + /* Generate the filter bytecode. */ + status = lttng_event_rule_kernel_syscall_get_filter(rule, &filter); + if (status == LTTNG_EVENT_RULE_STATUS_UNSET) { + filter = NULL; + } else if (status != LTTNG_EVENT_RULE_STATUS_OK) { + ret_code = LTTNG_ERR_FILTER_INVAL; + goto end; + } + + if (filter && filter[0] == '\0') { + ret_code = LTTNG_ERR_FILTER_INVAL; + goto end; + } + + if (filter == NULL) { + /* Nothing to do. */ + ret = LTTNG_OK; + goto end; + } + + syscall->internal_filter.filter = strdup(filter); + if (syscall->internal_filter.filter == NULL) { + ret_code = LTTNG_ERR_NOMEM; + goto end; + } + + ret = run_as_generate_filter_bytecode( + syscall->internal_filter.filter, creds, &bytecode); + if (ret) { + ret_code = LTTNG_ERR_FILTER_INVAL; + } + + syscall->internal_filter.bytecode = bytecode; + bytecode = NULL; + +end: + free(bytecode); + return ret_code; +} + +static const char *lttng_event_rule_kernel_syscall_get_internal_filter( + const struct lttng_event_rule *rule) +{ + struct lttng_event_rule_kernel_syscall *syscall; + + assert(rule); + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + return syscall->internal_filter.filter; +} + +static const struct lttng_bytecode * +lttng_event_rule_kernel_syscall_get_internal_filter_bytecode( + const struct lttng_event_rule *rule) +{ + struct lttng_event_rule_kernel_syscall *syscall; + + assert(rule); + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + + return syscall->internal_filter.bytecode; +} + +static enum lttng_event_rule_generate_exclusions_status +lttng_event_rule_kernel_syscall_generate_exclusions(const struct lttng_event_rule *rule, + struct lttng_event_exclusion **exclusions) +{ + /* Unsupported. */ + *exclusions = NULL; + return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE; +} + +static unsigned long +lttng_event_rule_kernel_syscall_hash( + const struct lttng_event_rule *rule) +{ + unsigned long hash; + struct lttng_event_rule_kernel_syscall *syscall_rule = + container_of(rule, typeof(*syscall_rule), parent); + + hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL, + lttng_ht_seed); + hash ^= hash_key_str(syscall_rule->pattern, lttng_ht_seed); + if (syscall_rule->filter_expression) { + hash ^= hash_key_str(syscall_rule->filter_expression, + lttng_ht_seed); + } + + return hash; +} + +struct lttng_event_rule *lttng_event_rule_kernel_syscall_create( + enum lttng_event_rule_kernel_syscall_emission_site + emission_site) +{ + struct lttng_event_rule *rule = NULL; + struct lttng_event_rule_kernel_syscall *syscall_rule; + enum lttng_event_rule_status status; + + /* Validate the emission site type */ + switch (emission_site) { + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT: + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY: + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_EXIT: + break; + default: + /* Invalid emission type */ + goto end; + } + + syscall_rule = zmalloc(sizeof(struct lttng_event_rule_kernel_syscall)); + if (!syscall_rule) { + goto end; + } + + rule = &syscall_rule->parent; + lttng_event_rule_init( + &syscall_rule->parent, LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL); + syscall_rule->parent.validate = lttng_event_rule_kernel_syscall_validate; + syscall_rule->parent.serialize = lttng_event_rule_kernel_syscall_serialize; + syscall_rule->parent.equal = lttng_event_rule_kernel_syscall_is_equal; + syscall_rule->parent.destroy = lttng_event_rule_kernel_syscall_destroy; + syscall_rule->parent.generate_filter_bytecode = + lttng_event_rule_kernel_syscall_generate_filter_bytecode; + syscall_rule->parent.get_filter = + lttng_event_rule_kernel_syscall_get_internal_filter; + syscall_rule->parent.get_filter_bytecode = + lttng_event_rule_kernel_syscall_get_internal_filter_bytecode; + syscall_rule->parent.generate_exclusions = + lttng_event_rule_kernel_syscall_generate_exclusions; + syscall_rule->parent.hash = lttng_event_rule_kernel_syscall_hash; + + /* Default pattern is '*'. */ + status = lttng_event_rule_kernel_syscall_set_name_pattern(rule, "*"); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + lttng_event_rule_destroy(rule); + rule = NULL; + } + + /* Emission site type */ + syscall_rule->emission_site = emission_site; + +end: + return rule; +} + +LTTNG_HIDDEN +ssize_t lttng_event_rule_kernel_syscall_create_from_payload( + struct lttng_payload_view *view, + struct lttng_event_rule **_event_rule) +{ + ssize_t ret, offset = 0; + enum lttng_event_rule_status status; + const struct lttng_event_rule_kernel_syscall_comm *syscall_comm; + const char *pattern; + const char *filter_expression = NULL; + struct lttng_buffer_view current_buffer_view; + struct lttng_event_rule *rule = NULL; + + if (!_event_rule) { + ret = -1; + goto end; + } + + if (view->buffer.size < sizeof(*syscall_comm)) { + ERR("Failed to initialize from malformed event rule syscall: buffer too short to contain header"); + ret = -1; + goto end; + } + + current_buffer_view = lttng_buffer_view_from_view( + &view->buffer, offset, sizeof(*syscall_comm)); + if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { + ret = -1; + goto end; + } + + syscall_comm = (typeof(syscall_comm)) current_buffer_view.data; + rule = lttng_event_rule_kernel_syscall_create(syscall_comm->emission_site); + if (!rule) { + ERR("Failed to create event rule syscall"); + ret = -1; + goto end; + } + + /* Skip to payload. */ + offset += current_buffer_view.size; + + /* Map the pattern. */ + current_buffer_view = lttng_buffer_view_from_view( + &view->buffer, offset, syscall_comm->pattern_len); + if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { + ret = -1; + goto end; + } + + pattern = current_buffer_view.data; + if (!lttng_buffer_view_contains_string(¤t_buffer_view, pattern, + syscall_comm->pattern_len)) { + ret = -1; + goto end; + } + + /* Skip after the pattern. */ + offset += syscall_comm->pattern_len; + + if (!syscall_comm->filter_expression_len) { + goto skip_filter_expression; + } + + /* Map the filter_expression. */ + current_buffer_view = lttng_buffer_view_from_view(&view->buffer, offset, + syscall_comm->filter_expression_len); + if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { + ret = -1; + goto end; + } + + filter_expression = current_buffer_view.data; + if (!lttng_buffer_view_contains_string(¤t_buffer_view, + filter_expression, + syscall_comm->filter_expression_len)) { + ret = -1; + goto end; + } + + /* Skip after the pattern. */ + offset += syscall_comm->filter_expression_len; + +skip_filter_expression: + + status = lttng_event_rule_kernel_syscall_set_name_pattern(rule, pattern); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + ERR("Failed to set event rule syscall pattern"); + ret = -1; + goto end; + } + + if (filter_expression) { + status = lttng_event_rule_kernel_syscall_set_filter( + rule, filter_expression); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + ERR("Failed to set event rule syscall pattern"); + ret = -1; + goto end; + } + } + + *_event_rule = rule; + rule = NULL; + ret = offset; +end: + lttng_event_rule_destroy(rule); + return ret; +} + +enum lttng_event_rule_status lttng_event_rule_kernel_syscall_set_name_pattern( + struct lttng_event_rule *rule, const char *pattern) +{ + char *pattern_copy = NULL; + struct lttng_event_rule_kernel_syscall *syscall; + enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !pattern || + strlen(pattern) == 0) { + status = LTTNG_EVENT_RULE_STATUS_INVALID; + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + pattern_copy = strdup(pattern); + if (!pattern_copy) { + status = LTTNG_EVENT_RULE_STATUS_ERROR; + goto end; + } + + strutils_normalize_star_glob_pattern(pattern_copy); + + free(syscall->pattern); + + syscall->pattern = pattern_copy; + pattern_copy = NULL; +end: + return status; +} + +enum lttng_event_rule_status lttng_event_rule_kernel_syscall_get_name_pattern( + const struct lttng_event_rule *rule, const char **pattern) +{ + struct lttng_event_rule_kernel_syscall *syscall; + enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !pattern) { + status = LTTNG_EVENT_RULE_STATUS_INVALID; + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + if (!syscall->pattern) { + status = LTTNG_EVENT_RULE_STATUS_UNSET; + goto end; + } + + *pattern = syscall->pattern; +end: + return status; +} + +enum lttng_event_rule_status lttng_event_rule_kernel_syscall_set_filter( + struct lttng_event_rule *rule, const char *expression) +{ + char *expression_copy = NULL; + struct lttng_event_rule_kernel_syscall *syscall; + enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; + + /* TODO: validate that the passed expression is valid. */ + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !expression || + strlen(expression) == 0) { + status = LTTNG_EVENT_RULE_STATUS_INVALID; + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + expression_copy = strdup(expression); + if (!expression_copy) { + status = LTTNG_EVENT_RULE_STATUS_ERROR; + goto end; + } + + if (syscall->filter_expression) { + free(syscall->filter_expression); + } + + syscall->filter_expression = expression_copy; + expression_copy = NULL; +end: + return status; +} + +enum lttng_event_rule_status lttng_event_rule_kernel_syscall_get_filter( + const struct lttng_event_rule *rule, const char **expression) +{ + struct lttng_event_rule_kernel_syscall *syscall; + enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !expression) { + status = LTTNG_EVENT_RULE_STATUS_INVALID; + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + if (!syscall->filter_expression) { + status = LTTNG_EVENT_RULE_STATUS_UNSET; + goto end; + } + + *expression = syscall->filter_expression; +end: + return status; +} +extern enum lttng_event_rule_kernel_syscall_emission_site +lttng_event_rule_kernel_syscall_get_emission_site( + const struct lttng_event_rule *rule) +{ + enum lttng_event_rule_kernel_syscall_emission_site emission_site = + LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_UNKNOWN; + struct lttng_event_rule_kernel_syscall *syscall; + + if (!rule || !IS_SYSCALL_EVENT_RULE(rule)) { + goto end; + } + + syscall = container_of(rule, struct lttng_event_rule_kernel_syscall, parent); + emission_site = syscall->emission_site; + +end: + return emission_site; +} + +LTTNG_HIDDEN +const char *lttng_event_rule_kernel_syscall_emission_site_str( + enum lttng_event_rule_kernel_syscall_emission_site emission_site) +{ + switch (emission_site) { + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY: + return "entry"; + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY_EXIT: + return "entry+exit"; + case LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_EXIT: + return "exit"; + default: + return "???"; + } +} diff --git a/src/common/event-rule/syscall.c b/src/common/event-rule/syscall.c deleted file mode 100644 index 4ac6a11af..000000000 --- a/src/common/event-rule/syscall.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (C) 2019 Jonathan Rajotte - * - * SPDX-License-Identifier: LGPL-2.1-only - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IS_SYSCALL_EVENT_RULE(rule) \ - (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL) - -static void lttng_event_rule_syscall_destroy(struct lttng_event_rule *rule) -{ - struct lttng_event_rule_syscall *syscall; - - if (rule == NULL) { - return; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - free(syscall->pattern); - free(syscall->filter_expression); - free(syscall->internal_filter.filter); - free(syscall->internal_filter.bytecode); - free(syscall); -} - -static bool lttng_event_rule_syscall_validate( - const struct lttng_event_rule *rule) -{ - bool valid = false; - struct lttng_event_rule_syscall *syscall; - - if (!rule) { - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - /* Required field. */ - if (!syscall->pattern) { - ERR("Invalid syscall event rule: a pattern must be set."); - goto end; - } - - valid = true; -end: - return valid; -} - -static int lttng_event_rule_syscall_serialize( - const struct lttng_event_rule *rule, - struct lttng_payload *payload) -{ - int ret; - size_t pattern_len, filter_expression_len; - struct lttng_event_rule_syscall *syscall; - struct lttng_event_rule_syscall_comm syscall_comm; - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule)) { - ret = -1; - goto end; - } - - DBG("Serializing syscall event rule"); - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - pattern_len = strlen(syscall->pattern) + 1; - - if (syscall->filter_expression != NULL) { - filter_expression_len = strlen(syscall->filter_expression) + 1; - } else { - filter_expression_len = 0; - } - - syscall_comm.pattern_len = pattern_len; - syscall_comm.filter_expression_len = filter_expression_len; - syscall_comm.emission_site = syscall->emission_site; - - ret = lttng_dynamic_buffer_append( - &payload->buffer, &syscall_comm, sizeof(syscall_comm)); - if (ret) { - goto end; - } - - ret = lttng_dynamic_buffer_append( - &payload->buffer, syscall->pattern, pattern_len); - if (ret) { - goto end; - } - - ret = lttng_dynamic_buffer_append(&payload->buffer, - syscall->filter_expression, filter_expression_len); -end: - return ret; -} - -static bool lttng_event_rule_syscall_is_equal(const struct lttng_event_rule *_a, - const struct lttng_event_rule *_b) -{ - bool is_equal = false; - struct lttng_event_rule_syscall *a, *b; - - a = container_of(_a, struct lttng_event_rule_syscall, parent); - b = container_of(_b, struct lttng_event_rule_syscall, parent); - - if (!!a->filter_expression != !!b->filter_expression) { - goto end; - } - - assert(a->pattern); - assert(b->pattern); - if (strcmp(a->pattern, b->pattern)) { - goto end; - } - - if (a->filter_expression && b->filter_expression) { - if (strcmp(a->filter_expression, b->filter_expression)) { - goto end; - } - } else if (!!a->filter_expression != !!b->filter_expression) { - /* One is set and not the other. */ - goto end; - } - - is_equal = true; -end: - return is_equal; -} - -static enum lttng_error_code lttng_event_rule_syscall_generate_filter_bytecode( - struct lttng_event_rule *rule, - const struct lttng_credentials *creds) -{ - int ret; - enum lttng_error_code ret_code = LTTNG_OK; - struct lttng_event_rule_syscall *syscall; - enum lttng_event_rule_status status; - const char *filter; - struct lttng_bytecode *bytecode = NULL; - - assert(rule); - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - /* Generate the filter bytecode. */ - status = lttng_event_rule_syscall_get_filter(rule, &filter); - if (status == LTTNG_EVENT_RULE_STATUS_UNSET) { - filter = NULL; - } else if (status != LTTNG_EVENT_RULE_STATUS_OK) { - ret_code = LTTNG_ERR_FILTER_INVAL; - goto end; - } - - if (filter && filter[0] == '\0') { - ret_code = LTTNG_ERR_FILTER_INVAL; - goto end; - } - - if (filter == NULL) { - /* Nothing to do. */ - ret = LTTNG_OK; - goto end; - } - - syscall->internal_filter.filter = strdup(filter); - if (syscall->internal_filter.filter == NULL) { - ret_code = LTTNG_ERR_NOMEM; - goto end; - } - - ret = run_as_generate_filter_bytecode( - syscall->internal_filter.filter, creds, &bytecode); - if (ret) { - ret_code = LTTNG_ERR_FILTER_INVAL; - } - - syscall->internal_filter.bytecode = bytecode; - bytecode = NULL; - -end: - free(bytecode); - return ret_code; -} - -static const char *lttng_event_rule_syscall_get_internal_filter( - const struct lttng_event_rule *rule) -{ - struct lttng_event_rule_syscall *syscall; - - assert(rule); - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - return syscall->internal_filter.filter; -} - -static const struct lttng_bytecode * -lttng_event_rule_syscall_get_internal_filter_bytecode( - const struct lttng_event_rule *rule) -{ - struct lttng_event_rule_syscall *syscall; - - assert(rule); - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - - return syscall->internal_filter.bytecode; -} - -static enum lttng_event_rule_generate_exclusions_status -lttng_event_rule_syscall_generate_exclusions(const struct lttng_event_rule *rule, - struct lttng_event_exclusion **exclusions) -{ - /* Unsupported. */ - *exclusions = NULL; - return LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE; -} - -static unsigned long -lttng_event_rule_syscall_hash( - const struct lttng_event_rule *rule) -{ - unsigned long hash; - struct lttng_event_rule_syscall *syscall_rule = - container_of(rule, typeof(*syscall_rule), parent); - - hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_SYSCALL, - lttng_ht_seed); - hash ^= hash_key_str(syscall_rule->pattern, lttng_ht_seed); - if (syscall_rule->filter_expression) { - hash ^= hash_key_str(syscall_rule->filter_expression, - lttng_ht_seed); - } - - return hash; -} - -struct lttng_event_rule *lttng_event_rule_syscall_create( - enum lttng_event_rule_syscall_emission_site - emission_site) -{ - struct lttng_event_rule *rule = NULL; - struct lttng_event_rule_syscall *syscall_rule; - enum lttng_event_rule_status status; - - /* Validate the emission site type */ - switch (emission_site) { - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT: - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY: - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT: - break; - default: - /* Invalid emission type */ - goto end; - } - - syscall_rule = zmalloc(sizeof(struct lttng_event_rule_syscall)); - if (!syscall_rule) { - goto end; - } - - rule = &syscall_rule->parent; - lttng_event_rule_init( - &syscall_rule->parent, LTTNG_EVENT_RULE_TYPE_SYSCALL); - syscall_rule->parent.validate = lttng_event_rule_syscall_validate; - syscall_rule->parent.serialize = lttng_event_rule_syscall_serialize; - syscall_rule->parent.equal = lttng_event_rule_syscall_is_equal; - syscall_rule->parent.destroy = lttng_event_rule_syscall_destroy; - syscall_rule->parent.generate_filter_bytecode = - lttng_event_rule_syscall_generate_filter_bytecode; - syscall_rule->parent.get_filter = - lttng_event_rule_syscall_get_internal_filter; - syscall_rule->parent.get_filter_bytecode = - lttng_event_rule_syscall_get_internal_filter_bytecode; - syscall_rule->parent.generate_exclusions = - lttng_event_rule_syscall_generate_exclusions; - syscall_rule->parent.hash = lttng_event_rule_syscall_hash; - - /* Default pattern is '*'. */ - status = lttng_event_rule_syscall_set_name_pattern(rule, "*"); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - lttng_event_rule_destroy(rule); - rule = NULL; - } - - /* Emission site type */ - syscall_rule->emission_site = emission_site; - -end: - return rule; -} - -LTTNG_HIDDEN -ssize_t lttng_event_rule_syscall_create_from_payload( - struct lttng_payload_view *view, - struct lttng_event_rule **_event_rule) -{ - ssize_t ret, offset = 0; - enum lttng_event_rule_status status; - const struct lttng_event_rule_syscall_comm *syscall_comm; - const char *pattern; - const char *filter_expression = NULL; - struct lttng_buffer_view current_buffer_view; - struct lttng_event_rule *rule = NULL; - - if (!_event_rule) { - ret = -1; - goto end; - } - - if (view->buffer.size < sizeof(*syscall_comm)) { - ERR("Failed to initialize from malformed event rule syscall: buffer too short to contain header"); - ret = -1; - goto end; - } - - current_buffer_view = lttng_buffer_view_from_view( - &view->buffer, offset, sizeof(*syscall_comm)); - if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { - ret = -1; - goto end; - } - - syscall_comm = (typeof(syscall_comm)) current_buffer_view.data; - rule = lttng_event_rule_syscall_create(syscall_comm->emission_site); - if (!rule) { - ERR("Failed to create event rule syscall"); - ret = -1; - goto end; - } - - /* Skip to payload. */ - offset += current_buffer_view.size; - - /* Map the pattern. */ - current_buffer_view = lttng_buffer_view_from_view( - &view->buffer, offset, syscall_comm->pattern_len); - if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { - ret = -1; - goto end; - } - - pattern = current_buffer_view.data; - if (!lttng_buffer_view_contains_string(¤t_buffer_view, pattern, - syscall_comm->pattern_len)) { - ret = -1; - goto end; - } - - /* Skip after the pattern. */ - offset += syscall_comm->pattern_len; - - if (!syscall_comm->filter_expression_len) { - goto skip_filter_expression; - } - - /* Map the filter_expression. */ - current_buffer_view = lttng_buffer_view_from_view(&view->buffer, offset, - syscall_comm->filter_expression_len); - if (!lttng_buffer_view_is_valid(¤t_buffer_view)) { - ret = -1; - goto end; - } - - filter_expression = current_buffer_view.data; - if (!lttng_buffer_view_contains_string(¤t_buffer_view, - filter_expression, - syscall_comm->filter_expression_len)) { - ret = -1; - goto end; - } - - /* Skip after the pattern. */ - offset += syscall_comm->filter_expression_len; - -skip_filter_expression: - - status = lttng_event_rule_syscall_set_name_pattern(rule, pattern); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - ERR("Failed to set event rule syscall pattern"); - ret = -1; - goto end; - } - - if (filter_expression) { - status = lttng_event_rule_syscall_set_filter( - rule, filter_expression); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - ERR("Failed to set event rule syscall pattern"); - ret = -1; - goto end; - } - } - - *_event_rule = rule; - rule = NULL; - ret = offset; -end: - lttng_event_rule_destroy(rule); - return ret; -} - -enum lttng_event_rule_status lttng_event_rule_syscall_set_name_pattern( - struct lttng_event_rule *rule, const char *pattern) -{ - char *pattern_copy = NULL; - struct lttng_event_rule_syscall *syscall; - enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !pattern || - strlen(pattern) == 0) { - status = LTTNG_EVENT_RULE_STATUS_INVALID; - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - pattern_copy = strdup(pattern); - if (!pattern_copy) { - status = LTTNG_EVENT_RULE_STATUS_ERROR; - goto end; - } - - strutils_normalize_star_glob_pattern(pattern_copy); - - free(syscall->pattern); - - syscall->pattern = pattern_copy; - pattern_copy = NULL; -end: - return status; -} - -enum lttng_event_rule_status lttng_event_rule_syscall_get_name_pattern( - const struct lttng_event_rule *rule, const char **pattern) -{ - struct lttng_event_rule_syscall *syscall; - enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !pattern) { - status = LTTNG_EVENT_RULE_STATUS_INVALID; - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - if (!syscall->pattern) { - status = LTTNG_EVENT_RULE_STATUS_UNSET; - goto end; - } - - *pattern = syscall->pattern; -end: - return status; -} - -enum lttng_event_rule_status lttng_event_rule_syscall_set_filter( - struct lttng_event_rule *rule, const char *expression) -{ - char *expression_copy = NULL; - struct lttng_event_rule_syscall *syscall; - enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; - - /* TODO: validate that the passed expression is valid. */ - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !expression || - strlen(expression) == 0) { - status = LTTNG_EVENT_RULE_STATUS_INVALID; - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - expression_copy = strdup(expression); - if (!expression_copy) { - status = LTTNG_EVENT_RULE_STATUS_ERROR; - goto end; - } - - if (syscall->filter_expression) { - free(syscall->filter_expression); - } - - syscall->filter_expression = expression_copy; - expression_copy = NULL; -end: - return status; -} - -enum lttng_event_rule_status lttng_event_rule_syscall_get_filter( - const struct lttng_event_rule *rule, const char **expression) -{ - struct lttng_event_rule_syscall *syscall; - enum lttng_event_rule_status status = LTTNG_EVENT_RULE_STATUS_OK; - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule) || !expression) { - status = LTTNG_EVENT_RULE_STATUS_INVALID; - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - if (!syscall->filter_expression) { - status = LTTNG_EVENT_RULE_STATUS_UNSET; - goto end; - } - - *expression = syscall->filter_expression; -end: - return status; -} -extern enum lttng_event_rule_syscall_emission_site -lttng_event_rule_syscall_get_emission_site( - const struct lttng_event_rule *rule) -{ - enum lttng_event_rule_syscall_emission_site emission_site = - LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_UNKNOWN; - struct lttng_event_rule_syscall *syscall; - - if (!rule || !IS_SYSCALL_EVENT_RULE(rule)) { - goto end; - } - - syscall = container_of(rule, struct lttng_event_rule_syscall, parent); - emission_site = syscall->emission_site; - -end: - return emission_site; -} - -LTTNG_HIDDEN -const char *lttng_event_rule_syscall_emission_site_str( - enum lttng_event_rule_syscall_emission_site emission_site) -{ - switch (emission_site) { - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY: - return "entry"; - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY_EXIT: - return "entry+exit"; - case LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_EXIT: - return "exit"; - default: - return "???"; - } -} diff --git a/tests/regression/tools/notification/notification.c b/tests/regression/tools/notification/notification.c index 9638bb452..e089d47c0 100644 --- a/tests/regression/tools/notification/notification.c +++ b/tests/regression/tools/notification/notification.c @@ -2054,10 +2054,10 @@ static void test_syscall_event_rule_notification( lttng_session_daemon_notification_endpoint); ok(notification_channel, "Notification channel object creation"); - event_rule = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY); + event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY); ok(event_rule, "syscall event rule object creation"); - event_rule_status = lttng_event_rule_syscall_set_name_pattern( + event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern( event_rule, syscall_name); ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK, "Setting syscall event rule pattern: '%s'", syscall_name); @@ -2140,15 +2140,15 @@ static void test_syscall_event_rule_notification_filter( lttng_session_daemon_notification_endpoint); ok(notification_channel, "Notification channel object creation"); - event_rule = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY); + event_rule = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY); ok(event_rule, "syscall event rule object creation"); - event_rule_status = lttng_event_rule_syscall_set_name_pattern( + event_rule_status = lttng_event_rule_kernel_syscall_set_name_pattern( event_rule, syscall_name); ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK, "Setting syscall event rule pattern: '%s'", syscall_name); - event_rule_status = lttng_event_rule_syscall_set_filter( + event_rule_status = lttng_event_rule_kernel_syscall_set_filter( event_rule, filter_pattern); ok(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK, "Setting filter: '%s'", filter_pattern); diff --git a/tests/regression/tools/trigger/test_add_trigger_cli b/tests/regression/tools/trigger/test_add_trigger_cli index 0b551d4d1..029f17cef 100755 --- a/tests/regression/tools/trigger/test_add_trigger_cli +++ b/tests/regression/tools/trigger/test_add_trigger_cli @@ -23,7 +23,7 @@ TESTDIR="$CURDIR/../../.." # shellcheck source=../../../utils/utils.sh source "$TESTDIR/utils/utils.sh" -plan_tests 285 +plan_tests 297 FULL_LTTNG_BIN="${TESTDIR}/../src/bin/lttng/${LTTNG_BIN}" @@ -190,7 +190,7 @@ skip $ist_root "non-root user: skipping uprobe tests" 12 || { done } -skip $ist_root "non-root user: skipping syscall tests" 18 || { +skip $ist_root "non-root user: skipping syscall tests" 30 || { test_success "--condition event-rule-matches one syscall" \ --condition event-rule-matches --domain=kernel --type=syscall --name=open \ --action notify @@ -211,6 +211,22 @@ skip $ist_root "non-root user: skipping syscall tests" 18 || { test_success "--condition event-rule-matches one syscall:entry-exit" \ --condition event-rule-matches --domain=kernel --type=syscall:entry+exit --name=open \ --action notify + + # Same thing but with "kernel:syscall" type instead: + test_success "--condition event-rule-matches one syscall" \ + --condition event-rule-matches --domain=kernel --type=kernel:syscall --name=open \ + --action notify + + test_success "--condition event-rule-matches one kernel:syscall:entry" \ + --condition event-rule-matches --domain=kernel --type=kernel:syscall:entry --name=open \ + --action notify + test_success "--condition event-rule-matches one kernel:syscall:exit" \ + --condition event-rule-matches --domain=kernel --type=kernel:syscall:exit --name=open \ + --action notify + test_success "--condition event-rule-matches one kernel:syscall:entry-exit" \ + --condition event-rule-matches --domain=kernel --type=kernel:syscall:entry+exit --name=open \ + --action notify + } # `--action notify` successes diff --git a/tests/regression/tools/trigger/test_list_triggers_cli b/tests/regression/tools/trigger/test_list_triggers_cli index 26f2f9f46..cfeab29b7 100755 --- a/tests/regression/tools/trigger/test_list_triggers_cli +++ b/tests/regression/tools/trigger/test_list_triggers_cli @@ -318,7 +318,7 @@ test_event_rule_matches_syscall () - name: T0 owner uid: ${uid} condition: event rule matches - rule: open (type: syscall:entry+exit) + rule: open (type: kernel:syscall:entry+exit) actions: notify errors: none @@ -326,7 +326,7 @@ test_event_rule_matches_syscall () - name: T1 owner uid: ${uid} condition: event rule matches - rule: open (type: syscall:entry) + rule: open (type: kernel:syscall:entry) actions: notify errors: none @@ -334,7 +334,7 @@ test_event_rule_matches_syscall () - name: T2 owner uid: ${uid} condition: event rule matches - rule: open (type: syscall:exit) + rule: open (type: kernel:syscall:exit) actions: notify errors: none @@ -342,7 +342,7 @@ test_event_rule_matches_syscall () - name: T3 owner uid: ${uid} condition: event rule matches - rule: open (type: syscall:entry+exit) + rule: open (type: kernel:syscall:entry+exit) actions: notify errors: none @@ -350,7 +350,7 @@ test_event_rule_matches_syscall () - name: T4 owner uid: ${uid} condition: event rule matches - rule: ptrace (type: syscall:entry+exit, filter: a > 2) + rule: ptrace (type: kernel:syscall:entry+exit, filter: a > 2) actions: notify errors: none diff --git a/tests/unit/test_event_rule.c b/tests/unit/test_event_rule.c index f30343b30..6ec49fe66 100644 --- a/tests/unit/test_event_rule.c +++ b/tests/unit/test_event_rule.c @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -184,18 +184,18 @@ static void test_event_rule_syscall(void) lttng_payload_init(&payload); - syscall = lttng_event_rule_syscall_create(LTTNG_EVENT_RULE_SYSCALL_EMISSION_SITE_ENTRY); + syscall = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY); ok(syscall, "syscall object."); - status = lttng_event_rule_syscall_set_name_pattern(syscall, pattern); + status = lttng_event_rule_kernel_syscall_set_name_pattern(syscall, pattern); ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); - status = lttng_event_rule_syscall_get_name_pattern(syscall, &tmp); + status = lttng_event_rule_kernel_syscall_get_name_pattern(syscall, &tmp); ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); - status = lttng_event_rule_syscall_set_filter(syscall, filter); + status = lttng_event_rule_kernel_syscall_set_filter(syscall, filter); ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); - status = lttng_event_rule_syscall_get_filter(syscall, &tmp); + status = lttng_event_rule_kernel_syscall_get_filter(syscall, &tmp); ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal.");