Clarify terminolgy around cpu ids and array length
[lttng-ust.git] / src / lib / lttng-ust-ctl / ustctl.c
index 86e37f1816a660881b225f9742ec13c9d296ae4d..6faaef5ed44ff4fcc88a31b181ddd511c3f87cce 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SPDX-License-Identifier: GPL-2.0-only
  *
- * Copyright (C) 2011 Julien Desfossez <julien.desfossez@polymtl.ca>
+ * Copyright (C) 2011 EfficiOS Inc.
  * Copyright (C) 2011-2013 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  */
 
@@ -17,6 +17,8 @@
 #include <lttng/ust-abi.h>
 #include <lttng/ust-endian.h>
 #include <lttng/ust-common.h>
+#include <lttng/ust-sigbus.h>
+#include <urcu/rculist.h>
 
 #include "common/logging.h"
 #include "common/ustcomm.h"
 #include "common/ringbuffer/frontend.h"
 #include "common/events.h"
 #include "common/wait.h"
-#include "lib/lttng-ust/lttng-rb-clients.h"
+#include "common/ringbuffer-clients/clients.h"
 #include "common/getenv.h"
-#include "lib/lttng-ust/lttng-tracer-core.h"
-#include "lib/lttng-ust/lttng-counter-client.h"
+#include "common/tracer.h"
+#include "common/counter-clients/clients.h"
 
 #include "common/smp.h"
 #include "common/counter/counter.h"
@@ -62,6 +64,7 @@ struct lttng_ust_ctl_consumer_stream {
        int shm_fd, wait_fd, wakeup_fd;
        int cpu;
        uint64_t memory_map_size;
+       void *memory_map_addr;
 };
 
 #define LTTNG_UST_CTL_COUNTER_ATTR_DIMENSION_MAX 8
@@ -83,6 +86,67 @@ struct lttng_ust_ctl_daemon_counter {
        struct lttng_ust_ctl_counter_attr *attr;        /* initial attributes */
 };
 
+/*
+ * Evaluates to false if transaction begins, true if it has failed due to SIGBUS.
+ * The entire transaction must complete before the current function returns.
+ * A transaction can contain 0 or more tracked ranges as sigbus begin/end pairs.
+ */
+#define sigbus_begin() \
+({ \
+       assert(!lttng_ust_sigbus_state.jmp_ready); \
+       if (!lttng_ust_sigbus_state.head.next) { \
+               /* \
+                * Lazy init because static list initialisation is \
+                * problematic for TLS variable. \
+                */ \
+               CDS_INIT_LIST_HEAD(&lttng_ust_sigbus_state.head); \
+       } \
+       if (sigsetjmp(lttng_ust_sigbus_state.sj_env, 1)) { \
+               /* SIGBUS. */ \
+               CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 0); \
+               true; \
+       } \
+       cmm_barrier(); \
+       CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 1); \
+       false; \
+})
+
+static void sigbus_end(void)
+{
+       assert(lttng_ust_sigbus_state.jmp_ready);
+       cmm_barrier();
+       CMM_STORE_SHARED(lttng_ust_sigbus_state.jmp_ready, 0);
+}
+
+static
+void lttng_ust_sigbus_add_range(struct lttng_ust_sigbus_range *range, void *start, size_t len)
+{
+       range->start = start;
+       range->end = (char *)start + len;
+       cds_list_add_rcu(&range->node, &lttng_ust_sigbus_state.head);
+       cmm_barrier();
+}
+
+static
+void lttng_ust_sigbus_del_range(struct lttng_ust_sigbus_range *range)
+{
+       cmm_barrier();
+       cds_list_del_rcu(&range->node);
+}
+
+void lttng_ust_ctl_sigbus_handle(void *addr)
+{
+       struct lttng_ust_sigbus_range *range;
+
+       if (!CMM_LOAD_SHARED(lttng_ust_sigbus_state.jmp_ready))
+               return;
+       cds_list_for_each_entry_rcu(range, &lttng_ust_sigbus_state.head, node) {
+               if (addr < range->start || addr >= range->end)
+                       continue;
+               siglongjmp(lttng_ust_sigbus_state.sj_env, 1);
+       }
+}
+
 int lttng_ust_ctl_release_handle(int sock, int handle)
 {
        struct ustcomm_ust_msg lum;
@@ -248,6 +312,17 @@ int lttng_ust_ctl_create_event(int sock, struct lttng_ust_abi_event *ev,
        return 0;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_CONTEXT command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - send:     var len ctx_name
+ * - receive:  struct ustcomm_ust_reply
+ *
+ * TODO: At the next breaking protocol bump, we should indicate the total
+ * command message length as part of a message header so that the protocol can
+ * recover from invalid command errors.
+ */
 int lttng_ust_ctl_add_context(int sock, struct lttng_ust_context_attr *ctx,
                struct lttng_ust_abi_object_data *obj_data,
                struct lttng_ust_abi_object_data **_context_data)
@@ -319,6 +394,13 @@ int lttng_ust_ctl_add_context(int sock, struct lttng_ust_context_attr *ctx,
        }
        ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
        if (ret < 0) {
+               if (ret == -EINVAL) {
+                       /*
+                        * Command unknown from remote end. The communication socket is
+                        * now out-of-sync and needs to be shutdown.
+                        */
+                       (void) ustcomm_shutdown_unix_sock(sock);
+               }
                goto end;
        }
        context_data->handle = -1;
@@ -331,6 +413,17 @@ end:
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_FILTER command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - send:     var len bytecode
+ * - receive:  struct ustcomm_ust_reply
+ *
+ * TODO: At the next breaking protocol bump, we should indicate the total
+ * command message length as part of a message header so that the protocol can
+ * recover from invalid command errors.
+ */
 int lttng_ust_ctl_set_filter(int sock, struct lttng_ust_abi_filter_bytecode *bytecode,
                struct lttng_ust_abi_object_data *obj_data)
 {
@@ -359,9 +452,25 @@ int lttng_ust_ctl_set_filter(int sock, struct lttng_ust_abi_filter_bytecode *byt
        }
        if (ret != bytecode->len)
                return -EINVAL;
-       return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (ret == -EINVAL) {
+               /*
+                * Command unknown from remote end. The communication socket is
+                * now out-of-sync and needs to be shutdown.
+                */
+               (void) ustcomm_shutdown_unix_sock(sock);
+       }
+       return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_CAPTURE command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     var len bytecode
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *bytecode,
                struct lttng_ust_abi_object_data *obj_data)
 {
@@ -379,7 +488,7 @@ int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *b
        lum.u.capture.reloc_offset = bytecode->reloc_offset;
        lum.u.capture.seqnum = bytecode->seqnum;
 
-       ret = ustcomm_send_app_msg(sock, &lum);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
        /* send var len bytecode */
@@ -393,6 +502,17 @@ int lttng_ust_ctl_set_capture(int sock, struct lttng_ust_abi_capture_bytecode *b
        return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_EXCLUSION command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - send:     var len exclusion names
+ * - receive:  struct ustcomm_ust_reply
+ *
+ * TODO: At the next breaking protocol bump, we should indicate the total
+ * command message length as part of a message header so that the protocol can
+ * recover from invalid command errors.
+ */
 int lttng_ust_ctl_set_exclusion(int sock, struct lttng_ust_abi_event_exclusion *exclusion,
                struct lttng_ust_abi_object_data *obj_data)
 {
@@ -424,7 +544,15 @@ int lttng_ust_ctl_set_exclusion(int sock, struct lttng_ust_abi_event_exclusion *
        if (ret != exclusion->count * LTTNG_UST_ABI_SYM_NAME_LEN) {
                return -EINVAL;
        }
-       return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (ret == -EINVAL) {
+               /*
+                * Command unknown from remote end. The communication socket is
+                * now out-of-sync and needs to be shutdown.
+                */
+               (void) ustcomm_shutdown_unix_sock(sock);
+       }
+       return ret;
 }
 
 /* Enable event, channel and session ioctl */
@@ -483,6 +611,14 @@ int lttng_ust_ctl_stop_session(int sock, int handle)
        return lttng_ust_ctl_disable(sock, &obj);
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     file descriptor
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_create_event_notifier_group(int sock, int pipe_fd,
                struct lttng_ust_abi_object_data **_event_notifier_group_data)
 {
@@ -505,7 +641,7 @@ int lttng_ust_ctl_create_event_notifier_group(int sock, int pipe_fd,
        lum.handle = LTTNG_UST_ABI_ROOT_HANDLE;
        lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE;
 
-       ret = ustcomm_send_app_msg(sock, &lum);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                goto error;
 
@@ -534,6 +670,14 @@ end:
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     struct lttng_ust_abi_event_notifier
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_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)
@@ -558,7 +702,7 @@ int lttng_ust_ctl_create_event_notifier(int sock, struct lttng_ust_abi_event_not
        lum.cmd = LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE;
        lum.u.event_notifier.len = sizeof(*event_notifier);
 
-       ret = ustcomm_send_app_msg(sock, &lum);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret) {
                free(event_notifier_data);
                return ret;
@@ -984,6 +1128,17 @@ error_alloc:
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_CHANNEL command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - send:     file descriptors and channel data
+ * - receive:  struct ustcomm_ust_reply
+ *
+ * TODO: At the next breaking protocol bump, we should indicate the total
+ * command message length as part of a message header so that the protocol can
+ * recover from invalid command errors.
+ */
 int lttng_ust_ctl_send_channel_to_ust(int sock, int session_handle,
                struct lttng_ust_abi_object_data *channel_data)
 {
@@ -1014,10 +1169,27 @@ int lttng_ust_ctl_send_channel_to_ust(int sock, int session_handle,
        ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
        if (!ret) {
                channel_data->handle = lur.ret_val;
+       } else if (ret == -EINVAL) {
+               /*
+                * Command unknown from remote end. The communication socket is
+                * now out-of-sync and needs to be shutdown.
+                */
+               (void) ustcomm_shutdown_unix_sock(sock);
        }
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_STREAM command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - send:     file descriptors and stream data
+ * - receive:  struct ustcomm_ust_reply
+ *
+ * TODO: At the next breaking protocol bump, we should indicate the total
+ * command message length as part of a message header so that the protocol can
+ * recover from invalid command errors.
+ */
 int lttng_ust_ctl_send_stream_to_ust(int sock,
                struct lttng_ust_abi_object_data *channel_data,
                struct lttng_ust_abi_object_data *stream_data)
@@ -1045,7 +1217,15 @@ int lttng_ust_ctl_send_stream_to_ust(int sock,
                        stream_data->u.stream.wakeup_fd, 1);
        if (ret)
                return ret;
-       return ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       ret = ustcomm_recv_app_reply(sock, &lur, lum.handle, lum.cmd);
+       if (ret == -EINVAL) {
+               /*
+                * Command unknown from remote end. The communication socket is
+                * now out-of-sync and needs to be shutdown.
+                */
+               (void) ustcomm_shutdown_unix_sock(sock);
+       }
+       return ret;
 }
 
 int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **dest,
@@ -1077,7 +1257,7 @@ int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **d
                        obj->u.channel.wakeup_fd =
                                dup(src->u.channel.wakeup_fd);
                        if (obj->u.channel.wakeup_fd < 0) {
-                               ret = errno;
+                               ret = -errno;
                                goto chan_error_wakeup_fd;
                        }
                } else {
@@ -1113,7 +1293,7 @@ int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **d
                        obj->u.stream.wakeup_fd =
                                dup(src->u.stream.wakeup_fd);
                        if (obj->u.stream.wakeup_fd < 0) {
-                               ret = errno;
+                               ret = -errno;
                                goto stream_error_wakeup_fd;
                        }
                } else {
@@ -1125,7 +1305,7 @@ int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **d
                        obj->u.stream.shm_fd =
                                dup(src->u.stream.shm_fd);
                        if (obj->u.stream.shm_fd < 0) {
-                               ret = errno;
+                               ret = -errno;
                                goto stream_error_shm_fd;
                        }
                } else {
@@ -1164,7 +1344,7 @@ int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **d
                        obj->u.counter_global.shm_fd =
                                dup(src->u.counter_global.shm_fd);
                        if (obj->u.counter_global.shm_fd < 0) {
-                               ret = errno;
+                               ret = -errno;
                                goto error_type;
                        }
                }
@@ -1178,7 +1358,7 @@ int lttng_ust_ctl_duplicate_ust_object_data(struct lttng_ust_abi_object_data **d
                        obj->u.counter_cpu.shm_fd =
                                dup(src->u.counter_cpu.shm_fd);
                        if (obj->u.counter_cpu.shm_fd < 0) {
-                               ret = errno;
+                               ret = -errno;
                                goto error_type;
                        }
                }
@@ -1204,7 +1384,7 @@ error:
 
 int lttng_ust_ctl_get_nr_stream_per_channel(void)
 {
-       return num_possible_cpus();
+       return get_possible_cpus_array_len();
 }
 
 struct lttng_ust_ctl_consumer_channel *
@@ -1446,6 +1626,7 @@ struct lttng_ust_ctl_consumer_stream *
        struct lttng_ust_ring_buffer_channel *rb_chan;
        int shm_fd, wait_fd, wakeup_fd;
        uint64_t memory_map_size;
+       void *memory_map_addr;
        struct lttng_ust_ring_buffer *buf;
        int ret;
 
@@ -1458,7 +1639,7 @@ struct lttng_ust_ctl_consumer_stream *
 
        buf = channel_get_ring_buffer(&rb_chan->backend.config,
                rb_chan, cpu, handle, &shm_fd, &wait_fd,
-               &wakeup_fd, &memory_map_size);
+               &wakeup_fd, &memory_map_size, &memory_map_addr);
        if (!buf)
                return NULL;
        ret = lib_ring_buffer_open_read(buf, handle);
@@ -1474,6 +1655,7 @@ struct lttng_ust_ctl_consumer_stream *
        stream->wait_fd = wait_fd;
        stream->wakeup_fd = wakeup_fd;
        stream->memory_map_size = memory_map_size;
+       stream->memory_map_addr = memory_map_addr;
        stream->cpu = cpu;
        return stream;
 
@@ -1541,12 +1723,21 @@ void *lttng_ust_ctl_get_mmap_base(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
+       void *p;
 
        if (!stream)
                return NULL;
        buf = stream->buf;
        consumer_chan = stream->chan;
-       return shmp(consumer_chan->chan->priv->rb_chan->handle, buf->backend.memory_map);
+       if (sigbus_begin())
+               return NULL;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       p = shmp(consumer_chan->chan->priv->rb_chan->handle, buf->backend.memory_map);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return p;       /* Users of this pointer should check for sigbus. */
 }
 
 /* returns the length to mmap. */
@@ -1602,6 +1793,8 @@ int lttng_ust_ctl_get_mmap_read_offset(struct lttng_ust_ctl_consumer_stream *str
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
        struct lttng_ust_ring_buffer_backend_pages_shmp *barray_idx;
        struct lttng_ust_ring_buffer_backend_pages *pages;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream)
                return -EINVAL;
@@ -1610,17 +1803,31 @@ int lttng_ust_ctl_get_mmap_read_offset(struct lttng_ust_ctl_consumer_stream *str
        rb_chan = consumer_chan->chan->priv->rb_chan;
        if (rb_chan->backend.config.output != RING_BUFFER_MMAP)
                return -EINVAL;
+
+       if (sigbus_begin())
+               return -EIO;
+       ret = 0;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+
        sb_bindex = subbuffer_id_get_index(&rb_chan->backend.config,
                                        buf->backend.buf_rsb.id);
        barray_idx = shmp_index(rb_chan->handle, buf->backend.array,
                        sb_bindex);
-       if (!barray_idx)
-               return -EINVAL;
+       if (!barray_idx) {
+               ret = -EINVAL;
+               goto end;
+       }
        pages = shmp(rb_chan->handle, barray_idx->shmp);
-       if (!pages)
-               return -EINVAL;
+       if (!pages) {
+               ret = -EINVAL;
+               goto end;
+       }
        *off = pages->mmap_offset;
-       return 0;
+end:
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 /* returns the size of the current sub-buffer, without padding (for mmap). */
@@ -1630,6 +1837,7 @@ int lttng_ust_ctl_get_subbuf_size(struct lttng_ust_ctl_consumer_stream *stream,
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
        struct lttng_ust_ring_buffer_channel *rb_chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
 
        if (!stream)
                return -EINVAL;
@@ -1637,8 +1845,14 @@ int lttng_ust_ctl_get_subbuf_size(struct lttng_ust_ctl_consumer_stream *stream,
        buf = stream->buf;
        consumer_chan = stream->chan;
        rb_chan = consumer_chan->chan->priv->rb_chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        *len = lib_ring_buffer_get_read_data_size(&rb_chan->backend.config, buf,
                rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
        return 0;
 }
 
@@ -1649,15 +1863,22 @@ int lttng_ust_ctl_get_padded_subbuf_size(struct lttng_ust_ctl_consumer_stream *s
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
        struct lttng_ust_ring_buffer_channel *rb_chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
        rb_chan = consumer_chan->chan->priv->rb_chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        *len = lib_ring_buffer_get_read_data_size(&rb_chan->backend.config, buf,
                rb_chan->handle);
        *len = LTTNG_UST_PAGE_ALIGN(*len);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
        return 0;
 }
 
@@ -1666,27 +1887,42 @@ int lttng_ust_ctl_get_next_subbuf(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
-       return lib_ring_buffer_get_next_subbuf(buf,
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = lib_ring_buffer_get_next_subbuf(buf,
                        consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
-
 /* Release exclusive sub-buffer access, move consumer forward. */
 int lttng_ust_ctl_put_next_subbuf(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        lib_ring_buffer_put_next_subbuf(buf, consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
        return 0;
 }
 
@@ -1697,13 +1933,22 @@ int lttng_ust_ctl_snapshot(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
-       return lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = lib_ring_buffer_snapshot(buf, &buf->cons_snapshot,
                        &buf->prod_snapshot, consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 /*
@@ -1715,14 +1960,23 @@ int lttng_ust_ctl_snapshot_sample_positions(struct lttng_ust_ctl_consumer_stream
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
-       return lib_ring_buffer_snapshot_sample_positions(buf,
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = lib_ring_buffer_snapshot_sample_positions(buf,
                        &buf->cons_snapshot, &buf->prod_snapshot,
                        consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 /* Get the consumer position (iteration start) */
@@ -1757,13 +2011,22 @@ int lttng_ust_ctl_get_subbuf(struct lttng_ust_ctl_consumer_stream *stream,
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
-       return lib_ring_buffer_get_subbuf(buf, *pos,
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = lib_ring_buffer_get_subbuf(buf, *pos,
                        consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 /* Release exclusive sub-buffer access */
@@ -1771,40 +2034,63 @@ int lttng_ust_ctl_put_subbuf(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
 
        if (!stream)
                return -EINVAL;
        buf = stream->buf;
        consumer_chan = stream->chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        lib_ring_buffer_put_subbuf(buf, consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
        return 0;
 }
 
-void lttng_ust_ctl_flush_buffer(struct lttng_ust_ctl_consumer_stream *stream,
+int lttng_ust_ctl_flush_buffer(struct lttng_ust_ctl_consumer_stream *stream,
                int producer_active)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
 
        assert(stream);
        buf = stream->buf;
        consumer_chan = stream->chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        lib_ring_buffer_switch_slow(buf,
                producer_active ? SWITCH_ACTIVE : SWITCH_FLUSH,
                consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return 0;
 }
 
-void lttng_ust_ctl_clear_buffer(struct lttng_ust_ctl_consumer_stream *stream)
+int lttng_ust_ctl_clear_buffer(struct lttng_ust_ctl_consumer_stream *stream)
 {
        struct lttng_ust_ring_buffer *buf;
        struct lttng_ust_ctl_consumer_channel *consumer_chan;
+       struct lttng_ust_sigbus_range range;
 
        assert(stream);
        buf = stream->buf;
        consumer_chan = stream->chan;
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
        lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                consumer_chan->chan->priv->rb_chan->handle);
        lib_ring_buffer_clear_reader(buf, consumer_chan->chan->priv->rb_chan->handle);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return 0;
 }
 
 static
@@ -1830,6 +2116,8 @@ int lttng_ust_ctl_get_timestamp_begin(struct lttng_ust_ctl_consumer_stream *stre
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !timestamp_begin)
                return -EINVAL;
@@ -1838,7 +2126,14 @@ int lttng_ust_ctl_get_timestamp_begin(struct lttng_ust_ctl_consumer_stream *stre
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->timestamp_begin(buf, chan, timestamp_begin);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->timestamp_begin(buf, chan, timestamp_begin);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1847,6 +2142,8 @@ int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !timestamp_end)
                return -EINVAL;
@@ -1855,7 +2152,14 @@ int lttng_ust_ctl_get_timestamp_end(struct lttng_ust_ctl_consumer_stream *stream
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->timestamp_end(buf, chan, timestamp_end);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->timestamp_end(buf, chan, timestamp_end);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1864,6 +2168,8 @@ int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *str
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !events_discarded)
                return -EINVAL;
@@ -1872,7 +2178,14 @@ int lttng_ust_ctl_get_events_discarded(struct lttng_ust_ctl_consumer_stream *str
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->events_discarded(buf, chan, events_discarded);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->events_discarded(buf, chan, events_discarded);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1881,6 +2194,8 @@ int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream,
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !content_size)
                return -EINVAL;
@@ -1889,7 +2204,14 @@ int lttng_ust_ctl_get_content_size(struct lttng_ust_ctl_consumer_stream *stream,
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->content_size(buf, chan, content_size);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->content_size(buf, chan, content_size);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1898,6 +2220,8 @@ int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream,
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !packet_size)
                return -EINVAL;
@@ -1906,7 +2230,14 @@ int lttng_ust_ctl_get_packet_size(struct lttng_ust_ctl_consumer_stream *stream,
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->packet_size(buf, chan, packet_size);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->packet_size(buf, chan, packet_size);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1915,6 +2246,8 @@ int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream,
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !stream_id)
                return -EINVAL;
@@ -1923,7 +2256,14 @@ int lttng_ust_ctl_get_stream_id(struct lttng_ust_ctl_consumer_stream *stream,
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->stream_id(buf, chan, stream_id);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->stream_id(buf, chan, stream_id);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1932,6 +2272,8 @@ int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *st
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !ts)
                return -EINVAL;
@@ -1940,7 +2282,14 @@ int lttng_ust_ctl_get_current_timestamp(struct lttng_ust_ctl_consumer_stream *st
        client_cb = get_client_cb(buf, chan);
        if (!client_cb || !client_cb->current_timestamp)
                return -ENOSYS;
-       return client_cb->current_timestamp(buf, chan, ts);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->current_timestamp(buf, chan, ts);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1949,6 +2298,8 @@ int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stre
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !seq)
                return -EINVAL;
@@ -1957,7 +2308,14 @@ int lttng_ust_ctl_get_sequence_number(struct lttng_ust_ctl_consumer_stream *stre
        client_cb = get_client_cb(buf, chan);
        if (!client_cb || !client_cb->sequence_number)
                return -ENOSYS;
-       return client_cb->sequence_number(buf, chan, seq);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->sequence_number(buf, chan, seq);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream,
@@ -1966,6 +2324,8 @@ int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream,
        struct lttng_ust_client_lib_ring_buffer_client_cb *client_cb;
        struct lttng_ust_ring_buffer_channel *chan;
        struct lttng_ust_ring_buffer *buf;
+       struct lttng_ust_sigbus_range range;
+       int ret;
 
        if (!stream || !id)
                return -EINVAL;
@@ -1974,7 +2334,14 @@ int lttng_ust_ctl_get_instance_id(struct lttng_ust_ctl_consumer_stream *stream,
        client_cb = get_client_cb(buf, chan);
        if (!client_cb)
                return -ENOSYS;
-       return client_cb->instance_id(buf, chan, id);
+       if (sigbus_begin())
+               return -EIO;
+       lttng_ust_sigbus_add_range(&range, stream->memory_map_addr,
+                               stream->memory_map_size);
+       ret = client_cb->instance_id(buf, chan, id);
+       lttng_ust_sigbus_del_range(&range);
+       sigbus_end();
+       return ret;
 }
 
 #ifdef HAVE_LINUX_PERF_EVENT_H
@@ -2041,7 +2408,6 @@ int get_cred(int sock,
 /*
  * 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,
@@ -2055,21 +2421,25 @@ int get_cred(int sock,
        socklen_t xucred_len = sizeof(struct xucred);
        int ret;
 
-       ret = getsockopt(sock, SOL_SOCKET, LOCAL_PEERCRED, &xucred, &xucred_len);
+       ret = getsockopt(sock, SOL_LOCAL, 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],
+       DBG("Unix socket peercred [ pid: %u, uid: %u, gid: %u ], "
+               "application registered claiming [ pid: %u, ppid: %u, uid: %u, gid: %u ]",
+               xucred.cr_pid, 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;
+       *pid = xucred.cr_pid;
        *uid = xucred.cr_uid;
        *gid = xucred.cr_groups[0];
+       if (xucred.cr_pid == reg_msg->pid) {
+               *ppid = reg_msg->ppid;
+       } else {
+               *ppid = 0;
+       }
        return 0;
 }
 #else
@@ -2534,7 +2904,7 @@ int lttng_ust_ctl_regenerate_statedump(int sock, int handle)
 
 int lttng_ust_ctl_get_nr_cpu_per_counter(void)
 {
-       return num_possible_cpus();
+       return get_possible_cpus_array_len();
 }
 
 struct lttng_ust_ctl_daemon_counter *
@@ -2762,6 +3132,14 @@ void lttng_ust_ctl_destroy_counter(struct lttng_ust_ctl_daemon_counter *counter)
        free(counter);
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_COUNTER command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     counter data
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle,
                struct lttng_ust_abi_object_data *counter_data)
 {
@@ -2779,7 +3157,7 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle,
        lum.handle = parent_handle;
        lum.cmd = LTTNG_UST_ABI_COUNTER;
        lum.u.counter.len = size;
-       ret = ustcomm_send_app_msg(sock, &lum);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
 
@@ -2799,6 +3177,14 @@ int lttng_ust_ctl_send_counter_data_to_ust(int sock, int parent_handle,
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_COUNTER_GLOBAL command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     file descriptor
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_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)
@@ -2817,7 +3203,7 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock,
        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);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
 
@@ -2837,6 +3223,14 @@ int lttng_ust_ctl_send_counter_global_data_to_ust(int sock,
        return ret;
 }
 
+/*
+ * Protocol for LTTNG_UST_ABI_COUNTER_CPU command:
+ *
+ * - send:     struct ustcomm_ust_msg
+ * - receive:  struct ustcomm_ust_reply
+ * - send:     file descriptor
+ * - receive:  struct ustcomm_ust_reply (actual command return code)
+ */
 int lttng_ust_ctl_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)
@@ -2856,7 +3250,7 @@ int lttng_ust_ctl_send_counter_cpu_data_to_ust(int sock,
        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);
+       ret = ustcomm_send_app_cmd(sock, &lum, &lur);
        if (ret)
                return ret;
 
This page took 0.03498 seconds and 4 git commands to generate.