X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Flttng-ctl.c;h=afa741c05b93554c00ec5dd70d90472123176a8b;hp=0dcd673ebaed084249afa638cd0dc00a9a52e2ca;hb=8d7f6956990e8d0e0f32a532321db44263c6903f;hpb=9ae110e2d5cf6618d4d58eb70f34fbd7029cf368 diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 0dcd673eb..afa741c05 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, @@ -149,7 +150,7 @@ end: * On success, returns the number of bytes sent (>=0) * On error, returns -1 */ -static int send_session_varlen(void *data, size_t len) +static int send_session_varlen(const void *data, size_t len) { int ret; @@ -399,7 +400,7 @@ static int disconnect_sessiond(void) */ LTTNG_HIDDEN int lttng_ctl_ask_sessiond_varlen(struct lttcomm_session_msg *lsm, - void *vardata, size_t varlen, void **buf) + const void *vardata, size_t varlen, void **buf) { int ret; size_t size; @@ -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; } /* @@ -1482,7 +1525,7 @@ int lttng_create_session(const char *name, const char *url) * Destroy session using name. * Returns size of returned session payload data or a negative error code. */ -int lttng_destroy_session(const char *session_name) +int _lttng_destroy_session(const char *session_name) { struct lttcomm_session_msg lsm; @@ -1499,6 +1542,48 @@ int lttng_destroy_session(const char *session_name) return lttng_ctl_ask_sessiond(&lsm, NULL); } +/* + * Stop the session and wait for the data before destroying it + */ +int lttng_destroy_session(const char *session_name) +{ + int ret; + + /* + * Stop the tracing and wait for the data. + */ + ret = _lttng_stop_tracing(session_name, 1); + if (ret && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) { + goto end; + } + + ret = _lttng_destroy_session(session_name); +end: + return ret; +} + +/* + * Destroy the session without waiting for the data. + */ +int lttng_destroy_session_no_wait(const char *session_name) +{ + int ret; + + /* + * Stop the tracing without waiting for the data. + * The session might already have been stopped, so just + * skip this error. + */ + ret = _lttng_stop_tracing(session_name, 0); + if (ret && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) { + goto end; + } + + ret = _lttng_destroy_session(session_name); +end: + return ret; +} + /* * Ask the session daemon for all available sessions. * Sets the contents of the sessions array.