X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fevent-rule%2Ftracepoint.c;h=93de1e98ce936c28ffe1dfb6a634595e51b8353b;hp=0d0864719df5425500bb04f11c1665dbeaa1bdc1;hb=cb6096aac522cc9b005eb704d40c6aac00e384ab;hpb=58daac01d91347336f24e1fc1cacd4e7a3101e93 diff --git a/src/common/event-rule/tracepoint.c b/src/common/event-rule/tracepoint.c index 0d0864719..93de1e98c 100644 --- a/src/common/event-rule/tracepoint.c +++ b/src/common/event-rule/tracepoint.c @@ -12,8 +12,11 @@ #include #include #include +#include +#include #include #include +#include #define IS_TRACEPOINT_EVENT_RULE(rule) \ (lttng_event_rule_get_type(rule) == LTTNG_EVENT_RULE_TYPE_TRACEPOINT) @@ -367,7 +370,7 @@ lttng_event_rule_tracepoint_generate_filter_bytecode( enum lttng_domain_type domain_type; enum lttng_event_rule_status status; const char *filter; - struct lttng_filter_bytecode *bytecode = NULL; + struct lttng_bytecode *bytecode = NULL; assert(rule); @@ -459,7 +462,7 @@ static const char *lttng_event_rule_tracepoint_get_internal_filter( return tracepoint->internal_filter.filter; } -static const struct lttng_filter_bytecode * +static const struct lttng_bytecode * lttng_event_rule_tracepoint_get_internal_filter_bytecode( const struct lttng_event_rule *rule) { @@ -471,19 +474,22 @@ lttng_event_rule_tracepoint_get_internal_filter_bytecode( return tracepoint->internal_filter.bytecode; } -static struct lttng_event_exclusion * +static enum lttng_event_rule_generate_exclusions_status lttng_event_rule_tracepoint_generate_exclusions( - const struct lttng_event_rule *rule) + const struct lttng_event_rule *rule, + struct lttng_event_exclusion **_exclusions) { - enum lttng_domain_type domain_type = LTTNG_DOMAIN_NONE; - enum lttng_event_rule_status status; - struct lttng_event_exclusion *local_exclusions = NULL; - struct lttng_event_exclusion *ret_exclusions = NULL; - unsigned int nb_exclusions = 0; - unsigned int i; + unsigned int nb_exclusions = 0, i; + enum lttng_domain_type domain_type; + struct lttng_event_exclusion *exclusions; + enum lttng_event_rule_status event_rule_status; + enum lttng_event_rule_generate_exclusions_status ret_status; - status = lttng_event_rule_tracepoint_get_domain_type(rule, &domain_type); - assert(status == LTTNG_EVENT_RULE_STATUS_OK); + assert(_exclusions); + + event_rule_status = lttng_event_rule_tracepoint_get_domain_type( + rule, &domain_type); + assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK); switch (domain_type) { case LTTNG_DOMAIN_KERNEL: @@ -491,50 +497,60 @@ lttng_event_rule_tracepoint_generate_exclusions( case LTTNG_DOMAIN_LOG4J: case LTTNG_DOMAIN_PYTHON: /* Not supported. */ - ret_exclusions = NULL; + exclusions = NULL; + ret_status = LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE; goto end; case LTTNG_DOMAIN_UST: /* Exclusions supported. */ break; default: + /* Unknown domain. */ abort(); } - status = lttng_event_rule_tracepoint_get_exclusions_count( + event_rule_status = lttng_event_rule_tracepoint_get_exclusions_count( rule, &nb_exclusions); - assert(status == LTTNG_EVENT_RULE_STATUS_OK); + assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK); if (nb_exclusions == 0) { /* Nothing to do. */ - ret_exclusions = NULL; + exclusions = NULL; + ret_status = LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_NONE; goto end; } - local_exclusions = zmalloc(sizeof(struct lttng_event_exclusion) + - (LTTNG_SYMBOL_NAME_LEN * nb_exclusions)); - if (!local_exclusions) { + exclusions = zmalloc(sizeof(struct lttng_event_exclusion) + + (LTTNG_SYMBOL_NAME_LEN * nb_exclusions)); + if (!exclusions) { PERROR("Failed to allocate exclusions buffer"); - ret_exclusions = NULL; + ret_status = LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_OUT_OF_MEMORY; goto end; } - local_exclusions->count = nb_exclusions; + exclusions->count = nb_exclusions; for (i = 0; i < nb_exclusions; i++) { - /* Truncation is already checked at the setter level. */ - const char *tmp; - - status = lttng_event_rule_tracepoint_get_exclusion_at_index( - rule, i, &tmp); - assert(status == LTTNG_EVENT_RULE_STATUS_OK); - strncpy(local_exclusions->names[i], tmp, LTTNG_SYMBOL_NAME_LEN); - local_exclusions->names[i][LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + int copy_ret; + const char *exclusion_str; + + event_rule_status = + lttng_event_rule_tracepoint_get_exclusion_at_index( + rule, i, &exclusion_str); + assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK); + + copy_ret = lttng_strncpy(exclusions->names[i], exclusion_str, + LTTNG_SYMBOL_NAME_LEN); + if (copy_ret) { + free(exclusions); + exclusions = NULL; + ret_status = LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_ERROR; + goto end; + } } - /* Pass ownership. */ - ret_exclusions = local_exclusions; - local_exclusions = NULL; + ret_status = LTTNG_EVENT_RULE_GENERATE_EXCLUSIONS_STATUS_OK; + end: - free(local_exclusions); - return ret_exclusions; + *_exclusions = exclusions; + return ret_status; } static void destroy_lttng_exclusions_element(void *ptr) @@ -542,11 +558,89 @@ static void destroy_lttng_exclusions_element(void *ptr) free(ptr); } +static unsigned long lttng_event_rule_tracepoint_hash( + const struct lttng_event_rule *rule) +{ + unsigned long hash; + unsigned int i, exclusion_count; + enum lttng_event_rule_status status; + struct lttng_event_rule_tracepoint *tp_rule = + container_of(rule, typeof(*tp_rule), parent); + + hash = hash_key_ulong((void *) LTTNG_EVENT_RULE_TYPE_TRACEPOINT, + lttng_ht_seed); + hash ^= hash_key_ulong((void *) tp_rule->domain, lttng_ht_seed); + hash ^= hash_key_str(tp_rule->pattern, lttng_ht_seed); + + if (tp_rule->filter_expression) { + hash ^= hash_key_str(tp_rule->filter_expression, lttng_ht_seed); + } + + hash ^= hash_key_ulong((void *) tp_rule->loglevel.type, + lttng_ht_seed); + if (tp_rule->loglevel.type != LTTNG_EVENT_LOGLEVEL_ALL) { + hash ^= hash_key_ulong( + (void *) (unsigned long) tp_rule->loglevel.value, + lttng_ht_seed); + } + + status = lttng_event_rule_tracepoint_get_exclusions_count(rule, + &exclusion_count); + assert(status == LTTNG_EVENT_RULE_STATUS_OK); + + for (i = 0; i < exclusion_count; i++) { + const char *exclusion; + + status = lttng_event_rule_tracepoint_get_exclusion_at_index( + rule, i, &exclusion); + assert(status == LTTNG_EVENT_RULE_STATUS_OK); + hash ^= hash_key_str(exclusion, lttng_ht_seed); + } + + return hash; +} + +static struct lttng_event *lttng_event_rule_tracepoint_generate_lttng_event( + const struct lttng_event_rule *rule) +{ + int ret; + const struct lttng_event_rule_tracepoint *tracepoint; + struct lttng_event *local_event = NULL; + struct lttng_event *event = NULL; + + tracepoint = container_of( + rule, const struct lttng_event_rule_tracepoint, parent); + + local_event = zmalloc(sizeof(*local_event)); + if (!local_event) { + goto error; + } + + local_event->type = LTTNG_EVENT_TRACEPOINT; + ret = lttng_strncpy(local_event->name, tracepoint->pattern, + sizeof(local_event->name)); + if (ret) { + ERR("Truncation occurred when copying event rule pattern to `lttng_event` structure: pattern = '%s'", + tracepoint->pattern); + goto error; + } + + local_event->loglevel_type = tracepoint->loglevel.type; + local_event->loglevel = tracepoint->loglevel.value; + + event = local_event; + local_event = NULL; +error: + free(local_event); + return event; +} + struct lttng_event_rule *lttng_event_rule_tracepoint_create( enum lttng_domain_type domain_type) { struct lttng_event_rule *rule = NULL; struct lttng_event_rule_tracepoint *tp_rule; + enum lttng_event_rule_status status; if (domain_type == LTTNG_DOMAIN_NONE) { goto end; @@ -571,12 +665,23 @@ struct lttng_event_rule *lttng_event_rule_tracepoint_create( lttng_event_rule_tracepoint_get_internal_filter_bytecode; tp_rule->parent.generate_exclusions = lttng_event_rule_tracepoint_generate_exclusions; + tp_rule->parent.hash = lttng_event_rule_tracepoint_hash; + tp_rule->parent.generate_lttng_event = + lttng_event_rule_tracepoint_generate_lttng_event; tp_rule->domain = domain_type; tp_rule->loglevel.type = LTTNG_EVENT_LOGLEVEL_ALL; lttng_dynamic_pointer_array_init(&tp_rule->exclusions, destroy_lttng_exclusions_element); + + /* Default pattern is '*'. */ + status = lttng_event_rule_tracepoint_set_pattern(rule, "*"); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + lttng_event_rule_destroy(rule); + rule = NULL; + } + end: return rule; }