X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng-sessiond%2Fcontext.c;h=e29cc09a5379bd0ea59dacc783790483b5984d12;hp=c7c902197df34fa54143bec06dd437f8db5bf017;hb=7bd3904781fa78155c13952f5d5cb9ab42f44a08;hpb=e0b03593613331103ad4c15a95f5495a31289225 diff --git a/lttng-sessiond/context.c b/lttng-sessiond/context.c index c7c902197..e29cc09a5 100644 --- a/lttng-sessiond/context.c +++ b/lttng-sessiond/context.c @@ -22,12 +22,14 @@ #include #include +#include #include #include #include "context.h" -#include "hashtable.h" #include "kernel.h" +#include "ust-app.h" +#include "trace-ust.h" /* * Add kernel context to an event of a specific channel. @@ -150,235 +152,233 @@ error: } /* - * Add kernel context to tracer. + * Add UST context to channel. */ -int context_kernel_add(struct ltt_kernel_session *ksession, - struct lttng_event_context *ctx, char *event_name, - char *channel_name) +static int add_uctx_to_channel(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan, struct lttng_event_context *ctx) { int ret; - struct ltt_kernel_channel *kchan; - struct lttng_kernel_context kctx; + struct ltt_ust_context *uctx; - /* Setup kernel context structure */ - kctx.ctx = ctx->ctx; - kctx.u.perf_counter.type = ctx->u.perf_counter.type; - kctx.u.perf_counter.config = ctx->u.perf_counter.config; - strncpy(kctx.u.perf_counter.name, ctx->u.perf_counter.name, - LTTNG_SYMBOL_NAME_LEN); - kctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; - - if (strlen(channel_name) == 0) { - ret = add_kctx_all_channels(ksession, &kctx, event_name); - if (ret != LTTCOMM_OK) { - goto error; - } - } else { - /* Get kernel channel */ - kchan = trace_kernel_get_channel_by_name(channel_name, ksession); - if (kchan == NULL) { - ret = LTTCOMM_KERN_CHAN_NOT_FOUND; - goto error; - } + /* Create ltt UST context */ + uctx = trace_ust_create_context(ctx); + if (uctx == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } - ret = add_kctx_to_channel(&kctx, kchan, event_name); - if (ret != LTTCOMM_OK) { + switch (domain) { + case LTTNG_DOMAIN_UST: + ret = ust_app_add_ctx_channel_glb(usess, uchan, uctx); + if (ret < 0) { goto error; } + break; + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - ret = LTTCOMM_OK; + /* Add ltt UST context node to ltt UST channel */ + lttng_ht_add_unique_ulong(uchan->ctx, &uctx->node); + + return LTTCOMM_OK; error: + free(uctx); return ret; } /* - * UST support. - */ - -/* - * Add UST context to an event of a specific channel. + * Add UST context to event. */ -#ifdef DISABLE -static int add_ustctx_to_event(struct ltt_ust_session *ustsession, - struct lttng_ust_context *ustctx, - struct ltt_ust_channel *ustchan, char *event_name) +static int add_uctx_to_event(struct ltt_ust_session *usess, int domain, + struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, + struct lttng_event_context *ctx) { - int ret, found = 0; - struct ltt_ust_event *ustevent; - struct object_data *context_data; /* FIXME: currently a memleak */ + int ret; + struct ltt_ust_context *uctx; - DBG("Add UST context to event %s", event_name); + /* Create ltt UST context */ + uctx = trace_ust_create_context(ctx); + if (uctx == NULL) { + ret = LTTCOMM_FATAL; + goto error; + } - ustevent = trace_ust_find_event_by_name(ustchan->events, event_name); - if (ustevent != NULL) { - ret = ustctl_add_context(ustsession->sock, ustctx, - ustevent->obj, &context_data); + switch (domain) { + case LTTNG_DOMAIN_UST: + ret = ust_app_add_ctx_event_glb(usess, uchan, uevent, uctx); if (ret < 0) { goto error; } - found = 1; - } - - ret = found; - -error: - return ret; -} -#endif - -/* - * Add UST context to all channel. - * - * If event_name is specified, add context to event instead. - */ -static int add_ustctx_all_channels(struct ltt_ust_session *ustsession, - struct lttng_ust_context *ustctx, char *event_name, - struct cds_lfht *channels) -{ -#ifdef DISABLE - int ret, no_event = 0, found = 0; - struct ltt_ust_channel *ustchan; - struct object_data *context_data; /* FIXME: currently a memleak */ - - if (strlen(event_name) == 0) { - no_event = 1; + break; + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - DBG("Adding ust context to all channels (event: %s)", event_name); + /* Add ltt UST context node to ltt UST event */ + lttng_ht_add_unique_ulong(uevent->ctx, &uctx->node); - struct cds_lfht_node *node; - struct cds_lfht_iter iter; + return LTTCOMM_OK; - rcu_read_lock(); - hashtable_get_first(channels, &iter); - while ((node = hashtable_iter_get_node(&iter)) != NULL) { - ustchan = caa_container_of(node, struct ltt_ust_channel, node); - if (no_event) { - //ret = ustctl_add_context(ustsession->sock, - // ustctx, ustchan->obj, &context_data); - if (ret < 0) { - ret = LTTCOMM_UST_CONTEXT_FAIL; - goto error; - } - } else { - ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name); - if (ret < 0) { - ret = LTTCOMM_UST_CONTEXT_FAIL; - goto error; - } else if (ret == 1) { - /* Event found and context added */ - found = 1; - break; - } - } - hashtable_get_next(channels, &iter); - } - if (!found && !no_event) { - ret = LTTCOMM_NO_EVENT; - goto error; - } - ret = LTTCOMM_OK; error: - rcu_read_unlock(); + free(uctx); return ret; -#endif - return 0; } /* - * Add UST context to a specific channel. - * - * If event_name is specified, add context to that event. + * Add kernel context to tracer. */ -static int add_ustctx_to_channel(struct ltt_ust_session *ustsession, - struct lttng_ust_context *ustctx, - struct ltt_ust_channel *ustchan, char *event_name) +int context_kernel_add(struct ltt_kernel_session *ksession, + struct lttng_event_context *ctx, char *event_name, + char *channel_name) { -#ifdef DISABLE - int ret, no_event = 0, found = 0; - struct object_data *context_data; /* FIXME: currently a memleak */ - - if (strlen(event_name) == 0) { - no_event = 1; - } + int ret; + struct ltt_kernel_channel *kchan; + struct lttng_kernel_context kctx; - DBG("Add UST context to channel '%s', event '%s'", - ustchan->name, event_name); + /* Setup kernel context structure */ + kctx.ctx = ctx->ctx; + kctx.u.perf_counter.type = ctx->u.perf_counter.type; + kctx.u.perf_counter.config = ctx->u.perf_counter.config; + strncpy(kctx.u.perf_counter.name, ctx->u.perf_counter.name, + LTTNG_SYMBOL_NAME_LEN); + kctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; - if (no_event) { - //ret = ustctl_add_context(ustsession->sock, ustctx, - // ustchan->obj, &context_data); - if (ret < 0) { - ret = LTTCOMM_UST_CONTEXT_FAIL; + if (strlen(channel_name) == 0) { + ret = add_kctx_all_channels(ksession, &kctx, event_name); + if (ret != LTTCOMM_OK) { goto error; } } else { - ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name); - if (ret < 0) { - ret = LTTCOMM_UST_CONTEXT_FAIL; + /* Get kernel channel */ + kchan = trace_kernel_get_channel_by_name(channel_name, ksession); + if (kchan == NULL) { + ret = LTTCOMM_KERN_CHAN_NOT_FOUND; goto error; - } else if (ret == 1) { - /* Event found and context added */ - found = 1; } - } - if (!found && !no_event) { - ret = LTTCOMM_NO_EVENT; - goto error; + ret = add_kctx_to_channel(&kctx, kchan, event_name); + if (ret != LTTCOMM_OK) { + goto error; + } } ret = LTTCOMM_OK; error: return ret; -#endif - return 0; } /* * Add UST context to tracer. */ -int context_ust_add(struct ltt_ust_session *ustsession, +int context_ust_add(struct ltt_ust_session *usess, int domain, struct lttng_event_context *ctx, char *event_name, - char *channel_name, int domain) + char *channel_name) { - int ret; - struct cds_lfht *chan_ht = NULL; - struct ltt_ust_channel *ustchan; - struct lttng_ust_context ustctx; - - /* Setup UST context structure */ - ustctx.ctx = ctx->ctx; - + int ret = LTTCOMM_OK, have_event = 0; + struct lttng_ht_iter iter, uiter; + struct lttng_ht *chan_ht; + struct ltt_ust_channel *uchan = NULL; + struct ltt_ust_event *uevent = NULL; + + /* + * Define which channel's hashtable to use from the domain or quit if + * unknown domain. + */ switch (domain) { - case LTTNG_DOMAIN_UST: - chan_ht = ustsession->domain_global.channels; - break; + case LTTNG_DOMAIN_UST: + chan_ht = usess->domain_global.channels; + break; + case LTTNG_DOMAIN_UST_EXEC_NAME: + case LTTNG_DOMAIN_UST_PID: + case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: + default: + ret = LTTCOMM_NOT_IMPLEMENTED; + goto error; } - if (strlen(channel_name) == 0) { - ret = add_ustctx_all_channels(ustsession, &ustctx, event_name, chan_ht); - if (ret != LTTCOMM_OK) { - goto error; - } - } else { - /* Get UST channel */ - ustchan = trace_ust_find_channel_by_name(chan_ht, channel_name); - if (ustchan == NULL) { + /* Do we have an event name */ + if (strlen(event_name) != 0) { + have_event = 1; + } + + /* Get UST channel if defined */ + if (strlen(channel_name) != 0) { + uchan = trace_ust_find_channel_by_name(chan_ht, channel_name); + if (uchan == NULL) { ret = LTTCOMM_UST_CHAN_NOT_FOUND; goto error; } + } - ret = add_ustctx_to_channel(ustsession, &ustctx, ustchan, event_name); - if (ret != LTTCOMM_OK) { + /* If UST channel specified and event name, get UST event ref */ + if (uchan && have_event) { + uevent = trace_ust_find_event_by_name(uchan->events, event_name); + if (uevent == NULL) { + ret = LTTCOMM_UST_EVENT_NOT_FOUND; goto error; } } - ret = LTTCOMM_OK; + /* At this point, we have 4 possibilities */ + + if (uchan && uevent) { /* Add ctx to event in channel */ + ret = add_uctx_to_event(usess, domain, uchan, uevent, ctx); + } else if (uchan && !have_event) { /* Add ctx to channel */ + ret = add_uctx_to_channel(usess, domain, uchan, ctx); + } else if (!uchan && have_event) { /* Add ctx to event */ + /* Add context to event without having the channel name */ + cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) { + uevent = trace_ust_find_event_by_name(uchan->events, event_name); + if (uevent != NULL) { + ret = add_uctx_to_event(usess, domain, uchan, uevent, ctx); + /* + * LTTng UST does not allowed the same event to be registered + * multiple time in different or the same channel. So, if we + * found our event, we stop. + */ + goto end; + } + } + ret = LTTCOMM_UST_EVENT_NOT_FOUND; + goto error; + } else if (!uchan && !have_event) { /* Add ctx all events, all channels */ + /* For all channels */ + cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) { + ret = add_uctx_to_channel(usess, domain, uchan, ctx); + if (ret < 0) { + ERR("Context added to channel %s failed", uchan->name); + continue; + } + + /* For all events in channel */ + cds_lfht_for_each_entry(uchan->events->ht, &uiter.iter, uevent, + node.node) { + ret = add_uctx_to_event(usess, domain, uchan, uevent, ctx); + if (ret < 0) { + ERR("Context add to event %s in channel %s failed", + uevent->attr.name, uchan->name); + continue; + } + } + } + } + +end: + switch (ret) { + case -EEXIST: + ret = LTTCOMM_UST_CONTEXT_EXIST; + goto error; + case -ENOMEM: + ret = LTTCOMM_FATAL; + goto error; + } + + return LTTCOMM_OK; error: return ret;