Use compiler-agnostic defines to silence warning
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.cpp
index 1bb8f80b8853d4599926981d7149bceccea25fb8..5d6a349ea413c3343aafe68f313d25c2170b3138 100644 (file)
@@ -24,6 +24,7 @@
 #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 <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.
+ */
+uint64_t next_kernel_channel_key;
+
+const char *module_proc_lttng = "/proc/lttng";
+
+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
@@ -68,25 +109,11 @@ static inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
        return raw_offset &= ~0b1;
 }
 #else /* defined(__arm__) || defined(__aarch64__) */
-static inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
+inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
 {
        return raw_offset;
 }
 #endif
-
-/*
- * Key used to reference a channel between the sessiond and the consumer. This
- * is only read and updated with the session_list lock held.
- */
-uint64_t next_kernel_channel_key;
-
-const char *module_proc_lttng = "/proc/lttng";
-
-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;
 } /* namespace */
 
 /*
@@ -136,13 +163,11 @@ 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 == nullptr) {
@@ -823,7 +848,7 @@ static int kernel_disable_event_notifier_rule(struct ltt_kernel_event_notifier_r
 
        LTTNG_ASSERT(event);
 
-       lttng::urcu::read_lock_guard read_lock;
+       const lttng::urcu::read_lock_guard read_lock;
        cds_lfht_del(kernel_token_to_event_notifier_rule_ht, &event->ht_node);
 
        ret = kernctl_disable(event->fd);
@@ -1271,7 +1296,7 @@ error:
 void kernel_wait_quiescent()
 {
        int ret;
-       int fd = kernel_tracer_fd;
+       const int fd = kernel_tracer_fd;
 
        DBG("Kernel quiescent wait on %d", fd);
 
@@ -1611,20 +1636,16 @@ 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. */
-               lttng::urcu::read_lock_guard 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;
@@ -1690,8 +1711,6 @@ 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 = nullptr;
        size_t consumer_path_offset = 0;
@@ -1724,55 +1743,51 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
                goto error;
        }
 
-       {
-               /* Send metadata to consumer and snapshot everything. */
-               lttng::urcu::read_lock_guard read_lock;
-
-               cds_lfht_for_each_entry (output->socks->ht, &iter.iter, socket, node.node) {
-                       struct ltt_kernel_channel *chan;
+       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);
-                       /* This stream must not be monitored by the consumer. */
-                       ret = kernel_consumer_add_metadata(socket, ksess, 0);
-                       pthread_mutex_unlock(socket->lock);
-                       if (ret < 0) {
-                               status = LTTNG_ERR_KERN_META_FAIL;
-                               goto error_consumer;
-                       }
-
-                       /* For each channel, ask the consumer to snapshot it. */
-                       cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
-                               status =
-                                       consumer_snapshot_channel(socket,
-                                                                 chan->key,
-                                                                 output,
-                                                                 0,
-                                                                 &trace_path[consumer_path_offset],
-                                                                 nb_packets_per_stream);
-                               if (status != LTTNG_OK) {
-                                       (void) kernel_consumer_destroy_metadata(socket,
-                                                                               ksess->metadata);
-                                       goto error_consumer;
-                               }
-                       }
+               pthread_mutex_lock(socket->lock);
+               /* This stream must not be monitored by the consumer. */
+               ret = kernel_consumer_add_metadata(socket, ksess, 0);
+               pthread_mutex_unlock(socket->lock);
+               if (ret < 0) {
+                       status = LTTNG_ERR_KERN_META_FAIL;
+                       goto error_consumer;
+               }
 
-                       /* Snapshot metadata, */
+               /* For each channel, ask the consumer to snapshot it. */
+               cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
                        status = consumer_snapshot_channel(socket,
-                                                          ksess->metadata->key,
+                                                          chan->key,
                                                           output,
-                                                          1,
+                                                          0,
                                                           &trace_path[consumer_path_offset],
-                                                          0);
+                                                          nb_packets_per_stream);
                        if (status != LTTNG_OK) {
+                               (void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
                                goto error_consumer;
                        }
+               }
 
-                       /*
-                        * The metadata snapshot is done, ask the consumer to destroy it since
-                        * it's not monitored on the consumer side.
-                        */
-                       (void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
+               /* Snapshot metadata, */
+               status = consumer_snapshot_channel(socket,
+                                                  ksess->metadata->key,
+                                                  output,
+                                                  1,
+                                                  &trace_path[consumer_path_offset],
+                                                  0);
+               if (status != LTTNG_OK) {
+                       goto error_consumer;
                }
+
+               /*
+                * The metadata snapshot is done, ask the consumer to destroy it since
+                * it's not monitored on the consumer side.
+                */
+               (void) kernel_consumer_destroy_metadata(socket, ksess->metadata);
        }
 
 error_consumer:
@@ -1871,12 +1886,10 @@ int kernel_supports_event_notifiers()
  *
  * 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);
@@ -1884,44 +1897,42 @@ enum lttng_error_code kernel_rotate_session(struct ltt_session *session)
 
        DBG("Rotate kernel session %s started (session %" PRIu64 ")", session->name, session->id);
 
-       {
-               /*
-                * Note that this loop will end after one iteration given that there is
-                * only one kernel consumer.
-                */
-               lttng::urcu::read_lock_guard read_lock;
-
-               cds_lfht_for_each_entry (
-                       ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
-                       struct ltt_kernel_channel *chan;
-
-                       /* For each channel, ask the consumer to rotate it. */
-                       cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
-                               DBG("Rotate kernel channel %" PRIu64 ", session %s",
-                                   chan->key,
-                                   session->name);
-                               ret = consumer_rotate_channel(socket,
-                                                             chan->key,
-                                                             ksess->consumer,
-                                                             /* is_metadata_channel */ false);
-                               if (ret < 0) {
-                                       status = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
-                                       goto error;
-                               }
-                       }
-
-                       /*
-                        * Rotate the metadata channel.
-                        */
+       /*
+        * Note that this loop will end after one iteration given that there is
+        * only one kernel consumer.
+        */
+       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. */
+               cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
+                       DBG("Rotate kernel channel %" PRIu64 ", session %s",
+                           chan->key,
+                           session->name);
                        ret = consumer_rotate_channel(socket,
-                                                     ksess->metadata->key,
+                                                     chan->key,
                                                      ksess->consumer,
-                                                     /* is_metadata_channel */ true);
+                                                     /* is_metadata_channel */ false);
                        if (ret < 0) {
                                status = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
                                goto error;
                        }
                }
+
+               /*
+                * Rotate the metadata channel.
+                */
+               ret = consumer_rotate_channel(socket,
+                                             ksess->metadata->key,
+                                             ksess->consumer,
+                                             /* is_metadata_channel */ true);
+               if (ret < 0) {
+                       status = LTTNG_ERR_ROTATION_FAIL_CONSUMER;
+                       goto error;
+               }
        }
 
 error:
@@ -1933,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;
 
-       lttng::urcu::read_lock_guard read_lock;
+       const lttng::urcu::read_lock_guard read_lock;
        LTTNG_ASSERT(ksess->current_trace_chunk);
 
        /*
@@ -1998,7 +2009,12 @@ void set_kernel_tracer_status_from_modules_ret(int code)
 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();
@@ -2094,7 +2110,8 @@ int init_kernel_tracer()
                    "work for this session daemon.");
        }
 
-       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(LTTNG_KERNEL_TRACER_STATUS_INITIALIZED);
+       kernel_tracer_status = nonstd::optional<enum lttng_kernel_tracer_status>(
+               LTTNG_KERNEL_TRACER_STATUS_INITIALIZED);
        return 0;
 
 error_version:
@@ -2197,7 +2214,6 @@ void cleanup_kernel_tracer()
        }
 
        kernel_tracer_status = nonstd::nullopt;
-       free(syscall_table);
 }
 
 bool kernel_tracer_is_initialized()
@@ -2210,12 +2226,10 @@ bool kernel_tracer_is_initialized()
  *
  * 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);
@@ -2229,46 +2243,44 @@ enum lttng_error_code kernel_clear_session(struct ltt_session *session)
                goto end;
        }
 
-       {
-               /*
-                * Note that this loop will end after one iteration given that there is
-                * only one kernel consumer.
-                */
-               lttng::urcu::read_lock_guard read_lock;
-
-               cds_lfht_for_each_entry (
-                       ksess->consumer->socks->ht, &iter.iter, socket, node.node) {
-                       struct ltt_kernel_channel *chan;
-
-                       /* For each channel, ask the consumer to clear it. */
-                       cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
-                               DBG("Clear kernel channel %" PRIu64 ", session %s",
-                                   chan->key,
-                                   session->name);
-                               ret = consumer_clear_channel(socket, chan->key);
-                               if (ret < 0) {
-                                       goto error;
-                               }
-                       }
-
-                       if (!ksess->metadata) {
-                               /*
-                                * Nothing to do for the metadata.
-                                * This is a snapshot session.
-                                * The metadata is genererated on the fly.
-                                */
-                               continue;
+       /*
+        * Note that this loop will end after one iteration given that there is
+        * only one kernel consumer.
+        */
+       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. */
+               cds_list_for_each_entry (chan, &ksess->channel_list.head, list) {
+                       DBG("Clear kernel channel %" PRIu64 ", session %s",
+                           chan->key,
+                           session->name);
+                       ret = consumer_clear_channel(socket, chan->key);
+                       if (ret < 0) {
+                               goto error;
                        }
+               }
 
+               if (!ksess->metadata) {
                        /*
-                        * Clear the metadata channel.
-                        * Metadata channel is not cleared per se but we still need to
-                        * perform a rotation operation on it behind the scene.
+                        * Nothing to do for the metadata.
+                        * This is a snapshot session.
+                        * The metadata is genererated on the fly.
                         */
-                       ret = consumer_clear_channel(socket, ksess->metadata->key);
-                       if (ret < 0) {
-                               goto error;
-                       }
+                       continue;
+               }
+
+               /*
+                * Clear the metadata channel.
+                * Metadata channel is not cleared per se but we still need to
+                * perform a rotation operation on it behind the scene.
+                */
+               ret = consumer_clear_channel(socket, ksess->metadata->key);
+               if (ret < 0) {
+                       goto error;
                }
        }
 
@@ -2333,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);
@@ -2516,7 +2528,7 @@ static enum lttng_error_code kernel_create_event_notifier_rule(
 
        /* Add trigger to kernel token mapping in the hash table. */
        {
-               lttng::urcu::read_lock_guard read_lock;
+               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);
@@ -2582,7 +2594,7 @@ enum lttng_error_code kernel_unregister_event_notifier(const struct lttng_trigge
        enum lttng_error_code error_code_ret;
        int ret;
 
-       lttng::urcu::read_lock_guard read_lock;
+       const lttng::urcu::read_lock_guard read_lock;
 
        cds_lfht_lookup(kernel_token_to_event_notifier_rule_ht,
                        hash_trigger(trigger),
This page took 0.029368 seconds and 4 git commands to generate.