X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=11dde04abaea1f112dcd171e988ab922ed6d5537;hb=fa7fee60cac8659b3a980a6400939a5a24e0e61e;hp=f8e96936d172f45ae85ac5a2980f8d2020a95a80;hpb=f14256d650ba78aa23c87a1f35c0c66656cb9e06;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index f8e96936d..11dde04ab 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -1446,7 +1446,32 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess, } /* If event not enabled, disable it on the tracer */ - if (ua_event->enabled == 0) { + if (ua_event->enabled) { + /* + * We now need to explicitly enable the event, since it + * is now disabled at creation. + */ + ret = enable_ust_event(app, ua_sess, ua_event); + if (ret < 0) { + /* + * If we hit an EPERM, something is wrong with our enable call. If + * we get an EEXIST, there is a problem on the tracer side since we + * just created it. + */ + switch (ret) { + case -LTTNG_UST_ERR_PERM: + /* Code flow problem */ + assert(0); + case -LTTNG_UST_ERR_EXIST: + /* It's OK for our use case. */ + ret = 0; + break; + default: + break; + } + goto error; + } + } else { ret = disable_ust_event(app, ua_sess, ua_event); if (ret < 0) { /* @@ -1923,6 +1948,75 @@ error: return ret; } +/* + * Match function for a hash table lookup of ust_app_ctx. + * + * It matches an ust app context based on the context type and, in the case + * of perf counters, their name. + */ +static int ht_match_ust_app_ctx(struct cds_lfht_node *node, const void *_key) +{ + struct ust_app_ctx *ctx; + const struct lttng_ust_context *key; + + assert(node); + assert(_key); + + ctx = caa_container_of(node, struct ust_app_ctx, node.node); + key = _key; + + /* Context type */ + if (ctx->ctx.ctx != key->ctx) { + goto no_match; + } + + /* Check the name in the case of perf thread counters. */ + if (key->ctx == LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER) { + if (strncmp(key->u.perf_counter.name, + ctx->ctx.u.perf_counter.name, + sizeof(key->u.perf_counter.name))) { + goto no_match; + } + } + + /* Match. */ + return 1; + +no_match: + return 0; +} + +/* + * Lookup for an ust app context from an lttng_ust_context. + * + * Must be called while holding RCU read side lock. + * Return an ust_app_ctx object or NULL on error. + */ +static +struct ust_app_ctx *find_ust_app_context(struct lttng_ht *ht, + struct lttng_ust_context *uctx) +{ + struct lttng_ht_iter iter; + struct lttng_ht_node_ulong *node; + struct ust_app_ctx *app_ctx = NULL; + + assert(uctx); + assert(ht); + + /* Lookup using the lttng_ust_context_type and a custom match fct. */ + cds_lfht_lookup(ht->ht, ht->hash_fct((void *) uctx->ctx, lttng_ht_seed), + ht_match_ust_app_ctx, uctx, &iter.iter); + node = lttng_ht_iter_get_node_ulong(&iter); + if (!node) { + goto end; + } + + app_ctx = caa_container_of(node, struct ust_app_ctx, node); + +end: + return app_ctx; +} + /* * Create a context for the channel on the tracer. * @@ -1934,15 +2028,12 @@ int create_ust_app_channel_context(struct ust_app_session *ua_sess, struct ust_app *app) { int ret = 0; - struct lttng_ht_iter iter; - struct lttng_ht_node_ulong *node; struct ust_app_ctx *ua_ctx; DBG2("UST app adding context to channel %s", ua_chan->name); - lttng_ht_lookup(ua_chan->ctx, (void *)((unsigned long)uctx->ctx), &iter); - node = lttng_ht_iter_get_node_ulong(&iter); - if (node != NULL) { + ua_ctx = find_ust_app_context(ua_chan->ctx, uctx); + if (ua_ctx) { ret = -EEXIST; goto error; } @@ -5081,10 +5172,12 @@ unsigned int ust_app_get_nb_stream(struct ltt_ust_session *usess) cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { struct buffer_reg_channel *reg_chan; + rcu_read_lock(); cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, reg_chan, node.node) { ret += reg_chan->stream_count; } + rcu_read_unlock(); } break; }