X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcontext.c;h=621c0b9fb53cfa88a56abc5b6737b52aee8eaa56;hp=a83cb46fc9dec796868dbb95157d901cb46cdb70;hb=d37ac3cdc4fe21f117edfb829db4d0eb7cf914a1;hpb=9d035200e9006c4d4cf6951c54641e06c0bdf2bc diff --git a/src/bin/lttng-sessiond/context.c b/src/bin/lttng-sessiond/context.c index a83cb46fc..621c0b9fb 100644 --- a/src/bin/lttng-sessiond/context.c +++ b/src/bin/lttng-sessiond/context.c @@ -1,21 +1,12 @@ /* - * Copyright (C) 2011 - David Goulet + * 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, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include @@ -29,12 +20,15 @@ #include "kernel.h" #include "ust-app.h" #include "trace-ust.h" +#include "agent.h" /* * Add kernel context to all channel. + * + * Assumes the ownership of kctx. */ static int add_kctx_all_channels(struct ltt_kernel_session *ksession, - struct lttng_kernel_context *kctx) + struct ltt_kernel_context *kctx) { int ret; struct ltt_kernel_channel *kchan; @@ -46,9 +40,19 @@ static int add_kctx_all_channels(struct ltt_kernel_session *ksession, /* Go over all channels */ cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) { - ret = kernel_add_channel_context(kchan, kctx); - if (ret < 0) { - ret = LTTNG_ERR_KERN_CONTEXT_FAIL; + struct ltt_kernel_context *kctx_copy; + + kctx_copy = trace_kernel_copy_context(kctx); + if (!kctx_copy) { + PERROR("zmalloc ltt_kernel_context"); + ret = -LTTNG_ERR_NOMEM; + goto error; + } + + /* Ownership of kctx_copy is transferred to the callee. */ + ret = kernel_add_channel_context(kchan, kctx_copy); + kctx_copy = NULL; + if (ret != 0) { goto error; } } @@ -56,13 +60,16 @@ static int add_kctx_all_channels(struct ltt_kernel_session *ksession, ret = LTTNG_OK; error: + trace_kernel_destroy_context(kctx); return ret; } /* * Add kernel context to a specific channel. + * + * Assumes the ownership of kctx. */ -static int add_kctx_to_channel(struct lttng_kernel_context *kctx, +static int add_kctx_to_channel(struct ltt_kernel_context *kctx, struct ltt_kernel_channel *kchan) { int ret; @@ -72,9 +79,10 @@ static int add_kctx_to_channel(struct lttng_kernel_context *kctx, DBG("Add kernel context to channel '%s'", kchan->channel->name); + /* Ownership of kctx is transferred to the callee. */ ret = kernel_add_channel_context(kchan, kctx); - if (ret < 0) { - ret = LTTNG_ERR_KERN_CONTEXT_FAIL; + kctx = NULL; + if (ret != 0) { goto error; } @@ -87,58 +95,91 @@ error: /* * Add UST context to channel. */ -static int add_uctx_to_channel(struct ltt_ust_session *usess, int domain, - struct ltt_ust_channel *uchan, struct lttng_event_context *ctx) +static int add_uctx_to_channel(struct ltt_ust_session *usess, + enum lttng_domain_type domain, + struct ltt_ust_channel *uchan, + const struct lttng_event_context *ctx) { int ret; - struct ltt_ust_context *uctx; - struct lttng_ht_iter iter; - struct lttng_ht_node_ulong *uctx_node; + struct ltt_ust_context *uctx = NULL; assert(usess); assert(uchan); assert(ctx); - /* Create ltt UST context */ - uctx = trace_ust_create_context(ctx); - if (uctx == NULL) { - ret = -EINVAL; - goto error; + /* Check if context is duplicate */ + cds_list_for_each_entry(uctx, &uchan->ctx_list, list) { + if (trace_ust_match_context(uctx, ctx)) { + ret = LTTNG_ERR_UST_CONTEXT_EXIST; + goto duplicate; + } } + uctx = NULL; switch (domain) { - case LTTNG_DOMAIN_UST: - ret = ust_app_add_ctx_channel_glb(usess, uchan, uctx); - if (ret < 0) { + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + { + struct agent *agt; + + if (ctx->ctx != LTTNG_EVENT_CONTEXT_APP_CONTEXT) { + /* Other contexts are not needed by the agent. */ + break; + } + agt = trace_ust_find_agent(usess, domain); + + if (!agt) { + agt = agent_create(domain); + if (!agt) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + agent_add(agt, usess->agents); + } + ret = agent_add_context(ctx, agt); + if (ret != LTTNG_OK) { goto error; } + + ret = agent_enable_context(ctx, domain); + if (ret != LTTNG_OK) { + goto error; + } + break; + } + case LTTNG_DOMAIN_UST: break; default: - ret = -ENOSYS; - goto error; + assert(0); } - rcu_read_lock(); - - /* Lookup context before adding it */ - lttng_ht_lookup(uchan->ctx, (void *)((unsigned long)uctx->ctx.ctx), &iter); - uctx_node = lttng_ht_iter_get_node_ulong(&iter); - if (uctx_node != NULL) { - ret = -EEXIST; - rcu_read_unlock(); + /* Create ltt UST context */ + uctx = trace_ust_create_context(ctx); + if (uctx == NULL) { + ret = LTTNG_ERR_UST_CONTEXT_INVAL; goto error; } /* Add ltt UST context node to ltt UST channel */ - lttng_ht_add_unique_ulong(uchan->ctx, &uctx->node); - rcu_read_unlock(); + lttng_ht_add_ulong(uchan->ctx, &uctx->node); + cds_list_add_tail(&uctx->list, &uchan->ctx_list); + + if (!usess->active) { + goto end; + } + ret = ust_app_add_ctx_channel_glb(usess, uchan, uctx); + if (ret < 0) { + goto error; + } +end: DBG("Context UST %d added to channel %s", uctx->ctx.ctx, uchan->name); return 0; error: free(uctx); +duplicate: return ret; } @@ -146,63 +187,151 @@ error: * Add kernel context to tracer. */ int context_kernel_add(struct ltt_kernel_session *ksession, - struct lttng_event_context *ctx, char *channel_name) + const struct lttng_event_context *ctx, char *channel_name) { int ret; struct ltt_kernel_channel *kchan; - struct lttng_kernel_context kctx; + struct ltt_kernel_context *kctx; assert(ksession); assert(ctx); assert(channel_name); + kctx = trace_kernel_create_context(NULL); + if (!kctx) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + /* Setup kernel context structure */ switch (ctx->ctx) { case LTTNG_EVENT_CONTEXT_PID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_PID; - break; - case LTTNG_EVENT_CONTEXT_PERF_COUNTER: - kctx.ctx = LTTNG_KERNEL_CONTEXT_PERF_COUNTER; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PID; break; case LTTNG_EVENT_CONTEXT_PROCNAME: - kctx.ctx = LTTNG_KERNEL_CONTEXT_PROCNAME; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PROCNAME; break; case LTTNG_EVENT_CONTEXT_PRIO: - kctx.ctx = LTTNG_KERNEL_CONTEXT_PRIO; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PRIO; break; case LTTNG_EVENT_CONTEXT_NICE: - kctx.ctx = LTTNG_KERNEL_CONTEXT_NICE; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_NICE; break; case LTTNG_EVENT_CONTEXT_VPID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_VPID; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VPID; break; case LTTNG_EVENT_CONTEXT_TID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_TID; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_TID; break; case LTTNG_EVENT_CONTEXT_VTID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_VTID; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VTID; break; case LTTNG_EVENT_CONTEXT_PPID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_PPID; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PPID; break; case LTTNG_EVENT_CONTEXT_VPPID: - kctx.ctx = LTTNG_KERNEL_CONTEXT_VPPID; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VPPID; break; case LTTNG_EVENT_CONTEXT_HOSTNAME: - kctx.ctx = LTTNG_KERNEL_CONTEXT_HOSTNAME; + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_HOSTNAME; + break; + case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER: + case LTTNG_EVENT_CONTEXT_PERF_COUNTER: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER; + break; + case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE; + break; + case LTTNG_EVENT_CONTEXT_PREEMPTIBLE: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PREEMPTIBLE; + break; + case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE; + break; + case LTTNG_EVENT_CONTEXT_MIGRATABLE: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_MIGRATABLE; + break; + case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL; + break; + case LTTNG_EVENT_CONTEXT_CALLSTACK_USER: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_CALLSTACK_USER; + break; + case LTTNG_EVENT_CONTEXT_CGROUP_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_CGROUP_NS; + break; + case LTTNG_EVENT_CONTEXT_IPC_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_IPC_NS; + break; + case LTTNG_EVENT_CONTEXT_MNT_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_MNT_NS; + break; + case LTTNG_EVENT_CONTEXT_NET_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_NET_NS; + break; + case LTTNG_EVENT_CONTEXT_PID_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_PID_NS; + break; + case LTTNG_EVENT_CONTEXT_TIME_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_TIME_NS; + break; + case LTTNG_EVENT_CONTEXT_USER_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_USER_NS; + break; + case LTTNG_EVENT_CONTEXT_UTS_NS: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_UTS_NS; + break; + case LTTNG_EVENT_CONTEXT_UID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_UID; + break; + case LTTNG_EVENT_CONTEXT_EUID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_EUID; + break; + case LTTNG_EVENT_CONTEXT_SUID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_SUID; + break; + case LTTNG_EVENT_CONTEXT_GID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_GID; + break; + case LTTNG_EVENT_CONTEXT_EGID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_EGID; + break; + case LTTNG_EVENT_CONTEXT_SGID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_SGID; + break; + case LTTNG_EVENT_CONTEXT_VUID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VUID; + break; + case LTTNG_EVENT_CONTEXT_VEUID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VEUID; + break; + case LTTNG_EVENT_CONTEXT_VSUID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VSUID; + break; + case LTTNG_EVENT_CONTEXT_VGID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VGID; + break; + case LTTNG_EVENT_CONTEXT_VEGID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VEGID; + break; + case LTTNG_EVENT_CONTEXT_VSGID: + kctx->ctx.ctx = LTTNG_KERNEL_CONTEXT_VSGID; break; default: - return LTTNG_ERR_KERN_CONTEXT_FAIL; + ret = LTTNG_ERR_KERN_CONTEXT_FAIL; + goto error; } - 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, + kctx->ctx.u.perf_counter.type = ctx->u.perf_counter.type; + kctx->ctx.u.perf_counter.config = ctx->u.perf_counter.config; + strncpy(kctx->ctx.u.perf_counter.name, ctx->u.perf_counter.name, LTTNG_SYMBOL_NAME_LEN); - kctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + kctx->ctx.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; if (*channel_name == '\0') { - ret = add_kctx_all_channels(ksession, &kctx); + ret = add_kctx_all_channels(ksession, kctx); + /* Ownership of kctx is transferred to the callee. */ + kctx = NULL; if (ret != LTTNG_OK) { goto error; } @@ -214,7 +343,9 @@ int context_kernel_add(struct ltt_kernel_session *ksession, goto error; } - ret = add_kctx_to_channel(&kctx, kchan); + ret = add_kctx_to_channel(kctx, kchan); + /* Ownership of kctx is transferred to the callee. */ + kctx = NULL; if (ret != LTTNG_OK) { goto error; } @@ -223,14 +354,19 @@ int context_kernel_add(struct ltt_kernel_session *ksession, ret = LTTNG_OK; error: + if (kctx) { + trace_kernel_destroy_context(kctx); + } return ret; } /* * Add UST context to tracer. */ -int context_ust_add(struct ltt_ust_session *usess, int domain, - struct lttng_event_context *ctx, char *channel_name) +int context_ust_add(struct ltt_ust_session *usess, + enum lttng_domain_type domain, + const struct lttng_event_context *ctx, + char *channel_name) { int ret = LTTNG_OK; struct lttng_ht_iter iter; @@ -243,26 +379,10 @@ int context_ust_add(struct ltt_ust_session *usess, int domain, rcu_read_lock(); - /* - * Define which channel's hashtable to use from the domain or quit if - * unknown domain. - */ - switch (domain) { - case LTTNG_DOMAIN_UST: - chan_ht = usess->domain_global.channels; - break; -#if 0 - case LTTNG_DOMAIN_UST_EXEC_NAME: - case LTTNG_DOMAIN_UST_PID: - case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: -#endif - default: - ret = LTTNG_ERR_UND; - goto error; - } + chan_ht = usess->domain_global.channels; /* Get UST channel if defined */ - if (channel_name != '\0') { + if (channel_name[0] != '\0') { uchan = trace_ust_find_channel_by_name(chan_ht, channel_name); if (uchan == NULL) { ret = LTTNG_ERR_UST_CHAN_NOT_FOUND; @@ -278,8 +398,9 @@ int context_ust_add(struct ltt_ust_session *usess, int domain, /* Add ctx all events, 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 failed for channel %s", uchan->name); + if (ret) { + ERR("Failed to add context to channel %s", + uchan->name); continue; } } @@ -287,10 +408,10 @@ int context_ust_add(struct ltt_ust_session *usess, int domain, } switch (ret) { - case -EEXIST: - ret = LTTNG_ERR_UST_CONTEXT_EXIST; + case LTTNG_ERR_UST_CONTEXT_EXIST: break; case -ENOMEM: + case -LTTNG_ERR_NOMEM: ret = LTTNG_ERR_FATAL; break; case -EINVAL: @@ -300,7 +421,11 @@ int context_ust_add(struct ltt_ust_session *usess, int domain, ret = LTTNG_ERR_UNKNOWN_DOMAIN; break; default: - ret = LTTNG_OK; + if (ret != 0 && ret != LTTNG_OK) { + ret = ret > 0 ? ret : LTTNG_ERR_UNK; + } else { + ret = LTTNG_OK; + } break; }