From 2001793c1141e89b34e70efb28b27ec0cc8e6d47 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 26 Jan 2016 11:42:45 -0500 Subject: [PATCH] Add application context support to lttng-ctl lttng_add_context MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Forward the provider and context names of app contexts to the session daemon. Signed-off-by: Jérémie Galarneau --- include/lttng/event.h | 34 +++++++----- src/bin/lttng-sessiond/main.c | 69 +++++++++++++++++++++++- src/common/sessiond-comm/sessiond-comm.h | 2 + src/lib/lttng-ctl/lttng-ctl.c | 55 ++++++++++++++++--- 4 files changed, 138 insertions(+), 22 deletions(-) diff --git a/include/lttng/event.h b/include/lttng/event.h index 3e8fbe3e8..e5b2b4bb0 100644 --- a/include/lttng/event.h +++ b/include/lttng/event.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 - David Goulet + * Copyright (C) 2016 - Jérémie Galarneau * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, version 2.1 only, @@ -121,21 +122,22 @@ enum lttng_event_output { /* Event context possible type */ enum lttng_event_context_type { - LTTNG_EVENT_CONTEXT_PID = 0, - LTTNG_EVENT_CONTEXT_PERF_COUNTER = 1, /* Backward compat. */ - LTTNG_EVENT_CONTEXT_PROCNAME = 2, - LTTNG_EVENT_CONTEXT_PRIO = 3, - LTTNG_EVENT_CONTEXT_NICE = 4, - LTTNG_EVENT_CONTEXT_VPID = 5, - LTTNG_EVENT_CONTEXT_TID = 6, - LTTNG_EVENT_CONTEXT_VTID = 7, - LTTNG_EVENT_CONTEXT_PPID = 8, - LTTNG_EVENT_CONTEXT_VPPID = 9, - LTTNG_EVENT_CONTEXT_PTHREAD_ID = 10, - LTTNG_EVENT_CONTEXT_HOSTNAME = 11, - LTTNG_EVENT_CONTEXT_IP = 12, - LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER = 13, + LTTNG_EVENT_CONTEXT_PID = 0, + LTTNG_EVENT_CONTEXT_PERF_COUNTER = 1, /* Backward compat. */ + LTTNG_EVENT_CONTEXT_PROCNAME = 2, + LTTNG_EVENT_CONTEXT_PRIO = 3, + LTTNG_EVENT_CONTEXT_NICE = 4, + LTTNG_EVENT_CONTEXT_VPID = 5, + LTTNG_EVENT_CONTEXT_TID = 6, + LTTNG_EVENT_CONTEXT_VTID = 7, + LTTNG_EVENT_CONTEXT_PPID = 8, + LTTNG_EVENT_CONTEXT_VPPID = 9, + LTTNG_EVENT_CONTEXT_PTHREAD_ID = 10, + LTTNG_EVENT_CONTEXT_HOSTNAME = 11, + LTTNG_EVENT_CONTEXT_IP = 12, + LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER = 13, LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER = 14, + LTTNG_EVENT_CONTEXT_APP_CONTEXT = 15, }; enum lttng_event_field_type { @@ -178,6 +180,10 @@ struct lttng_event_context { union { struct lttng_event_perf_counter_ctx perf_counter; + struct { + char *provider_name; + char *ctx_name; + } app_ctx; char padding[LTTNG_EVENT_CONTEXT_PADDING2]; } u; }; diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index c1f466ed7..7a8b5ae42 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -3343,9 +3343,74 @@ skip_domain: switch (cmd_ctx->lsm->cmd_type) { case LTTNG_ADD_CONTEXT: { - ret = cmd_add_context(cmd_ctx->session, cmd_ctx->lsm->domain.type, + /* + * An LTTNG_ADD_CONTEXT command might have a supplementary + * payload if the context being added is an application context. + */ + if (cmd_ctx->lsm->u.context.ctx.ctx == + LTTNG_EVENT_CONTEXT_APP_CONTEXT) { + char *provider_name = NULL, *context_name = NULL; + size_t provider_name_len = + cmd_ctx->lsm->u.context.provider_name_len; + size_t context_name_len = + cmd_ctx->lsm->u.context.context_name_len; + + if (provider_name_len == 0 || context_name_len == 0) { + /* + * Application provider and context names MUST + * be provided. + */ + ret = -LTTNG_ERR_INVALID; + goto error; + } + + provider_name = zmalloc(provider_name_len + 1); + if (!provider_name) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + + context_name = zmalloc(context_name_len + 1); + if (!context_name) { + ret = -LTTNG_ERR_NOMEM; + goto error_add_context; + } + + ret = lttcomm_recv_unix_sock(sock, provider_name, + provider_name_len); + if (ret < 0) { + goto error_add_context; + } + + ret = lttcomm_recv_unix_sock(sock, context_name, + context_name_len); + if (ret < 0) { + goto error_add_context; + } + cmd_ctx->lsm->u.context.ctx.u.app_ctx.provider_name = + provider_name; + cmd_ctx->lsm->u.context.ctx.u.app_ctx.ctx_name = + context_name; + } + + /* + * cmd_add_context assumes ownership of the provider and context + * names. + */ + ret = cmd_add_context(cmd_ctx->session, + cmd_ctx->lsm->domain.type, cmd_ctx->lsm->u.context.channel_name, - &cmd_ctx->lsm->u.context.ctx, kernel_poll_pipe[1]); + &cmd_ctx->lsm->u.context.ctx, + kernel_poll_pipe[1]); + + cmd_ctx->lsm->u.context.ctx.u.app_ctx.provider_name = NULL; + cmd_ctx->lsm->u.context.ctx.u.app_ctx.ctx_name = NULL; +error_add_context: + free(cmd_ctx->lsm->u.context.ctx.u.app_ctx.provider_name); + free(cmd_ctx->lsm->u.context.ctx.u.app_ctx.ctx_name); + if (ret < 0) { + goto error; + } break; } case LTTNG_DISABLE_CHANNEL: diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 778618876..4a204c02e 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -270,6 +270,8 @@ struct lttcomm_session_msg { struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; struct lttng_event_context ctx LTTNG_PACKED; + uint32_t provider_name_len; + uint32_t context_name_len; } LTTNG_PACKED context; /* Use by register_consumer */ struct { diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 0dcd673eb..03b74c0b7 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -4,6 +4,7 @@ * Linux Trace Toolkit Control Library * * Copyright (C) 2011 David Goulet + * Copyright (C) 2016 - Jérémie Galarneau * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License, version 2.1 only, @@ -644,15 +645,18 @@ int lttng_add_context(struct lttng_handle *handle, struct lttng_event_context *ctx, const char *event_name, const char *channel_name) { + int ret; + size_t len = 0; + char *buf = NULL; struct lttcomm_session_msg lsm; /* Safety check. Both are mandatory. */ if (handle == NULL || ctx == NULL) { - return -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID; + goto end; } memset(&lsm, 0, sizeof(lsm)); - lsm.cmd_type = LTTNG_ADD_CONTEXT; /* If no channel name, send empty string. */ @@ -665,13 +669,52 @@ int lttng_add_context(struct lttng_handle *handle, } lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); - - memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context)); - lttng_ctl_copy_string(lsm.session.name, handle->session_name, sizeof(lsm.session.name)); - return lttng_ctl_ask_sessiond(&lsm, NULL); + if (ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT) { + size_t provider_len, ctx_len; + const char *provider_name = ctx->u.app_ctx.provider_name; + const char *ctx_name = ctx->u.app_ctx.ctx_name; + + if (!provider_name || !ctx_name) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + provider_len = strlen(provider_name); + if (provider_len == 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + lsm.u.context.provider_name_len = provider_len; + + ctx_len = strlen(ctx_name); + if (ctx_len == 0) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + lsm.u.context.context_name_len = ctx_len; + + len = provider_len + ctx_len; + buf = zmalloc(len); + if (!buf) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } + + memcpy(buf, provider_name, provider_len); + memcpy(buf + provider_len, ctx_name, ctx_len); + } + memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context)); + /* Don't leak application addresses to the sessiond. */ + lsm.u.context.ctx.u.app_ctx.provider_name = NULL; + lsm.u.context.ctx.u.app_ctx.ctx_name = NULL; + + ret = lttng_ctl_ask_sessiond_varlen(&lsm, buf, len, NULL); +end: + free(buf); + return ret; } /* -- 2.34.1