X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftrace-ust.c;h=55ca4fb3c9bfe5fc6b142cc9a5aa51dda4e117c3;hp=b7ef806af1a5a218cdfa7ccc2f1b4c6e04691f98;hb=e9404c27e7cc9d841785e6c4292c1add19fbc1cc;hpb=b953b8cd56dbdc30e9228a7334c6e5fbe302cfc7 diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index b7ef806af..55ca4fb3c 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 - David Goulet + * Copyright (C) 2016 - Jérémie Galarneau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2 only, @@ -15,7 +16,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #define _LGPL_SOURCE #include #include @@ -72,6 +72,7 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) struct ltt_ust_event *event; const struct ltt_ust_ht_key *key; int ev_loglevel_value; + int ll_match; assert(node); assert(_key); @@ -88,19 +89,11 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) } /* Event loglevel value and type. */ - if (event->attr.loglevel_type == key->loglevel_type) { - /* Same loglevel type. */ - if (key->loglevel_type != LTTNG_UST_LOGLEVEL_ALL) { - /* - * Loglevel value must also match since the loglevel - * type is not all. - */ - if (ev_loglevel_value != key->loglevel_value) { - goto no_match; - } - } - } else { - /* Loglevel type is different: no match. */ + ll_match = loglevels_match(event->attr.loglevel_type, + ev_loglevel_value, key->loglevel_type, + key->loglevel_value, LTTNG_UST_LOGLEVEL_ALL); + + if (!ll_match) { goto no_match; } @@ -124,12 +117,46 @@ int trace_ust_ht_match_event(struct cds_lfht_node *node, const void *_key) } if (key->exclusion && event->exclusion) { - /* Both exclusions exist; check count followed by names. */ - if (event->exclusion->count != key->exclusion->count || - memcmp(event->exclusion->names, key->exclusion->names, - event->exclusion->count * LTTNG_SYMBOL_NAME_LEN) != 0) { + size_t i; + + /* Check exclusion counts first. */ + if (event->exclusion->count != key->exclusion->count) { goto no_match; } + + /* Compare names individually. */ + for (i = 0; i < event->exclusion->count; ++i) { + size_t j; + bool found = false; + const char *name_ev = + LTTNG_EVENT_EXCLUSION_NAME_AT( + event->exclusion, i); + + /* + * Compare this exclusion name to all the key's + * exclusion names. + */ + for (j = 0; j < key->exclusion->count; ++j) { + const char *name_key = + LTTNG_EVENT_EXCLUSION_NAME_AT( + key->exclusion, j); + + if (!strncmp(name_ev, name_key, + LTTNG_SYMBOL_NAME_LEN)) { + /* Names match! */ + found = true; + break; + } + } + + /* + * If the current exclusion name was not found amongst + * the key's exclusion names, then there's no match. + */ + if (!found) { + goto no_match; + } + } } /* Match. */ return 1; @@ -329,6 +356,8 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan, luc->attr.switch_timer_interval = chan->attr.switch_timer_interval; luc->attr.read_timer_interval = chan->attr.read_timer_interval; luc->attr.output = (enum lttng_ust_output) chan->attr.output; + luc->monitor_timer_interval = + ((struct lttng_channel_extended *) chan->attr.extended.ptr)->monitor_timer_interval; /* Translate to UST output enum */ switch (luc->attr.output) { @@ -367,6 +396,39 @@ error: return luc; } +/* + * Validates an exclusion list. + * + * Returns 0 if valid, negative value if invalid. + */ +static int validate_exclusion(struct lttng_event_exclusion *exclusion) +{ + size_t i; + int ret = 0; + + assert(exclusion); + + for (i = 0; i < exclusion->count; ++i) { + size_t j; + const char *name_a = + LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, i); + + for (j = 0; j < i; ++j) { + const char *name_b = + LTTNG_EVENT_EXCLUSION_NAME_AT(exclusion, j); + + if (!strncmp(name_a, name_b, LTTNG_SYMBOL_NAME_LEN)) { + /* Match! */ + ret = -1; + goto end; + } + } + } + +end: + return ret; +} + /* * Allocate and initialize a ust event. Set name and event type. * We own filter_expression, filter, and exclusion. @@ -383,6 +445,10 @@ struct ltt_ust_event *trace_ust_create_event(struct lttng_event *ev, assert(ev); + if (exclusion && validate_exclusion(exclusion)) { + goto error; + } + lue = zmalloc(sizeof(struct ltt_ust_event)); if (lue == NULL) { PERROR("ust event zmalloc"); @@ -455,7 +521,8 @@ error: } static -int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type) +int trace_ust_context_type_event_to_ust( + enum lttng_event_context_type type) { int utype; @@ -483,8 +550,10 @@ int trace_ust_context_type_event_to_ust(enum lttng_event_context_type type) utype = LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER; } break; + case LTTNG_EVENT_CONTEXT_APP_CONTEXT: + utype = LTTNG_UST_CONTEXT_APP_CONTEXT; + break; default: - ERR("Invalid UST context"); utype = -1; break; } @@ -522,6 +591,15 @@ int trace_ust_match_context(struct ltt_ust_context *uctx, return 0; } break; + case LTTNG_UST_CONTEXT_APP_CONTEXT: + assert(uctx->ctx.u.app_ctx.provider_name); + assert(uctx->ctx.u.app_ctx.ctx_name); + if (strcmp(uctx->ctx.u.app_ctx.provider_name, + ctx->u.app_ctx.provider_name) || + strcmp(uctx->ctx.u.app_ctx.ctx_name, + ctx->u.app_ctx.ctx_name)) { + return 0; + } default: break; @@ -537,20 +615,21 @@ int trace_ust_match_context(struct ltt_ust_context *uctx, struct ltt_ust_context *trace_ust_create_context( struct lttng_event_context *ctx) { - struct ltt_ust_context *uctx; + struct ltt_ust_context *uctx = NULL; int utype; assert(ctx); utype = trace_ust_context_type_event_to_ust(ctx->ctx); if (utype < 0) { - return NULL; + ERR("Invalid UST context"); + goto end; } uctx = zmalloc(sizeof(struct ltt_ust_context)); - if (uctx == NULL) { + if (!uctx) { PERROR("zmalloc ltt_ust_context"); - goto error; + goto end; } uctx->ctx.ctx = (enum lttng_ust_context_type) utype; @@ -562,14 +641,31 @@ struct ltt_ust_context *trace_ust_create_context( LTTNG_UST_SYM_NAME_LEN); uctx->ctx.u.perf_counter.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; break; + case LTTNG_UST_CONTEXT_APP_CONTEXT: + { + char *provider_name = NULL, *ctx_name = NULL; + + provider_name = strdup(ctx->u.app_ctx.provider_name); + if (!provider_name) { + goto error; + } + uctx->ctx.u.app_ctx.provider_name = provider_name; + + ctx_name = strdup(ctx->u.app_ctx.ctx_name); + if (!ctx_name) { + goto error; + } + uctx->ctx.u.app_ctx.ctx_name = ctx_name; + break; + } default: break; } lttng_ht_node_init_ulong(&uctx->node, (unsigned long) uctx->ctx.ctx); - +end: return uctx; - error: + trace_ust_destroy_context(uctx); return NULL; } @@ -868,7 +964,7 @@ static void destroy_context_rcu(struct rcu_head *head) struct ltt_ust_context *ctx = caa_container_of(node, struct ltt_ust_context, node); - free(ctx); + trace_ust_destroy_context(ctx); } /* @@ -913,6 +1009,20 @@ void trace_ust_destroy_event(struct ltt_ust_event *event) free(event); } +/* + * Cleanup ust context structure. + */ +void trace_ust_destroy_context(struct ltt_ust_context *ctx) +{ + assert(ctx); + + if (ctx->ctx.ctx == LTTNG_UST_CONTEXT_APP_CONTEXT) { + free(ctx->ctx.u.app_ctx.provider_name); + free(ctx->ctx.u.app_ctx.ctx_name); + } + free(ctx); +} + /* * URCU intermediate call to complete destroy event. */