Use compiler-agnostic defines to silence warning
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.cpp
index b4b8dab278caa8235e373d0f7b69aacacd062504..5d6a349ea413c3343aafe68f313d25c2170b3138 100644 (file)
@@ -16,7 +16,6 @@
 #include "lttng-syscall.hpp"
 #include "modprobe.hpp"
 #include "notification-thread-commands.hpp"
-#include "rotate.hpp"
 #include "sessiond-config.hpp"
 #include "tracker.hpp"
 #include "utils.hpp"
 #include <common/hashtable/utils.hpp>
 #include <common/kernel-ctl/kernel-ctl.hpp>
 #include <common/kernel-ctl/kernel-ioctl.hpp>
+#include <common/scope-exit.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
 #include <common/trace-chunk.hpp>
 #include <common/tracker.hpp>
+#include <common/urcu.hpp>
 #include <common/utils.hpp>
 
 #include <lttng/condition/event-rule-matches-internal.hpp>
 #include <sys/types.h>
 #include <unistd.h>
 
+namespace {
 /*
  * Key used to reference a channel between the sessiond and the consumer. This
  * is only read and updated with the session_list lock held.
  */
-static uint64_t next_kernel_channel_key;
+uint64_t next_kernel_channel_key;
 
-static const char *module_proc_lttng = "/proc/lttng";
+const char *module_proc_lttng = "/proc/lttng";
 
-static int kernel_tracer_fd = -1;
-static int kernel_tracer_event_notifier_group_fd = -1;
-static int kernel_tracer_event_notifier_group_notification_fd = -1;
-static struct cds_lfht *kernel_token_to_event_notifier_rule_ht;
+int kernel_tracer_fd = -1;
+nonstd::optional<enum lttng_kernel_tracer_status> kernel_tracer_status = nonstd::nullopt;
+int kernel_tracer_event_notifier_group_fd = -1;
+int kernel_tracer_event_notifier_group_notification_fd = -1;
+struct cds_lfht *kernel_token_to_event_notifier_rule_ht;
+
+const char *kernel_tracer_status_to_str(lttng_kernel_tracer_status status)
+{
+       switch (status) {
+       case LTTNG_KERNEL_TRACER_STATUS_INITIALIZED:
+               return "LTTNG_KERNEL_TRACER_STATUS_INITIALIZED";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_UNKNOWN:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_UNKNOWN";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_NEED_ROOT:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_NEED_ROOT";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_OPEN_PROC_LTTNG:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_OPEN_PROC_LTTNG";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_VERSION_MISMATCH:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_VERSION_MISMATCH";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_UNKNOWN:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_UNKNOWN";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_MISSING:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_MISSING";
+       case LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_SIGNATURE:
+               return "LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_SIGNATURE";
+       }
+
+       abort();
+}
+
+/*
+ * On some architectures, calling convention details are embedded in the symbol
+ * addresses. Uprobe requires a "clean" symbol offset (or at least, an address
+ * where an instruction boundary would be legal) to add
+ * instrumentation. sanitize_uprobe_offset implements that sanitization logic on
+ * a per-architecture basis.
+ */
+#if defined(__arm__) || defined(__aarch64__)
+static inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
+{
+       /*
+        * The least significant bit is used when branching to switch to thumb
+        * ISA. However, it's an invalid address for us; mask the least
+        * significant bit.
+        */
+       return raw_offset &= ~0b1;
+}
+#else /* defined(__arm__) || defined(__aarch64__) */
+inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
+{
+       return raw_offset;
+}
+#endif
+} /* namespace */
 
 /*
  * Add context on a kernel channel.
@@ -97,7 +151,7 @@ int kernel_add_channel_context(struct ltt_kernel_channel *chan, struct ltt_kerne
 end:
        cds_list_add_tail(&ctx->list, &chan->ctx_list);
        ctx->in_list = true;
-       ctx = NULL;
+       ctx = nullptr;
 error:
        if (ctx) {
                trace_kernel_destroy_context(ctx);
@@ -109,16 +163,14 @@ error:
  * Create a new kernel session, register it to the kernel tracer and add it to
  * the session daemon session.
  */
-int kernel_create_session(struct ltt_session *session)
+int kernel_create_session(const ltt_session::locked_ref& session)
 {
        int ret;
        struct ltt_kernel_session *lks;
 
-       LTTNG_ASSERT(session);
-
        /* Allocate data structure */
        lks = trace_kernel_create_session();
-       if (lks == NULL) {
+       if (lks == nullptr) {
                ret = -1;
                goto error;
        }
@@ -189,7 +241,7 @@ int kernel_create_channel(struct ltt_kernel_session *session, struct lttng_chann
 
        /* Allocate kernel channel */
        lkc = trace_kernel_create_channel(chan);
-       if (lkc == NULL) {
+       if (lkc == nullptr) {
                goto error;
        }
 
@@ -300,8 +352,8 @@ static int extract_userspace_probe_offset_function_elf(
 {
        int fd;
        int ret = 0;
-       const char *symbol = NULL;
-       const struct lttng_userspace_probe_location_lookup_method *lookup = NULL;
+       const char *symbol = nullptr;
+       const struct lttng_userspace_probe_location_lookup_method *lookup = nullptr;
        enum lttng_userspace_probe_location_lookup_method_type lookup_method_type;
 
        LTTNG_ASSERT(lttng_userspace_probe_location_get_type(probe_location) ==
@@ -360,8 +412,8 @@ static int extract_userspace_probe_offset_tracepoint_sdt(
        uint32_t *offsets_count)
 {
        enum lttng_userspace_probe_location_lookup_method_type lookup_method_type;
-       const struct lttng_userspace_probe_location_lookup_method *lookup = NULL;
-       const char *probe_name = NULL, *provider_name = NULL;
+       const struct lttng_userspace_probe_location_lookup_method *lookup = nullptr;
+       const char *probe_name = nullptr, *provider_name = nullptr;
        int ret = 0;
        int fd, i;
 
@@ -428,7 +480,7 @@ static int userspace_probe_add_callsite(const struct lttng_userspace_probe_locat
                                        gid_t gid,
                                        int fd)
 {
-       const struct lttng_userspace_probe_location_lookup_method *lookup_method = NULL;
+       const struct lttng_userspace_probe_location_lookup_method *lookup_method = nullptr;
        enum lttng_userspace_probe_location_lookup_method_type type;
        int ret;
 
@@ -451,7 +503,7 @@ static int userspace_probe_add_callsite(const struct lttng_userspace_probe_locat
                        goto end;
                }
 
-               callsite.u.uprobe.offset = offset;
+               callsite.u.uprobe.offset = sanitize_uprobe_offset(offset);
                ret = kernctl_add_callsite(fd, &callsite);
                if (ret) {
                        WARN("Failed to add callsite to ELF userspace probe.");
@@ -463,7 +515,7 @@ static int userspace_probe_add_callsite(const struct lttng_userspace_probe_locat
        case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
        {
                int i;
-               uint64_t *offsets = NULL;
+               uint64_t *offsets = nullptr;
                uint32_t offsets_count;
                struct lttng_kernel_abi_event_callsite callsite;
 
@@ -478,7 +530,7 @@ static int userspace_probe_add_callsite(const struct lttng_userspace_probe_locat
                        goto end;
                }
                for (i = 0; i < offsets_count; i++) {
-                       callsite.u.uprobe.offset = offsets[i];
+                       callsite.u.uprobe.offset = sanitize_uprobe_offset(offsets[i]);
                        ret = kernctl_add_callsite(fd, &callsite);
                        if (ret) {
                                WARN("Failed to add callsite to SDT userspace probe");
@@ -507,7 +559,7 @@ static int userspace_probe_event_add_callsites(struct lttng_event *ev,
                                               int fd)
 {
        int ret;
-       const struct lttng_userspace_probe_location *location = NULL;
+       const struct lttng_userspace_probe_location *location = nullptr;
 
        LTTNG_ASSERT(ev);
        LTTNG_ASSERT(ev->type == LTTNG_EVENT_USERSPACE_PROBE);
@@ -538,7 +590,7 @@ static int userspace_probe_event_rule_add_callsites(const struct lttng_event_rul
        int ret;
        enum lttng_event_rule_status status;
        enum lttng_event_rule_type event_rule_type;
-       const struct lttng_userspace_probe_location *location = NULL;
+       const struct lttng_userspace_probe_location *location = nullptr;
 
        LTTNG_ASSERT(rule);
        LTTNG_ASSERT(creds);
@@ -691,7 +743,7 @@ int kernel_disable_channel(struct ltt_kernel_channel *chan)
                goto error;
        }
 
-       chan->enabled = 0;
+       chan->enabled = false;
        DBG("Kernel channel %s disabled (fd: %d, key: %" PRIu64 ")",
            chan->channel->name,
            chan->fd,
@@ -718,7 +770,7 @@ int kernel_enable_channel(struct ltt_kernel_channel *chan)
                goto error;
        }
 
-       chan->enabled = 1;
+       chan->enabled = true;
        DBG("Kernel channel %s enabled (fd: %d, key: %" PRIu64 ")",
            chan->channel->name,
            chan->fd,
@@ -752,7 +804,7 @@ int kernel_enable_event(struct ltt_kernel_event *event)
                goto error;
        }
 
-       event->enabled = 1;
+       event->enabled = true;
        DBG("Kernel event %s enabled (fd: %d)", event->event->name, event->fd);
 
        return 0;
@@ -778,7 +830,7 @@ int kernel_disable_event(struct ltt_kernel_event *event)
                goto error;
        }
 
-       event->enabled = 0;
+       event->enabled = false;
        DBG("Kernel event %s disabled (fd: %d)", event->event->name, event->fd);
 
        return 0;
@@ -796,9 +848,8 @@ static int kernel_disable_event_notifier_rule(struct ltt_kernel_event_notifier_r
 
        LTTNG_ASSERT(event);
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
        cds_lfht_del(kernel_token_to_event_notifier_rule_ht, &event->ht_node);
-       rcu_read_unlock();
 
        ret = kernctl_disable(event->fd);
        if (ret < 0) {
@@ -808,7 +859,7 @@ static int kernel_disable_event_notifier_rule(struct ltt_kernel_event_notifier_r
                goto error;
        }
 
-       event->enabled = 0;
+       event->enabled = false;
        DBG("Disabled kernel event notifier: fd = %d, token = %" PRIu64, event->fd, event->token);
 
 error:
@@ -833,7 +884,7 @@ _kernel_get_process_attr_tracker(struct ltt_kernel_session *session,
        case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
                return session->tracker_vgid;
        default:
-               return NULL;
+               return nullptr;
        }
 }
 
@@ -1180,13 +1231,13 @@ end:
 int kernel_open_metadata(struct ltt_kernel_session *session)
 {
        int ret;
-       struct ltt_kernel_metadata *lkm = NULL;
+       struct ltt_kernel_metadata *lkm = nullptr;
 
        LTTNG_ASSERT(session);
 
        /* Allocate kernel metadata */
        lkm = trace_kernel_create_metadata();
-       if (lkm == NULL) {
+       if (lkm == nullptr) {
                goto error;
        }
 
@@ -1242,10 +1293,10 @@ error:
 /*
  * Make a kernel wait to make sure in-flight probe have completed.
  */
-void kernel_wait_quiescent(void)
+void kernel_wait_quiescent()
 {
        int ret;
-       int fd = kernel_tracer_fd;
+       const int fd = kernel_tracer_fd;
 
        DBG("Kernel quiescent wait on %d", fd);
 
@@ -1338,7 +1389,7 @@ int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
 
        while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
                lks = trace_kernel_create_stream(channel->channel->name, channel->stream_count);
-               if (lks == NULL) {
+               if (lks == nullptr) {
                        ret = close(ret);
                        if (ret) {
                                PERROR("close");
@@ -1418,7 +1469,7 @@ ssize_t kernel_list_events(struct lttng_event **events)
        }
 
        fp = fdopen(fd, "r");
-       if (fp == NULL) {
+       if (fp == nullptr) {
                PERROR("kernel tracepoint list fdopen");
                goto error_fp;
        }
@@ -1429,7 +1480,7 @@ ssize_t kernel_list_events(struct lttng_event **events)
         */
        nbmem = KERNEL_EVENT_INIT_LIST_SIZE;
        elist = calloc<lttng_event>(nbmem);
-       if (elist == NULL) {
+       if (elist == nullptr) {
                PERROR("alloc list events");
                count = -ENOMEM;
                goto end;
@@ -1444,7 +1495,7 @@ ssize_t kernel_list_events(struct lttng_event **events)
                        DBG("Reallocating event list from %zu to %zu bytes", nbmem, new_nbmem);
                        new_elist = (lttng_event *) realloc(elist,
                                                            new_nbmem * sizeof(struct lttng_event));
-                       if (new_elist == NULL) {
+                       if (new_elist == nullptr) {
                                PERROR("realloc list events");
                                free(event);
                                free(elist);
@@ -1534,7 +1585,7 @@ error:
 /*
  * Kernel work-arounds called at the start of sessiond main().
  */
-int init_kernel_workarounds(void)
+int init_kernel_workarounds()
 {
        int ret;
        FILE *fp;
@@ -1571,7 +1622,7 @@ void kernel_destroy_session(struct ltt_kernel_session *ksess)
 {
        struct lttng_trace_chunk *trace_chunk;
 
-       if (ksess == NULL) {
+       if (ksess == nullptr) {
                DBG3("No kernel session when tearing down session");
                return;
        }
@@ -1585,26 +1636,22 @@ void kernel_destroy_session(struct ltt_kernel_session *ksess)
         * have to send a command to clean them up or else they leaked.
         */
        if (!ksess->output_traces && ksess->consumer_fds_sent) {
-               int ret;
-               struct consumer_socket *socket;
-               struct lttng_ht_iter iter;
-
-               /* For each consumer socket. */
-               rcu_read_lock();
-               cds_lfht_for_each_entry (
-                       ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
+               for (auto *socket :
+                    lttng::urcu::lfht_iteration_adapter<consumer_socket,
+                                                        decltype(consumer_socket::node),
+                                                        &consumer_socket::node>(
+                            *ksess->consumer->socks->ht)) {
                        struct ltt_kernel_channel *chan;
 
                        /* For each channel, ask the consumer to destroy it. */
                        cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
-                               ret = kernel_consumer_destroy_channel(socket, chan);
+                               const auto ret = kernel_consumer_destroy_channel(socket, chan);
                                if (ret < 0) {
                                        /* Consumer is probably dead. Use next socket. */
                                        continue;
                                }
                        }
                }
-               rcu_read_unlock();
        }
 
        /* Close any relayd session */
@@ -1617,7 +1664,7 @@ void kernel_destroy_session(struct ltt_kernel_session *ksess)
 /* Teardown of data required by destroy notifiers. */
 void kernel_free_session(struct ltt_kernel_session *ksess)
 {
-       if (ksess == NULL) {
+       if (ksess == nullptr) {
                return;
        }
        trace_kernel_free_session(ksess);
@@ -1628,7 +1675,7 @@ void kernel_free_session(struct ltt_kernel_session *ksess)
  */
 void kernel_destroy_channel(struct ltt_kernel_channel *kchan)
 {
-       struct ltt_kernel_session *ksess = NULL;
+       struct ltt_kernel_session *ksess = nullptr;
 
        LTTNG_ASSERT(kchan);
        LTTNG_ASSERT(kchan->channel);
@@ -1664,10 +1711,8 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
 {
        int err, ret, saved_metadata_fd;
        enum lttng_error_code status = LTTNG_OK;
-       struct consumer_socket *socket;
-       struct lttng_ht_iter iter;
        struct ltt_kernel_metadata *saved_metadata;
-       char *trace_path = NULL;
+       char *trace_path = nullptr;
        size_t consumer_path_offset = 0;
 
        LTTNG_ASSERT(ksess);
@@ -1680,8 +1725,6 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
        saved_metadata = ksess->metadata;
        saved_metadata_fd = ksess->metadata_stream_fd;
 
-       rcu_read_lock();
-
        ret = kernel_open_metadata(ksess);
        if (ret < 0) {
                status = LTTNG_ERR_KERN_META_FAIL;
@@ -1699,8 +1742,11 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
                status = LTTNG_ERR_INVALID;
                goto error;
        }
-       /* Send metadata to consumer and snapshot everything. */
-       cds_lfht_for_each_entry (output->socks->ht, &iter.iter, socket, node.node) {
+
+       for (auto *socket :
+            lttng::urcu::lfht_iteration_adapter<consumer_socket,
+                                                decltype(consumer_socket::node),
+                                                &consumer_socket::node>(*output->socks->ht)) {
                struct ltt_kernel_channel *chan;
 
                pthread_mutex_lock(socket->lock);
@@ -1757,7 +1803,6 @@ error:
        /* Restore metadata state.*/
        ksess->metadata = saved_metadata;
        ksess->metadata_stream_fd = saved_metadata_fd;
-       rcu_read_unlock();
        free(trace_path);
        return status;
 }
@@ -1799,7 +1844,7 @@ error:
  * Return 1 on success, 0 when feature is not supported, negative value in case
  * of errors.
  */
-int kernel_supports_ring_buffer_snapshot_sample_positions(void)
+int kernel_supports_ring_buffer_snapshot_sample_positions()
 {
        /*
         * RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS was introduced in 2.3
@@ -1813,7 +1858,7 @@ int kernel_supports_ring_buffer_snapshot_sample_positions(void)
  * Return 1 on success, 0 when feature is not supported, negative value in case
  * of errors.
  */
-int kernel_supports_ring_buffer_packet_sequence_number(void)
+int kernel_supports_ring_buffer_packet_sequence_number()
 {
        /*
         * Packet sequence number was introduced in LTTng 2.8,
@@ -1828,7 +1873,7 @@ int kernel_supports_ring_buffer_packet_sequence_number(void)
  * Return 1 on success, 0 when feature is not supported, negative value in case
  * of errors.
  */
-int kernel_supports_event_notifiers(void)
+int kernel_supports_event_notifiers()
 {
        /*
         * Event notifiers were introduced in LTTng 2.13, lttng-modules ABI 2.6.
@@ -1841,12 +1886,10 @@ int kernel_supports_event_notifiers(void)
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code kernel_rotate_session(struct ltt_session *session)
+enum lttng_error_code kernel_rotate_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code status = LTTNG_OK;
-       struct consumer_socket *socket;
-       struct lttng_ht_iter iter;
        struct ltt_kernel_session *ksess = session->kernel_session;
 
        LTTNG_ASSERT(ksess);
@@ -1854,13 +1897,14 @@ enum lttng_error_code kernel_rotate_session(struct ltt_session *session)
 
        DBG("Rotate kernel session %s started (session %" PRIu64 ")", session->name, session->id);
 
-       rcu_read_lock();
-
        /*
         * Note that this loop will end after one iteration given that there is
         * only one kernel consumer.
         */
-       cds_lfht_for_each_entry (ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
+       for (auto *socket : lttng::urcu::lfht_iteration_adapter<consumer_socket,
+                                                               decltype(consumer_socket::node),
+                                                               &consumer_socket::node>(
+                    *ksess->consumer->socks->ht)) {
                struct ltt_kernel_channel *chan;
 
                /* For each channel, ask the consumer to rotate it. */
@@ -1892,7 +1936,6 @@ enum lttng_error_code kernel_rotate_session(struct ltt_session *session)
        }
 
 error:
-       rcu_read_unlock();
        return status;
 }
 
@@ -1901,7 +1944,7 @@ enum lttng_error_code kernel_create_channel_subdirectories(const struct ltt_kern
        enum lttng_error_code ret = LTTNG_OK;
        enum lttng_trace_chunk_status chunk_status;
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
        LTTNG_ASSERT(ksess->current_trace_chunk);
 
        /*
@@ -1915,21 +1958,68 @@ enum lttng_error_code kernel_create_channel_subdirectories(const struct ltt_kern
                goto error;
        }
 error:
-       rcu_read_unlock();
        return ret;
 }
 
+/*
+ * Get current kernel tracer status
+ */
+enum lttng_kernel_tracer_status get_kernel_tracer_status()
+{
+       if (!kernel_tracer_status) {
+               return LTTNG_KERNEL_TRACER_STATUS_ERR_UNKNOWN;
+       }
+
+       return *kernel_tracer_status;
+}
+
+/*
+ * Sets the kernel tracer status based on the positive errno code
+ */
+void set_kernel_tracer_status_from_modules_ret(int code)
+{
+       switch (code) {
+       case ENOENT:
+       {
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_MISSING);
+               break;
+       }
+       case ENOKEY:
+       case EKEYEXPIRED:
+       case EKEYREVOKED:
+       case EKEYREJECTED:
+       {
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_SIGNATURE);
+               break;
+       }
+       default:
+       {
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_MODULES_UNKNOWN);
+               break;
+       }
+       }
+}
+
 /*
  * Setup necessary data for kernel tracer action.
  */
-int init_kernel_tracer(void)
+int init_kernel_tracer()
 {
        int ret;
-       bool is_root = !getuid();
+       const bool is_root = !getuid();
+
+       const auto log_status_on_exit = lttng::make_scope_exit([]() noexcept {
+               DBG_FMT("Kernel tracer status set to `{}`",
+                       kernel_tracer_status_to_str(*kernel_tracer_status));
+       });
 
        /* Modprobe lttng kernel modules */
        ret = modprobe_lttng_control();
        if (ret < 0) {
+               set_kernel_tracer_status_from_modules_ret(-ret);
                goto error;
        }
 
@@ -1937,17 +2027,22 @@ int init_kernel_tracer(void)
        kernel_tracer_fd = open(module_proc_lttng, O_RDWR);
        if (kernel_tracer_fd < 0) {
                DBG("Failed to open %s", module_proc_lttng);
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_OPEN_PROC_LTTNG);
                goto error_open;
        }
 
        /* Validate kernel version */
        ret = kernel_validate_version(&the_kernel_tracer_version, &the_kernel_tracer_abi_version);
        if (ret < 0) {
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_VERSION_MISMATCH);
                goto error_version;
        }
 
        ret = modprobe_lttng_data();
        if (ret < 0) {
+               set_kernel_tracer_status_from_modules_ret(-ret);
                goto error_modules;
        }
 
@@ -1964,6 +2059,8 @@ int init_kernel_tracer(void)
        ret = kernel_supports_event_notifiers();
        if (ret < 0) {
                ERR("Failed to check for kernel tracer event notifier support");
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER);
                goto error_modules;
        }
        ret = kernel_create_event_notifier_group(&kernel_tracer_event_notifier_group_fd);
@@ -1978,6 +2075,8 @@ int init_kernel_tracer(void)
                                &kernel_tracer_event_notifier_group_notification_fd);
 
                if (error_code_ret != LTTNG_OK) {
+                       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                               LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER);
                        goto error_modules;
                }
 
@@ -1986,12 +2085,16 @@ int init_kernel_tracer(void)
                if (error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
                        ERR("Failed to initialize event notifier error accounting for kernel tracer");
                        error_code_ret = LTTNG_ERR_EVENT_NOTIFIER_ERROR_ACCOUNTING;
+                       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                               LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER);
                        goto error_modules;
                }
 
                kernel_token_to_event_notifier_rule_ht = cds_lfht_new(
-                       DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+                       DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
                if (!kernel_token_to_event_notifier_rule_ht) {
+                       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                               LTTNG_KERNEL_TRACER_STATUS_ERR_NOTIFIER);
                        goto error_token_ht;
                }
        }
@@ -2007,6 +2110,8 @@ int init_kernel_tracer(void)
                    "work for this session daemon.");
        }
 
+       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+               LTTNG_KERNEL_TRACER_STATUS_INITIALIZED);
        return 0;
 
 error_version:
@@ -2051,13 +2156,15 @@ error:
        WARN("No kernel tracer available");
        kernel_tracer_fd = -1;
        if (!is_root) {
+               kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+                       LTTNG_KERNEL_TRACER_STATUS_ERR_NEED_ROOT);
                return LTTNG_ERR_NEED_ROOT_SESSIOND;
        } else {
                return LTTNG_ERR_KERN_NA;
        }
 }
 
-void cleanup_kernel_tracer(void)
+void cleanup_kernel_tracer()
 {
        DBG2("Closing kernel event notifier group notification file descriptor");
        if (kernel_tracer_event_notifier_group_notification_fd >= 0) {
@@ -2078,7 +2185,7 @@ void cleanup_kernel_tracer(void)
        }
 
        if (kernel_token_to_event_notifier_rule_ht) {
-               const int ret = cds_lfht_destroy(kernel_token_to_event_notifier_rule_ht, NULL);
+               const int ret = cds_lfht_destroy(kernel_token_to_event_notifier_rule_ht, nullptr);
                LTTNG_ASSERT(ret == 0);
        }
 
@@ -2106,10 +2213,10 @@ void cleanup_kernel_tracer(void)
                kernel_tracer_fd = -1;
        }
 
-       free(syscall_table);
+       kernel_tracer_status = nonstd::nullopt;
 }
 
-bool kernel_tracer_is_initialized(void)
+bool kernel_tracer_is_initialized()
 {
        return kernel_tracer_fd >= 0;
 }
@@ -2119,12 +2226,10 @@ bool kernel_tracer_is_initialized(void)
  *
  * Return LTTNG_OK on success or else an LTTng error code.
  */
-enum lttng_error_code kernel_clear_session(struct ltt_session *session)
+enum lttng_error_code kernel_clear_session(const ltt_session::locked_ref& session)
 {
        int ret;
        enum lttng_error_code status = LTTNG_OK;
-       struct consumer_socket *socket;
-       struct lttng_ht_iter iter;
        struct ltt_kernel_session *ksess = session->kernel_session;
 
        LTTNG_ASSERT(ksess);
@@ -2132,8 +2237,6 @@ enum lttng_error_code kernel_clear_session(struct ltt_session *session)
 
        DBG("Clear kernel session %s (session %" PRIu64 ")", session->name, session->id);
 
-       rcu_read_lock();
-
        if (ksess->active) {
                ERR("Expecting inactive session %s (%" PRIu64 ")", session->name, session->id);
                status = LTTNG_ERR_FATAL;
@@ -2144,7 +2247,10 @@ enum lttng_error_code kernel_clear_session(struct ltt_session *session)
         * Note that this loop will end after one iteration given that there is
         * only one kernel consumer.
         */
-       cds_lfht_for_each_entry (ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
+       for (auto *socket : lttng::urcu::lfht_iteration_adapter<consumer_socket,
+                                                               decltype(consumer_socket::node),
+                                                               &consumer_socket::node>(
+                    *ksess->consumer->socks->ht)) {
                struct ltt_kernel_channel *chan;
 
                /* For each channel, ask the consumer to clear it. */
@@ -2189,7 +2295,6 @@ error:
                break;
        }
 end:
-       rcu_read_unlock();
        return status;
 }
 
@@ -2240,7 +2345,7 @@ error:
 enum lttng_error_code
 kernel_destroy_event_notifier_group_notification_fd(int event_notifier_group_notification_fd)
 {
-       enum lttng_error_code ret_code = LTTNG_OK;
+       const lttng_error_code ret_code = LTTNG_OK;
 
        DBG("Closing event notifier group notification file descriptor: fd = %d",
            event_notifier_group_notification_fd);
@@ -2284,8 +2389,8 @@ static enum lttng_error_code kernel_create_event_notifier_rule(
        struct ltt_kernel_event_notifier_rule *event_notifier_rule;
        struct lttng_kernel_abi_event_notifier kernel_event_notifier = {};
        unsigned int capture_bytecode_count = 0, i;
-       const struct lttng_condition *condition = NULL;
-       const struct lttng_event_rule *event_rule = NULL;
+       const struct lttng_condition *condition = nullptr;
+       const struct lttng_event_rule *event_rule = nullptr;
        enum lttng_condition_status cond_status;
 
        LTTNG_ASSERT(trigger);
@@ -2392,7 +2497,7 @@ static enum lttng_error_code kernel_create_event_notifier_rule(
                        lttng_condition_event_rule_matches_get_capture_bytecode_at_index(condition,
                                                                                         i);
 
-               if (capture_bytecode == NULL) {
+               if (capture_bytecode == nullptr) {
                        ERR("Unexpected NULL capture bytecode on condition");
                        error_code_ret = LTTNG_ERR_KERN_ENABLE_FAIL;
                        goto capture_error;
@@ -2422,11 +2527,12 @@ static enum lttng_error_code kernel_create_event_notifier_rule(
        }
 
        /* Add trigger to kernel token mapping in the hash table. */
-       rcu_read_lock();
-       cds_lfht_add(kernel_token_to_event_notifier_rule_ht,
-                    hash_trigger(trigger),
-                    &event_notifier_rule->ht_node);
-       rcu_read_unlock();
+       {
+               const lttng::urcu::read_lock_guard read_lock;
+               cds_lfht_add(kernel_token_to_event_notifier_rule_ht,
+                            hash_trigger(trigger),
+                            &event_notifier_rule->ht_node);
+       }
 
        DBG("Created kernel event notifier: name = '%s', fd = %d",
            kernel_event_notifier.event.name,
@@ -2488,7 +2594,7 @@ enum lttng_error_code kernel_unregister_event_notifier(const struct lttng_trigge
        enum lttng_error_code error_code_ret;
        int ret;
 
-       rcu_read_lock();
+       const lttng::urcu::read_lock_guard read_lock;
 
        cds_lfht_lookup(kernel_token_to_event_notifier_rule_ht,
                        hash_trigger(trigger),
@@ -2515,12 +2621,11 @@ enum lttng_error_code kernel_unregister_event_notifier(const struct lttng_trigge
        error_code_ret = LTTNG_OK;
 
 error:
-       rcu_read_unlock();
 
        return error_code_ret;
 }
 
-int kernel_get_notification_fd(void)
+int kernel_get_notification_fd()
 {
        return kernel_tracer_event_notifier_group_notification_fd;
 }
This page took 0.036893 seconds and 4 git commands to generate.