#define _GNU_SOURCE
#include <string.h>
+#include <lttng/ust-config.h>
#include <lttng/ust-ctl.h>
#include <lttng/ust-abi.h>
#include <lttng/ust-events.h>
return 0;
}
-int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
+int ustctl_add_context(int sock, struct lttng_ust_context_attr *ctx,
struct lttng_ust_object_data *obj_data,
struct lttng_ust_object_data **_context_data)
{
struct ustcomm_ust_msg lum;
struct ustcomm_ust_reply lur;
- struct lttng_ust_object_data *context_data;
+ struct lttng_ust_object_data *context_data = NULL;
+ char *buf = NULL;
+ size_t len;
int ret;
- if (!obj_data || !_context_data)
- return -EINVAL;
+ if (!obj_data || !_context_data) {
+ ret = -EINVAL;
+ goto end;
+ }
context_data = zmalloc(sizeof(*context_data));
- if (!context_data)
- return -ENOMEM;
+ if (!context_data) {
+ ret = -ENOMEM;
+ goto end;
+ }
context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
memset(&lum, 0, sizeof(lum));
lum.handle = obj_data->handle;
lum.cmd = LTTNG_UST_CONTEXT;
- lum.u.context = *ctx;
- ret = ustcomm_send_app_cmd(sock, &lum, &lur);
- if (ret) {
- free(context_data);
- return ret;
+
+ lum.u.context.ctx = ctx->ctx;
+ switch (ctx->ctx) {
+ case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
+ lum.u.context.u.perf_counter = ctx->u.perf_counter;
+ break;
+ case LTTNG_UST_CONTEXT_APP_CONTEXT:
+ {
+ size_t provider_name_len = strlen(
+ ctx->u.app_ctx.provider_name) + 1;
+ size_t ctx_name_len = strlen(ctx->u.app_ctx.ctx_name) + 1;
+
+ lum.u.context.u.app_ctx.provider_name_len = provider_name_len;
+ lum.u.context.u.app_ctx.ctx_name_len = ctx_name_len;
+
+ len = provider_name_len + ctx_name_len;
+ buf = zmalloc(len);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto end;
+ }
+ memcpy(buf, ctx->u.app_ctx.provider_name,
+ provider_name_len);
+ memcpy(buf + provider_name_len, ctx->u.app_ctx.ctx_name,
+ ctx_name_len);
+ break;
+ }
+ default:
+ break;
+ }
+ ret = ustcomm_send_app_msg(sock, &lum);
+ if (ret)
+ goto end;
+ if (buf) {
+ /* send var len ctx_name */
+ ret = ustcomm_send_unix_sock(sock, buf, len);
+ if (ret < 0) {
+ goto end;
+ }
+ if (ret != len) {
+ ret = -EINVAL;
+ goto end;
+ }
+ }
+ ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+ if (ret < 0) {
+ goto end;
}
context_data->handle = -1;
DBG("Context created successfully");
*_context_data = context_data;
+ context_data = NULL;
+end:
+ free(context_data);
+ free(buf);
return ret;
}
chan->ops->packet_avail_size(chan->chan, chan->handle),
len - pos);
lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
- sizeof(char), -1, chan->handle);
+ sizeof(char), -1, chan->handle, NULL);
/*
* We don't care about metadata buffer's records lost
* count, because we always retry here. Report error if
chan->ops->packet_avail_size(chan->chan, chan->handle),
len);
lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
- sizeof(char), -1, chan->handle);
+ sizeof(char), -1, chan->handle, NULL);
ret = chan->ops->event_reserve(&ctx, 0);
if (ret != 0) {
DBG("LTTng: event reservation failed");
return client_cb->current_timestamp(buf, handle, ts);
}
-#if defined(__x86_64__) || defined(__i386__)
+int ustctl_get_sequence_number(struct ustctl_consumer_stream *stream,
+ uint64_t *seq)
+{
+ struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
+ struct lttng_ust_lib_ring_buffer *buf;
+ struct lttng_ust_shm_handle *handle;
+
+ if (!stream || !seq)
+ return -EINVAL;
+ buf = stream->buf;
+ handle = stream->chan->chan->handle;
+ client_cb = get_client_cb(buf, handle);
+ if (!client_cb || !client_cb->sequence_number)
+ return -ENOSYS;
+ return client_cb->sequence_number(buf, handle, seq);
+}
+
+int ustctl_get_instance_id(struct ustctl_consumer_stream *stream,
+ uint64_t *id)
+{
+ struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
+ struct lttng_ust_lib_ring_buffer *buf;
+ struct lttng_ust_shm_handle *handle;
+
+ if (!stream || !id)
+ return -EINVAL;
+ buf = stream->buf;
+ handle = stream->chan->chan->handle;
+ client_cb = get_client_cb(buf, handle);
+ if (!client_cb)
+ return -ENOSYS;
+ return client_cb->instance_id(buf, handle, id);
+}
+
+#ifdef LTTNG_UST_HAVE_PERF_EVENT
int ustctl_has_perf_counters(void)
{
return 0;
}
+/* Regenerate the statedump. */
+int ustctl_regenerate_statedump(int sock, int handle)
+{
+ struct ustcomm_ust_msg lum;
+ struct ustcomm_ust_reply lur;
+ int ret;
+
+ memset(&lum, 0, sizeof(lum));
+ lum.handle = handle;
+ lum.cmd = LTTNG_UST_SESSION_STATEDUMP;
+ ret = ustcomm_send_app_cmd(sock, &lum, &lur);
+ if (ret)
+ return ret;
+ DBG("Regenerated statedump for handle %u", handle);
+ return 0;
+}
+
static __attribute__((constructor))
void ustctl_init(void)
{