Refactoring: struct lttng_ust_channel_ops
[lttng-ust.git] / liblttng-ust-ctl / ustctl.c
index 01214eca60129650c12136205b294b9e1e1993c6..2a7c7d8a39ca0d3beadecdbab820fd90666b6999 100644 (file)
@@ -1,41 +1,39 @@
 /*
- * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
- * Copyright (C) 2011-2013 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License 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.
+ * Copyright (C) 2011 Julien Desfossez <julien.desfossez@polymtl.ca>
+ * Copyright (C) 2011-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  */
 
 #include <stdint.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <lttng/ust-config.h>
 #include <lttng/ust-ctl.h>
 #include <lttng/ust-abi.h>
-#include <lttng/ust-events.h>
 #include <lttng/ust-endian.h>
+
 #include <usterr-signal-safe.h>
 #include <ust-comm.h>
-#include <helper.h>
+#include <ust-helper.h>
+#include "ust-compat.h"
 
 #include "../libringbuffer/backend.h"
 #include "../libringbuffer/frontend.h"
+#include "../liblttng-ust/ust-events-internal.h"
 #include "../liblttng-ust/wait.h"
 #include "../liblttng-ust/lttng-rb-clients.h"
 #include "../liblttng-ust/clock.h"
 #include "../liblttng-ust/getenv.h"
+#include "../liblttng-ust/lttng-tracer-core.h"
+
+#include "../libcounter/shm.h"
+#include "../libcounter/smp.h"
+#include "../libcounter/counter.h"
 
 /*
  * Number of milliseconds to retry before failing metadata writes on
@@ -67,6 +65,25 @@ struct ustctl_consumer_stream {
        uint64_t memory_map_size;
 };
 
+#define USTCTL_COUNTER_ATTR_DIMENSION_MAX 8
+struct ustctl_counter_attr {
+       enum ustctl_counter_arithmetic arithmetic;
+       enum ustctl_counter_bitness bitness;
+       uint32_t nr_dimensions;
+       int64_t global_sum_step;
+       struct ustctl_counter_dimension dimensions[USTCTL_COUNTER_ATTR_DIMENSION_MAX];
+       bool coalesce_hits;
+};
+
+/*
+ * Counter representation within daemon.
+ */
+struct ustctl_daemon_counter {
+       struct lib_counter *counter;
+       const struct lttng_counter_ops *ops;
+       struct ustctl_counter_attr *attr;       /* initial attributes */
+};
+
 extern void lttng_ring_buffer_client_overwrite_init(void);
 extern void lttng_ring_buffer_client_overwrite_rt_init(void);
 extern void lttng_ring_buffer_client_discard_init(void);
@@ -78,6 +95,18 @@ extern void lttng_ring_buffer_client_discard_exit(void);
 extern void lttng_ring_buffer_client_discard_rt_exit(void);
 extern void lttng_ring_buffer_metadata_client_exit(void);
 
+__attribute__((visibility("hidden")))
+extern void lttng_counter_client_percpu_32_modular_init(void);
+
+__attribute__((visibility("hidden")))
+extern void lttng_counter_client_percpu_32_modular_exit(void);
+
+__attribute__((visibility("hidden")))
+extern void lttng_counter_client_percpu_64_modular_init(void);
+
+__attribute__((visibility("hidden")))
+extern void lttng_counter_client_percpu_64_modular_exit(void);
+
 int ustctl_release_handle(int sock, int handle)
 {
        struct ustcomm_ust_msg lum;
@@ -87,7 +116,7 @@ int ustctl_release_handle(int sock, int handle)
                return 0;
        memset(&lum, 0, sizeof(lum));
        lum.handle = handle;
-       lum.cmd = LTTNG_UST_RELEASE;
+       lum.cmd = LTTNG_UST_ABI_RELEASE;
        return ustcomm_send_app_cmd(sock, &lum, &lur);
 }
 
@@ -95,7 +124,7 @@ int ustctl_release_handle(int sock, int handle)
  * If sock is negative, it means we don't have to notify the other side
  * (e.g. application has already vanished).
  */
-int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
+int ustctl_release_object(int sock, struct lttng_ust_abi_object_data *data)
 {
        int ret;
 
@@ -103,7 +132,7 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
                return -EINVAL;
 
        switch (data->type) {
-       case LTTNG_UST_OBJECT_TYPE_CHANNEL:
+       case LTTNG_UST_ABI_OBJECT_TYPE_CHANNEL:
                if (data->u.channel.wakeup_fd >= 0) {
                        ret = close(data->u.channel.wakeup_fd);
                        if (ret < 0) {
@@ -115,7 +144,7 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
                free(data->u.channel.data);
                data->u.channel.data = NULL;
                break;
-       case LTTNG_UST_OBJECT_TYPE_STREAM:
+       case LTTNG_UST_ABI_OBJECT_TYPE_STREAM:
                if (data->u.stream.shm_fd >= 0) {
                        ret = close(data->u.stream.shm_fd);
                        if (ret < 0) {
@@ -133,8 +162,34 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
                        data->u.stream.wakeup_fd = -1;
                }
                break;
-       case LTTNG_UST_OBJECT_TYPE_EVENT:
-       case LTTNG_UST_OBJECT_TYPE_CONTEXT:
+       case LTTNG_UST_ABI_OBJECT_TYPE_EVENT:
+       case LTTNG_UST_ABI_OBJECT_TYPE_CONTEXT:
+       case LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER_GROUP:
+       case LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER:
+               break;
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER:
+               free(data->u.counter.data);
+               data->u.counter.data = NULL;
+               break;
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_GLOBAL:
+               if (data->u.counter_global.shm_fd >= 0) {
+                       ret = close(data->u.counter_global.shm_fd);
+                       if (ret < 0) {
+                               ret = -errno;
+                               return ret;
+                       }
+                       data->u.counter_global.shm_fd = -1;
+               }
+               break;
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_CPU:
+               if (data->u.counter_cpu.shm_fd >= 0) {
+                       ret = close(data->u.counter_cpu.shm_fd);
+                       if (ret < 0) {
+                               ret = -errno;
+                               return ret;
+                       }
+                       data->u.counter_cpu.shm_fd = -1;
+               }
                break;
        default:
                assert(0);
@@ -153,8 +208,8 @@ int ustctl_register_done(int sock)
 
        DBG("Sending register done command to %d", sock);
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_REGISTER_DONE;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_REGISTER_DONE;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -172,8 +227,8 @@ int ustctl_create_session(int sock)
 
        /* Create session */
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_SESSION;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_SESSION;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -182,13 +237,13 @@ int ustctl_create_session(int sock)
        return session_handle;
 }
 
-int ustctl_create_event(int sock, struct lttng_ust_event *ev,
-               struct lttng_ust_object_data *channel_data,
-               struct lttng_ust_object_data **_event_data)
+int ustctl_create_event(int sock, struct lttng_ust_abi_event *ev,
+               struct lttng_ust_abi_object_data *channel_data,
+               struct lttng_ust_abi_object_data **_event_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
-       struct lttng_ust_object_data *event_data;
+       struct lttng_ust_abi_object_data *event_data;
        int ret;
 
        if (!channel_data || !_event_data)
@@ -197,12 +252,12 @@ int ustctl_create_event(int sock, struct lttng_ust_event *ev,
        event_data = zmalloc(sizeof(*event_data));
        if (!event_data)
                return -ENOMEM;
-       event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
+       event_data->type = LTTNG_UST_ABI_OBJECT_TYPE_EVENT;
        memset(&lum, 0, sizeof(lum));
        lum.handle = channel_data->handle;
-       lum.cmd = LTTNG_UST_EVENT;
+       lum.cmd = LTTNG_UST_ABI_EVENT;
        strncpy(lum.u.event.name, ev->name,
-               LTTNG_UST_SYM_NAME_LEN);
+               LTTNG_UST_ABI_SYM_NAME_LEN);
        lum.u.event.instrumentation = ev->instrumentation;
        lum.u.event.loglevel_type = ev->loglevel_type;
        lum.u.event.loglevel = ev->loglevel;
@@ -218,12 +273,12 @@ int ustctl_create_event(int sock, struct lttng_ust_event *ev,
 }
 
 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 lttng_ust_abi_object_data *obj_data,
+               struct lttng_ust_abi_object_data **_context_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
-       struct lttng_ust_object_data *context_data = NULL;
+       struct lttng_ust_abi_object_data *context_data = NULL;
        char *buf = NULL;
        size_t len;
        int ret;
@@ -238,17 +293,17 @@ int ustctl_add_context(int sock, struct lttng_ust_context_attr *ctx,
                ret = -ENOMEM;
                goto end;
        }
-       context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
+       context_data->type = LTTNG_UST_ABI_OBJECT_TYPE_CONTEXT;
        memset(&lum, 0, sizeof(lum));
        lum.handle = obj_data->handle;
-       lum.cmd = LTTNG_UST_CONTEXT;
+       lum.cmd = LTTNG_UST_ABI_CONTEXT;
 
        lum.u.context.ctx = ctx->ctx;
        switch (ctx->ctx) {
-       case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
+       case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
                lum.u.context.u.perf_counter = ctx->u.perf_counter;
                break;
-       case LTTNG_UST_CONTEXT_APP_CONTEXT:
+       case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
        {
                size_t provider_name_len = strlen(
                                ctx->u.app_ctx.provider_name) + 1;
@@ -300,8 +355,8 @@ end:
        return ret;
 }
 
-int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode,
-               struct lttng_ust_object_data *obj_data)
+int ustctl_set_filter(int sock, struct lttng_ust_abi_filter_bytecode *bytecode,
+               struct lttng_ust_abi_object_data *obj_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -312,7 +367,7 @@ int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = obj_data->handle;
-       lum.cmd = LTTNG_UST_FILTER;
+       lum.cmd = LTTNG_UST_ABI_FILTER;
        lum.u.filter.data_size = bytecode->len;
        lum.u.filter.reloc_offset = bytecode->reloc_offset;
        lum.u.filter.seqnum = bytecode->seqnum;
@@ -331,8 +386,39 @@ int ustctl_set_filter(int sock, struct lttng_ust_filter_bytecode *bytecode,
        return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
 }
 
-int ustctl_set_exclusion(int sock, struct lttng_ust_event_exclusion *exclusion,
-               struct lttng_ust_object_data *obj_data)
+int ustctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *bytecode,
+               struct lttng_ust_abi_object_data *obj_data)
+{
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       int ret;
+
+       if (!obj_data)
+               return -EINVAL;
+
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = obj_data->handle;
+       lum.cmd = LTTNG_UST_ABI_CAPTURE;
+       lum.u.capture.data_size = bytecode->len;
+       lum.u.capture.reloc_offset = bytecode->reloc_offset;
+       lum.u.capture.seqnum = bytecode->seqnum;
+
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret)
+               return ret;
+       /* send var len bytecode */
+       ret = ustcomm_send_unix_sock(sock, bytecode->data,
+                               bytecode->len);
+       if (ret < 0) {
+               return ret;
+       }
+       if (ret != bytecode->len)
+               return -EINVAL;
+       return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+}
+
+int ustctl_set_exclusion(int sock, struct lttng_ust_abi_event_exclusion *exclusion,
+               struct lttng_ust_abi_object_data *obj_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -344,7 +430,7 @@ int ustctl_set_exclusion(int sock, struct lttng_ust_event_exclusion *exclusion,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = obj_data->handle;
-       lum.cmd = LTTNG_UST_EXCLUSION;
+       lum.cmd = LTTNG_UST_ABI_EXCLUSION;
        lum.u.exclusion.count = exclusion->count;
 
        ret = ustcomm_send_app_msg(sock, &lum);
@@ -355,18 +441,18 @@ int ustctl_set_exclusion(int sock, struct lttng_ust_event_exclusion *exclusion,
        /* send var len exclusion names */
        ret = ustcomm_send_unix_sock(sock,
                        exclusion->names,
-                       exclusion->count * LTTNG_UST_SYM_NAME_LEN);
+                       exclusion->count * LTTNG_UST_ABI_SYM_NAME_LEN);
        if (ret < 0) {
                return ret;
        }
-       if (ret != exclusion->count * LTTNG_UST_SYM_NAME_LEN) {
+       if (ret != exclusion->count * LTTNG_UST_ABI_SYM_NAME_LEN) {
                return -EINVAL;
        }
        return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
 }
 
 /* Enable event, channel and session ioctl */
-int ustctl_enable(int sock, struct lttng_ust_object_data *object)
+int ustctl_enable(int sock, struct lttng_ust_abi_object_data *object)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -377,7 +463,7 @@ int ustctl_enable(int sock, struct lttng_ust_object_data *object)
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = object->handle;
-       lum.cmd = LTTNG_UST_ENABLE;
+       lum.cmd = LTTNG_UST_ABI_ENABLE;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -386,7 +472,7 @@ int ustctl_enable(int sock, struct lttng_ust_object_data *object)
 }
 
 /* Disable event, channel and session ioctl */
-int ustctl_disable(int sock, struct lttng_ust_object_data *object)
+int ustctl_disable(int sock, struct lttng_ust_abi_object_data *object)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -397,7 +483,7 @@ int ustctl_disable(int sock, struct lttng_ust_object_data *object)
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = object->handle;
-       lum.cmd = LTTNG_UST_DISABLE;
+       lum.cmd = LTTNG_UST_ABI_DISABLE;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -407,7 +493,7 @@ int ustctl_disable(int sock, struct lttng_ust_object_data *object)
 
 int ustctl_start_session(int sock, int handle)
 {
-       struct lttng_ust_object_data obj;
+       struct lttng_ust_abi_object_data obj;
 
        obj.handle = handle;
        return ustctl_enable(sock, &obj);
@@ -415,12 +501,112 @@ int ustctl_start_session(int sock, int handle)
 
 int ustctl_stop_session(int sock, int handle)
 {
-       struct lttng_ust_object_data obj;
+       struct lttng_ust_abi_object_data obj;
 
        obj.handle = handle;
        return ustctl_disable(sock, &obj);
 }
 
+int ustctl_create_event_notifier_group(int sock, int pipe_fd,
+               struct lttng_ust_abi_object_data **_event_notifier_group_data)
+{
+       struct lttng_ust_abi_object_data *event_notifier_group_data;
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       ssize_t len;
+       int ret;
+
+       if (!_event_notifier_group_data)
+               return -EINVAL;
+
+       event_notifier_group_data = zmalloc(sizeof(*event_notifier_group_data));
+       if (!event_notifier_group_data)
+               return -ENOMEM;
+
+       event_notifier_group_data->type = LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER_GROUP;
+
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE;
+
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret)
+               goto error;
+
+       /* Send event_notifier notification pipe. */
+       len = ustcomm_send_fds_unix_sock(sock, &pipe_fd, 1);
+       if (len <= 0) {
+               ret = len;
+               goto error;
+       }
+
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (ret)
+               goto error;
+
+       event_notifier_group_data->handle = lur.ret_val;
+       DBG("received event_notifier group handle %d", event_notifier_group_data->handle);
+
+       *_event_notifier_group_data = event_notifier_group_data;
+
+       ret = 0;
+       goto end;
+error:
+       free(event_notifier_group_data);
+
+end:
+       return ret;
+}
+
+int ustctl_create_event_notifier(int sock, struct lttng_ust_abi_event_notifier *event_notifier,
+               struct lttng_ust_abi_object_data *event_notifier_group,
+               struct lttng_ust_abi_object_data **_event_notifier_data)
+{
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       struct lttng_ust_abi_object_data *event_notifier_data;
+       ssize_t len;
+       int ret;
+
+       if (!event_notifier_group || !_event_notifier_data)
+               return -EINVAL;
+
+       event_notifier_data = zmalloc(sizeof(*event_notifier_data));
+       if (!event_notifier_data)
+               return -ENOMEM;
+
+       event_notifier_data->type = LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER;
+
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = event_notifier_group->handle;
+       lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE;
+       lum.u.event_notifier.len = sizeof(*event_notifier);
+
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret) {
+               free(event_notifier_data);
+               return ret;
+       }
+       /* Send struct lttng_ust_event_notifier */
+       len = ustcomm_send_unix_sock(sock, event_notifier, sizeof(*event_notifier));
+       if (len != sizeof(*event_notifier)) {
+               if (len < 0)
+                       return len;
+               else
+                       return -EIO;
+       }
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (ret) {
+               free(event_notifier_data);
+               return ret;
+       }
+       event_notifier_data->handle = lur.ret_val;
+       DBG("received event_notifier handle %u", event_notifier_data->handle);
+       *_event_notifier_data = event_notifier_data;
+
+       return ret;
+}
+
 int ustctl_tracepoint_list(int sock)
 {
        struct ustcomm_ust_msg lum;
@@ -428,8 +614,8 @@ int ustctl_tracepoint_list(int sock)
        int ret, tp_list_handle;
 
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_TRACEPOINT_LIST;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_TRACEPOINT_LIST;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -439,7 +625,7 @@ int ustctl_tracepoint_list(int sock)
 }
 
 int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
-               struct lttng_ust_tracepoint_iter *iter)
+               struct lttng_ust_abi_tracepoint_iter *iter)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -450,7 +636,7 @@ int ustctl_tracepoint_list_get(int sock, int tp_list_handle,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = tp_list_handle;
-       lum.cmd = LTTNG_UST_TRACEPOINT_LIST_GET;
+       lum.cmd = LTTNG_UST_ABI_TRACEPOINT_LIST_GET;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -468,8 +654,8 @@ int ustctl_tracepoint_field_list(int sock)
        int ret, tp_field_list_handle;
 
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -479,7 +665,7 @@ int ustctl_tracepoint_field_list(int sock)
 }
 
 int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
-               struct lttng_ust_field_iter *iter)
+               struct lttng_ust_abi_field_iter *iter)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -491,7 +677,7 @@ int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = tp_field_list_handle;
-       lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST_GET;
+       lum.cmd = LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -507,7 +693,7 @@ int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
        return 0;
 }
 
-int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
+int ustctl_tracer_version(int sock, struct lttng_ust_abi_tracer_version *v)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -517,8 +703,8 @@ int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
                return -EINVAL;
 
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_TRACER_VERSION;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_TRACER_VERSION;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -534,8 +720,8 @@ int ustctl_wait_quiescent(int sock)
        int ret;
 
        memset(&lum, 0, sizeof(lum));
-       lum.handle = LTTNG_UST_ROOT_HANDLE;
-       lum.cmd = LTTNG_UST_WAIT_QUIESCENT;
+       lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
+       lum.cmd = LTTNG_UST_ABI_WAIT_QUIESCENT;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -543,7 +729,7 @@ int ustctl_wait_quiescent(int sock)
        return 0;
 }
 
-int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
+int ustctl_calibrate(int sock, struct lttng_ust_abi_calibrate *calibrate)
 {
        if (!calibrate)
                return -EINVAL;
@@ -551,7 +737,7 @@ int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
        return -ENOSYS;
 }
 
-int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
+int ustctl_sock_flush_buffer(int sock, struct lttng_ust_abi_object_data *object)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -562,7 +748,7 @@ int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = object->handle;
-       lum.cmd = LTTNG_UST_FLUSH_BUFFER;
+       lum.cmd = LTTNG_UST_ABI_FLUSH_BUFFER;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -572,7 +758,7 @@ int ustctl_sock_flush_buffer(int sock, struct lttng_ust_object_data *object)
 
 static
 int ustctl_send_channel(int sock,
-               enum lttng_ust_chan_type type,
+               enum lttng_ust_abi_chan_type type,
                void *data,
                uint64_t size,
                int wakeup_fd,
@@ -680,9 +866,9 @@ int ustctl_send_stream(int sock,
 }
 
 int ustctl_recv_channel_from_consumer(int sock,
-               struct lttng_ust_object_data **_channel_data)
+               struct lttng_ust_abi_object_data **_channel_data)
 {
-       struct lttng_ust_object_data *channel_data;
+       struct lttng_ust_abi_object_data *channel_data;
        ssize_t len;
        int wakeup_fd;
        int ret;
@@ -692,7 +878,7 @@ int ustctl_recv_channel_from_consumer(int sock,
                ret = -ENOMEM;
                goto error_alloc;
        }
-       channel_data->type = LTTNG_UST_OBJECT_TYPE_CHANNEL;
+       channel_data->type = LTTNG_UST_ABI_OBJECT_TYPE_CHANNEL;
        channel_data->handle = -1;
 
        /* recv mmap size */
@@ -756,9 +942,9 @@ error_alloc:
 }
 
 int ustctl_recv_stream_from_consumer(int sock,
-               struct lttng_ust_object_data **_stream_data)
+               struct lttng_ust_abi_object_data **_stream_data)
 {
-       struct lttng_ust_object_data *stream_data;
+       struct lttng_ust_abi_object_data *stream_data;
        ssize_t len;
        int ret;
        int fds[2];
@@ -769,7 +955,7 @@ int ustctl_recv_stream_from_consumer(int sock,
                goto error_alloc;
        }
 
-       stream_data->type = LTTNG_UST_OBJECT_TYPE_STREAM;
+       stream_data->type = LTTNG_UST_ABI_OBJECT_TYPE_STREAM;
        stream_data->handle = -1;
 
        /* recv mmap size */
@@ -821,7 +1007,7 @@ error_alloc:
 }
 
 int ustctl_send_channel_to_ust(int sock, int session_handle,
-               struct lttng_ust_object_data *channel_data)
+               struct lttng_ust_abi_object_data *channel_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -832,7 +1018,7 @@ int ustctl_send_channel_to_ust(int sock, int session_handle,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = session_handle;
-       lum.cmd = LTTNG_UST_CHANNEL;
+       lum.cmd = LTTNG_UST_ABI_CHANNEL;
        lum.u.channel.len = channel_data->size;
        lum.u.channel.type = channel_data->u.channel.type;
        ret = ustcomm_send_app_msg(sock, &lum);
@@ -855,8 +1041,8 @@ int ustctl_send_channel_to_ust(int sock, int session_handle,
 }
 
 int ustctl_send_stream_to_ust(int sock,
-               struct lttng_ust_object_data *channel_data,
-               struct lttng_ust_object_data *stream_data)
+               struct lttng_ust_abi_object_data *channel_data,
+               struct lttng_ust_abi_object_data *stream_data)
 {
        struct ustcomm_ust_msg lum;
        struct ustcomm_ust_reply lur;
@@ -864,7 +1050,7 @@ int ustctl_send_stream_to_ust(int sock,
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = channel_data->handle;
-       lum.cmd = LTTNG_UST_STREAM;
+       lum.cmd = LTTNG_UST_ABI_STREAM;
        lum.u.stream.len = stream_data->size;
        lum.u.stream.stream_nr = stream_data->u.stream.stream_nr;
        ret = ustcomm_send_app_msg(sock, &lum);
@@ -872,7 +1058,7 @@ int ustctl_send_stream_to_ust(int sock,
                return ret;
 
        assert(stream_data);
-       assert(stream_data->type == LTTNG_UST_OBJECT_TYPE_STREAM);
+       assert(stream_data->type == LTTNG_UST_ABI_OBJECT_TYPE_STREAM);
 
        ret = ustctl_send_stream(sock,
                        stream_data->u.stream.stream_nr,
@@ -884,10 +1070,10 @@ int ustctl_send_stream_to_ust(int sock,
        return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
 }
 
-int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
-                struct lttng_ust_object_data *src)
+int ustctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **dest,
+                struct lttng_ust_abi_object_data *src)
 {
-       struct lttng_ust_object_data *obj;
+       struct lttng_ust_abi_object_data *obj;
        int ret;
 
        if (src->handle != -1) {
@@ -906,7 +1092,7 @@ int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
        obj->size = src->size;
 
        switch (obj->type) {
-       case LTTNG_UST_OBJECT_TYPE_CHANNEL:
+       case LTTNG_UST_ABI_OBJECT_TYPE_CHANNEL:
        {
                obj->u.channel.type = src->u.channel.type;
                if (src->u.channel.wakeup_fd >= 0) {
@@ -942,7 +1128,7 @@ int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
 
        }
 
-       case LTTNG_UST_OBJECT_TYPE_STREAM:
+       case LTTNG_UST_ABI_OBJECT_TYPE_STREAM:
        {
                obj->u.stream.stream_nr = src->u.stream.stream_nr;
                if (src->u.stream.wakeup_fd >= 0) {
@@ -983,6 +1169,44 @@ int ustctl_duplicate_ust_object_data(struct lttng_ust_object_data **dest,
                goto error_type;
        }
 
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER:
+       {
+               obj->u.counter.data = zmalloc(obj->size);
+               if (!obj->u.counter.data) {
+                       ret = -ENOMEM;
+                       goto error_type;
+               }
+               memcpy(obj->u.counter.data, src->u.counter.data, obj->size);
+               break;
+       }
+
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_GLOBAL:
+       {
+               if (src->u.counter_global.shm_fd >= 0) {
+                       obj->u.counter_global.shm_fd =
+                               dup(src->u.counter_global.shm_fd);
+                       if (obj->u.counter_global.shm_fd < 0) {
+                               ret = errno;
+                               goto error_type;
+                       }
+               }
+               break;
+       }
+
+       case LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_CPU:
+       {
+               obj->u.counter_cpu.cpu_nr = src->u.counter_cpu.cpu_nr;
+               if (src->u.counter_cpu.shm_fd >= 0) {
+                       obj->u.counter_cpu.shm_fd =
+                               dup(src->u.counter_cpu.shm_fd);
+                       if (obj->u.counter_cpu.shm_fd < 0) {
+                               ret = errno;
+                               goto error_type;
+                       }
+               }
+               break;
+       }
+
        default:
                ret = -EINVAL;
                goto error_type;
@@ -1014,8 +1238,8 @@ struct ustctl_consumer_channel *
        struct lttng_transport *transport;
 
        switch (attr->type) {
-       case LTTNG_UST_CHAN_PER_CPU:
-               if (attr->output == LTTNG_UST_MMAP) {
+       case LTTNG_UST_ABI_CHAN_PER_CPU:
+               if (attr->output == LTTNG_UST_ABI_MMAP) {
                        if (attr->overwrite) {
                                if (attr->read_timer_interval == 0) {
                                        transport_name = "relay-overwrite-mmap";
@@ -1033,8 +1257,8 @@ struct ustctl_consumer_channel *
                        return NULL;
                }
                break;
-       case LTTNG_UST_CHAN_METADATA:
-               if (attr->output == LTTNG_UST_MMAP)
+       case LTTNG_UST_ABI_CHAN_METADATA:
+               if (attr->output == LTTNG_UST_ABI_MMAP)
                        transport_name = "relay-metadata-mmap";
                else
                        return NULL;
@@ -1044,7 +1268,7 @@ struct ustctl_consumer_channel *
                return NULL;
        }
 
-       transport = lttng_transport_find(transport_name);
+       transport = lttng_ust_transport_find(transport_name);
        if (!transport) {
                DBG("LTTng transport %s not found\n",
                        transport_name);
@@ -1055,7 +1279,7 @@ struct ustctl_consumer_channel *
        if (!chan)
                return NULL;
 
-       chan->chan = transport->ops.channel_create(transport_name, NULL,
+       chan->chan = transport->ops.priv->channel_create(transport_name, NULL,
                        attr->subbuf_size, attr->num_subbuf,
                        attr->switch_timer_interval,
                        attr->read_timer_interval,
@@ -1080,7 +1304,7 @@ void ustctl_destroy_channel(struct ustctl_consumer_channel *chan)
 {
        (void) ustctl_channel_close_wait_fd(chan);
        (void) ustctl_channel_close_wakeup_fd(chan);
-       chan->chan->ops->channel_destroy(chan->chan);
+       chan->chan->ops->priv->channel_destroy(chan->chan);
        free(chan);
 }
 
@@ -1126,10 +1350,10 @@ int ustctl_write_metadata_to_channel(
 
        for (pos = 0; pos < len; pos += reserve_len) {
                reserve_len = min_t(size_t,
-                               chan->ops->packet_avail_size(chan->chan, chan->handle),
+                               chan->ops->priv->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, NULL);
+                                        sizeof(char), -1, chan->handle);
                /*
                 * We don't care about metadata buffer's records lost
                 * count, because we always retry here. Report error if
@@ -1173,10 +1397,10 @@ ssize_t ustctl_write_one_packet_to_channel(
        int ret;
 
        reserve_len = min_t(ssize_t,
-                       chan->ops->packet_avail_size(chan->chan, chan->handle),
+                       chan->ops->priv->packet_avail_size(chan->chan, chan->handle),
                        len);
        lib_ring_buffer_ctx_init(&ctx, chan->chan, NULL, reserve_len,
-                       sizeof(char), -1, chan->handle, NULL);
+                       sizeof(char), -1, chan->handle);
        ret = chan->ops->event_reserve(&ctx, 0);
        if (ret != 0) {
                DBG("LTTng: event reservation failed");
@@ -1193,7 +1417,7 @@ end:
 
 int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        int ret;
 
        chan = consumer_chan->chan->chan;
@@ -1206,7 +1430,7 @@ int ustctl_channel_close_wait_fd(struct ustctl_consumer_channel *consumer_chan)
 
 int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        int ret;
 
        chan = consumer_chan->chan->chan;
@@ -1219,7 +1443,7 @@ int ustctl_channel_close_wakeup_fd(struct ustctl_consumer_channel *consumer_chan
 
 int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
 
        chan = stream->chan->chan->chan;
        return ring_buffer_stream_close_wait_fd(&chan->backend.config,
@@ -1228,7 +1452,7 @@ int ustctl_stream_close_wait_fd(struct ustctl_consumer_stream *stream)
 
 int ustctl_stream_close_wakeup_fd(struct ustctl_consumer_stream *stream)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
 
        chan = stream->chan->chan->chan;
        return ring_buffer_stream_close_wakeup_fd(&chan->backend.config,
@@ -1241,7 +1465,7 @@ struct ustctl_consumer_stream *
 {
        struct ustctl_consumer_stream *stream;
        struct lttng_ust_shm_handle *handle;
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        int shm_fd, wait_fd, wakeup_fd;
        uint64_t memory_map_size;
        struct lttng_ust_lib_ring_buffer *buf;
@@ -1354,7 +1578,7 @@ int ustctl_get_mmap_len(struct ustctl_consumer_stream *stream,
 {
        struct ustctl_consumer_channel *consumer_chan;
        unsigned long mmap_buf_len;
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
 
        if (!stream)
                return -EINVAL;
@@ -1376,7 +1600,7 @@ int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
                unsigned long *len)
 {
        struct ustctl_consumer_channel *consumer_chan;
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
 
        if (!stream)
                return -EINVAL;
@@ -1395,7 +1619,7 @@ int ustctl_get_max_subbuf_size(struct ustctl_consumer_stream *stream,
 int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
                unsigned long *off)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        unsigned long sb_bindex;
        struct lttng_ust_lib_ring_buffer *buf;
        struct ustctl_consumer_channel *consumer_chan;
@@ -1427,7 +1651,7 @@ int ustctl_get_subbuf_size(struct ustctl_consumer_stream *stream,
                unsigned long *len)
 {
        struct ustctl_consumer_channel *consumer_chan;
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        struct lttng_ust_lib_ring_buffer *buf;
 
        if (!stream)
@@ -1446,7 +1670,7 @@ int ustctl_get_padded_subbuf_size(struct ustctl_consumer_stream *stream,
                unsigned long *len)
 {
        struct ustctl_consumer_channel *consumer_chan;
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        struct lttng_ust_lib_ring_buffer *buf;
 
        if (!stream)
@@ -1611,7 +1835,7 @@ struct lttng_ust_client_lib_ring_buffer_client_cb *get_client_cb(
                struct lttng_ust_lib_ring_buffer *buf,
                struct lttng_ust_shm_handle *handle)
 {
-       struct channel *chan;
+       struct lttng_ust_lib_ring_buffer_channel *chan;
        const struct lttng_ust_lib_ring_buffer_config *config;
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
 
@@ -1780,7 +2004,7 @@ int ustctl_get_instance_id(struct ustctl_consumer_stream *stream,
        return client_cb->instance_id(buf, handle, id);
 }
 
-#ifdef LTTNG_UST_HAVE_PERF_EVENT
+#ifdef HAVE_PERF_EVENT
 
 int ustctl_has_perf_counters(void)
 {
@@ -1796,6 +2020,105 @@ int ustctl_has_perf_counters(void)
 
 #endif
 
+#ifdef __linux__
+/*
+ * Override application pid/uid/gid with unix socket credentials. If
+ * the application announced a pid matching our view, it means it is
+ * within the same pid namespace, so expose the ppid provided by the
+ * application.
+ */
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       struct ucred ucred;
+       socklen_t ucred_len = sizeof(struct ucred);
+       int ret;
+
+       ret = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len);
+       if (ret) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       DBG("Unix socket peercred [ pid: %u, uid: %u, gid: %u ], "
+               "application registered claiming [ pid: %u, ppid: %u, uid: %u, gid: %u ]",
+               ucred.pid, ucred.uid, ucred.gid,
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       if (!ucred.pid) {
+               ERR("Unix socket credential pid=0. Refusing application in distinct, non-nested pid namespace.");
+               return -LTTNG_UST_ERR_PEERCRED_PID;
+       }
+       *pid = ucred.pid;
+       *uid = ucred.uid;
+       *gid = ucred.gid;
+       if (ucred.pid == reg_msg->pid) {
+               *ppid = reg_msg->ppid;
+       } else {
+               *ppid = 0;
+       }
+       return 0;
+}
+#elif defined(__FreeBSD__)
+#include <sys/ucred.h>
+#include <sys/un.h>
+
+/*
+ * Override application uid/gid with unix socket credentials. Use the
+ * first group of the cr_groups.
+ * Use the pid and ppid provided by the application on registration.
+ */
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       struct xucred xucred;
+       socklen_t xucred_len = sizeof(struct xucred);
+       int ret;
+
+       ret = getsockopt(sock, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_len);
+       if (ret) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       if (xucred.cr_version != XUCRED_VERSION || xucred.cr_ngroups < 1) {
+               return -LTTNG_UST_ERR_PEERCRED;
+       }
+       DBG("Unix socket peercred [ uid: %u, gid: %u ], "
+               "application registered claiming [ pid: %d, ppid: %d, uid: %u, gid: %u ]",
+               xucred.cr_uid, xucred.cr_groups[0],
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       *pid = reg_msg->pid;
+       *ppid = reg_msg->ppid;
+       *uid = xucred.cr_uid;
+       *gid = xucred.cr_groups[0];
+       return 0;
+}
+#else
+#warning "Using insecure fallback: trusting user id provided by registered applications. Please consider implementing use of unix socket credentials on your platform."
+static
+int get_cred(int sock,
+       const struct ustctl_reg_msg *reg_msg,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid)
+{
+       DBG("Application registered claiming [ pid: %u, ppid: %d, uid: %u, gid: %u ]",
+               reg_msg->pid, reg_msg->ppid, reg_msg->uid, reg_msg->gid);
+       *pid = reg_msg->pid;
+       *ppid = reg_msg->ppid;
+       *uid = reg_msg->uid;
+       *gid = reg_msg->gid;
+       return 0;
+}
+#endif
+
 /*
  * Returns 0 on success, negative error value on error.
  */
@@ -1827,10 +2150,10 @@ int ustctl_recv_reg_msg(int sock,
        if (len < 0)
                return len;
 
-       if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
+       if (reg_msg.magic == LTTNG_UST_ABI_COMM_MAGIC) {
                *byte_order = BYTE_ORDER == BIG_ENDIAN ?
                                BIG_ENDIAN : LITTLE_ENDIAN;
-       } else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
+       } else if (reg_msg.magic == bswap_32(LTTNG_UST_ABI_COMM_MAGIC)) {
                *byte_order = BYTE_ORDER == BIG_ENDIAN ?
                                LITTLE_ENDIAN : BIG_ENDIAN;
        } else {
@@ -1846,10 +2169,6 @@ int ustctl_recv_reg_msg(int sock,
        }
        *major = reg_msg.major;
        *minor = reg_msg.minor;
-       *pid = reg_msg.pid;
-       *ppid = reg_msg.ppid;
-       *uid = reg_msg.uid;
-       *gid = reg_msg.gid;
        *bits_per_long = reg_msg.bits_per_long;
        *uint8_t_alignment = reg_msg.uint8_t_alignment;
        *uint16_t_alignment = reg_msg.uint16_t_alignment;
@@ -1861,8 +2180,7 @@ int ustctl_recv_reg_msg(int sock,
                        reg_msg.major > LTTNG_UST_ABI_MAJOR_VERSION) {
                return -LTTNG_UST_ERR_UNSUP_MAJOR;
        }
-
-       return 0;
+       return get_cred(sock, &reg_msg, pid, ppid, uid, gid);
 }
 
 int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
@@ -1922,8 +2240,8 @@ int ustctl_recv_register_event(int sock,
 
        *session_objd = msg.session_objd;
        *channel_objd = msg.channel_objd;
-       strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
-       event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+       strncpy(event_name, msg.event_name, LTTNG_UST_ABI_SYM_NAME_LEN);
+       event_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
        *loglevel = msg.loglevel;
        signature_len = msg.signature_len;
        fields_len = msg.fields_len;
@@ -2062,8 +2380,8 @@ int ustctl_recv_register_enum(int sock,
                return len;
 
        *session_objd = msg.session_objd;
-       strncpy(enum_name, msg.enum_name, LTTNG_UST_SYM_NAME_LEN);
-       enum_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+       strncpy(enum_name, msg.enum_name, LTTNG_UST_ABI_SYM_NAME_LEN);
+       enum_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
        entries_len = msg.entries_len;
 
        if (entries_len % sizeof(*a_entries) != 0) {
@@ -2231,7 +2549,7 @@ int ustctl_regenerate_statedump(int sock, int handle)
 
        memset(&lum, 0, sizeof(lum));
        lum.handle = handle;
-       lum.cmd = LTTNG_UST_SESSION_STATEDUMP;
+       lum.cmd = LTTNG_UST_ABI_SESSION_STATEDUMP;
        ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
@@ -2239,17 +2557,389 @@ int ustctl_regenerate_statedump(int sock, int handle)
        return 0;
 }
 
+/* counter operations */
+
+int ustctl_get_nr_cpu_per_counter(void)
+{
+       return lttng_counter_num_possible_cpus();
+}
+
+struct ustctl_daemon_counter *
+       ustctl_create_counter(size_t nr_dimensions,
+               const struct ustctl_counter_dimension *dimensions,
+               int64_t global_sum_step,
+               int global_counter_fd,
+               int nr_counter_cpu_fds,
+               const int *counter_cpu_fds,
+               enum ustctl_counter_bitness bitness,
+               enum ustctl_counter_arithmetic arithmetic,
+               uint32_t alloc_flags,
+               bool coalesce_hits)
+{
+       const char *transport_name;
+       struct ustctl_daemon_counter *counter;
+       struct lttng_counter_transport *transport;
+       struct lttng_counter_dimension ust_dim[LTTNG_COUNTER_DIMENSION_MAX];
+       size_t i;
+
+       if (nr_dimensions > LTTNG_COUNTER_DIMENSION_MAX)
+               return NULL;
+       /* Currently, only per-cpu allocation is supported. */
+       switch (alloc_flags) {
+       case USTCTL_COUNTER_ALLOC_PER_CPU:
+               break;
+
+       case USTCTL_COUNTER_ALLOC_PER_CPU | USTCTL_COUNTER_ALLOC_GLOBAL:
+       case USTCTL_COUNTER_ALLOC_GLOBAL:
+       default:
+               return NULL;
+       }
+       switch (bitness) {
+       case USTCTL_COUNTER_BITNESS_32:
+               switch (arithmetic) {
+               case USTCTL_COUNTER_ARITHMETIC_MODULAR:
+                       transport_name = "counter-per-cpu-32-modular";
+                       break;
+               case USTCTL_COUNTER_ARITHMETIC_SATURATION:
+                       transport_name = "counter-per-cpu-32-saturation";
+                       break;
+               default:
+                       return NULL;
+               }
+               break;
+       case USTCTL_COUNTER_BITNESS_64:
+               switch (arithmetic) {
+               case USTCTL_COUNTER_ARITHMETIC_MODULAR:
+                       transport_name = "counter-per-cpu-64-modular";
+                       break;
+               case USTCTL_COUNTER_ARITHMETIC_SATURATION:
+                       transport_name = "counter-per-cpu-64-saturation";
+                       break;
+               default:
+                       return NULL;
+               }
+               break;
+       default:
+               return NULL;
+       }
+
+       transport = lttng_counter_transport_find(transport_name);
+       if (!transport) {
+               DBG("LTTng transport %s not found\n",
+                       transport_name);
+               return NULL;
+       }
+
+       counter = zmalloc(sizeof(*counter));
+       if (!counter)
+               return NULL;
+       counter->attr = zmalloc(sizeof(*counter->attr));
+       if (!counter->attr)
+               goto free_counter;
+       counter->attr->bitness = bitness;
+       counter->attr->arithmetic = arithmetic;
+       counter->attr->nr_dimensions = nr_dimensions;
+       counter->attr->global_sum_step = global_sum_step;
+       counter->attr->coalesce_hits = coalesce_hits;
+       for (i = 0; i < nr_dimensions; i++)
+               counter->attr->dimensions[i] = dimensions[i];
+
+       for (i = 0; i < nr_dimensions; i++) {
+               ust_dim[i].size = dimensions[i].size;
+               ust_dim[i].underflow_index = dimensions[i].underflow_index;
+               ust_dim[i].overflow_index = dimensions[i].overflow_index;
+               ust_dim[i].has_underflow = dimensions[i].has_underflow;
+               ust_dim[i].has_overflow = dimensions[i].has_overflow;
+       }
+       counter->counter = transport->ops.counter_create(nr_dimensions,
+               ust_dim, global_sum_step, global_counter_fd,
+               nr_counter_cpu_fds, counter_cpu_fds, true);
+       if (!counter->counter)
+               goto free_attr;
+       counter->ops = &transport->ops;
+       return counter;
+
+free_attr:
+       free(counter->attr);
+free_counter:
+       free(counter);
+       return NULL;
+}
+
+int ustctl_create_counter_data(struct ustctl_daemon_counter *counter,
+               struct lttng_ust_abi_object_data **_counter_data)
+{
+       struct lttng_ust_abi_object_data *counter_data;
+       struct lttng_ust_abi_counter_conf counter_conf = {0};
+       size_t i;
+       int ret;
+
+       switch (counter->attr->arithmetic) {
+       case USTCTL_COUNTER_ARITHMETIC_MODULAR:
+               counter_conf.arithmetic = LTTNG_UST_ABI_COUNTER_ARITHMETIC_MODULAR;
+               break;
+       case USTCTL_COUNTER_ARITHMETIC_SATURATION:
+               counter_conf.arithmetic = LTTNG_UST_ABI_COUNTER_ARITHMETIC_SATURATION;
+               break;
+       default:
+               return -EINVAL;
+       }
+       switch (counter->attr->bitness) {
+       case USTCTL_COUNTER_BITNESS_32:
+               counter_conf.bitness = LTTNG_UST_ABI_COUNTER_BITNESS_32;
+               break;
+       case USTCTL_COUNTER_BITNESS_64:
+               counter_conf.bitness = LTTNG_UST_ABI_COUNTER_BITNESS_64;
+               break;
+       default:
+               return -EINVAL;
+       }
+       counter_conf.number_dimensions = counter->attr->nr_dimensions;
+       counter_conf.global_sum_step = counter->attr->global_sum_step;
+       counter_conf.coalesce_hits = counter->attr->coalesce_hits;
+       for (i = 0; i < counter->attr->nr_dimensions; i++) {
+               counter_conf.dimensions[i].size = counter->attr->dimensions[i].size;
+               counter_conf.dimensions[i].underflow_index = counter->attr->dimensions[i].underflow_index;
+               counter_conf.dimensions[i].overflow_index = counter->attr->dimensions[i].overflow_index;
+               counter_conf.dimensions[i].has_underflow = counter->attr->dimensions[i].has_underflow;
+               counter_conf.dimensions[i].has_overflow = counter->attr->dimensions[i].has_overflow;
+       }
+
+       counter_data = zmalloc(sizeof(*counter_data));
+       if (!counter_data) {
+               ret = -ENOMEM;
+               goto error_alloc;
+       }
+       counter_data->type = LTTNG_UST_ABI_OBJECT_TYPE_COUNTER;
+       counter_data->handle = -1;
+
+       counter_data->size = sizeof(counter_conf);
+       counter_data->u.counter.data = zmalloc(sizeof(counter_conf));
+       if (!counter_data->u.counter.data) {
+               ret = -ENOMEM;
+               goto error_alloc_data;
+       }
+
+       memcpy(counter_data->u.counter.data, &counter_conf, sizeof(counter_conf));
+       *_counter_data = counter_data;
+
+       return 0;
+
+error_alloc_data:
+       free(counter_data);
+error_alloc:
+       return ret;
+}
+
+int ustctl_create_counter_global_data(struct ustctl_daemon_counter *counter,
+               struct lttng_ust_abi_object_data **_counter_global_data)
+{
+       struct lttng_ust_abi_object_data *counter_global_data;
+       int ret, fd;
+       size_t len;
+
+       if (lttng_counter_get_global_shm(counter->counter, &fd, &len))
+               return -EINVAL;
+       counter_global_data = zmalloc(sizeof(*counter_global_data));
+       if (!counter_global_data) {
+               ret = -ENOMEM;
+               goto error_alloc;
+       }
+       counter_global_data->type = LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_GLOBAL;
+       counter_global_data->handle = -1;
+       counter_global_data->size = len;
+       counter_global_data->u.counter_global.shm_fd = fd;
+       *_counter_global_data = counter_global_data;
+       return 0;
+
+error_alloc:
+       return ret;
+}
+
+int ustctl_create_counter_cpu_data(struct ustctl_daemon_counter *counter, int cpu,
+               struct lttng_ust_abi_object_data **_counter_cpu_data)
+{
+       struct lttng_ust_abi_object_data *counter_cpu_data;
+       int ret, fd;
+       size_t len;
+
+       if (lttng_counter_get_cpu_shm(counter->counter, cpu, &fd, &len))
+               return -EINVAL;
+       counter_cpu_data = zmalloc(sizeof(*counter_cpu_data));
+       if (!counter_cpu_data) {
+               ret = -ENOMEM;
+               goto error_alloc;
+       }
+       counter_cpu_data->type = LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_CPU;
+       counter_cpu_data->handle = -1;
+       counter_cpu_data->size = len;
+       counter_cpu_data->u.counter_cpu.shm_fd = fd;
+       counter_cpu_data->u.counter_cpu.cpu_nr = cpu;
+       *_counter_cpu_data = counter_cpu_data;
+       return 0;
+
+error_alloc:
+       return ret;
+}
+
+void ustctl_destroy_counter(struct ustctl_daemon_counter *counter)
+{
+       counter->ops->counter_destroy(counter->counter);
+       free(counter->attr);
+       free(counter);
+}
+
+int ustctl_send_counter_data_to_ust(int sock, int parent_handle,
+               struct lttng_ust_abi_object_data *counter_data)
+{
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       int ret;
+       size_t size;
+       ssize_t len;
+
+       if (!counter_data)
+               return -EINVAL;
+
+       size = counter_data->size;
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = parent_handle;
+       lum.cmd = LTTNG_UST_ABI_COUNTER;
+       lum.u.counter.len = size;
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret)
+               return ret;
+
+       /* Send counter data */
+       len = ustcomm_send_unix_sock(sock, counter_data->u.counter.data, size);
+       if (len != size) {
+               if (len < 0)
+                       return len;
+               else
+                       return -EIO;
+       }
+
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (!ret) {
+               counter_data->handle = lur.ret_val;
+       }
+       return ret;
+}
+
+int ustctl_send_counter_global_data_to_ust(int sock,
+               struct lttng_ust_abi_object_data *counter_data,
+               struct lttng_ust_abi_object_data *counter_global_data)
+{
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       int ret, shm_fd[1];
+       size_t size;
+       ssize_t len;
+
+       if (!counter_data || !counter_global_data)
+               return -EINVAL;
+
+       size = counter_global_data->size;
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = counter_data->handle;      /* parent handle */
+       lum.cmd = LTTNG_UST_ABI_COUNTER_GLOBAL;
+       lum.u.counter_global.len = size;
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret)
+               return ret;
+
+       shm_fd[0] = counter_global_data->u.counter_global.shm_fd;
+       len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1);
+       if (len <= 0) {
+               if (len < 0)
+                       return len;
+               else
+                       return -EIO;
+       }
+
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (!ret) {
+               counter_global_data->handle = lur.ret_val;
+       }
+       return ret;
+}
+
+int ustctl_send_counter_cpu_data_to_ust(int sock,
+               struct lttng_ust_abi_object_data *counter_data,
+               struct lttng_ust_abi_object_data *counter_cpu_data)
+{
+       struct ustcomm_ust_msg lum;
+       struct ustcomm_ust_reply lur;
+       int ret, shm_fd[1];
+       size_t size;
+       ssize_t len;
+
+       if (!counter_data || !counter_cpu_data)
+               return -EINVAL;
+
+       size = counter_cpu_data->size;
+       memset(&lum, 0, sizeof(lum));
+       lum.handle = counter_data->handle;      /* parent handle */
+       lum.cmd = LTTNG_UST_ABI_COUNTER_CPU;
+       lum.u.counter_cpu.len = size;
+       lum.u.counter_cpu.cpu_nr = counter_cpu_data->u.counter_cpu.cpu_nr;
+       ret = ustcomm_send_app_msg(sock, &lum);
+       if (ret)
+               return ret;
+
+       shm_fd[0] = counter_cpu_data->u.counter_global.shm_fd;
+       len = ustcomm_send_fds_unix_sock(sock, shm_fd, 1);
+       if (len <= 0) {
+               if (len < 0)
+                       return len;
+               else
+                       return -EIO;
+       }
+
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (!ret) {
+               counter_cpu_data->handle = lur.ret_val;
+       }
+       return ret;
+}
+
+int ustctl_counter_read(struct ustctl_daemon_counter *counter,
+               const size_t *dimension_indexes,
+               int cpu, int64_t *value,
+               bool *overflow, bool *underflow)
+{
+       return counter->ops->counter_read(counter->counter, dimension_indexes, cpu,
+                       value, overflow, underflow);
+}
+
+int ustctl_counter_aggregate(struct ustctl_daemon_counter *counter,
+               const size_t *dimension_indexes,
+               int64_t *value,
+               bool *overflow, bool *underflow)
+{
+       return counter->ops->counter_aggregate(counter->counter, dimension_indexes,
+                       value, overflow, underflow);
+}
+
+int ustctl_counter_clear(struct ustctl_daemon_counter *counter,
+               const size_t *dimension_indexes)
+{
+       return counter->ops->counter_clear(counter->counter, dimension_indexes);
+}
+
 static __attribute__((constructor))
 void ustctl_init(void)
 {
-       init_usterr();
-       lttng_ust_getenv_init();        /* Needs init_usterr() to be completed. */
+       ust_err_init();
+       lttng_ust_getenv_init();        /* Needs ust_err_init() to be completed. */
        lttng_ust_clock_init();
        lttng_ring_buffer_metadata_client_init();
        lttng_ring_buffer_client_overwrite_init();
        lttng_ring_buffer_client_overwrite_rt_init();
        lttng_ring_buffer_client_discard_init();
        lttng_ring_buffer_client_discard_rt_init();
+       lttng_counter_client_percpu_32_modular_init();
+       lttng_counter_client_percpu_64_modular_init();
        lib_ringbuffer_signal_init();
 }
 
@@ -2261,4 +2951,6 @@ void ustctl_exit(void)
        lttng_ring_buffer_client_overwrite_rt_exit();
        lttng_ring_buffer_client_overwrite_exit();
        lttng_ring_buffer_metadata_client_exit();
+       lttng_counter_client_percpu_32_modular_exit();
+       lttng_counter_client_percpu_64_modular_exit();
 }
This page took 0.043072 seconds and 4 git commands to generate.