Clean-up: consumer.hpp: coding style indentation fix
[lttng-tools.git] / src / bin / lttng-sessiond / kernel.cpp
index 6e2bdb4c6cf4d5badbb79866397217762a623e8f..4cc51a279806e8f68b217b344057eebf03908bdf 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"
@@ -25,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 <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();
+}
 
-namespace {
 /*
  * On some architectures, calling convention details are embedded in the symbol
  * addresses. Uprobe requires a "clean" symbol offset (or at least, an address
@@ -87,7 +114,7 @@ static inline uint64_t sanitize_uprobe_offset(uint64_t raw_offset)
        return raw_offset;
 }
 #endif
-}
+} /* namespace */
 
 /*
  * Add context on a kernel channel.
@@ -1950,6 +1977,48 @@ error:
        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.
  */
@@ -1958,9 +2027,15 @@ int init_kernel_tracer()
        int ret;
        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;
        }
 
@@ -1968,17 +2043,22 @@ int init_kernel_tracer()
        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;
        }
 
@@ -1995,6 +2075,8 @@ int init_kernel_tracer()
        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);
@@ -2009,6 +2091,8 @@ int init_kernel_tracer()
                                &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;
                }
 
@@ -2017,12 +2101,16 @@ int init_kernel_tracer()
                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, 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;
                }
        }
@@ -2038,6 +2126,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);
        return 0;
 
 error_version:
@@ -2082,6 +2172,8 @@ 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;
@@ -2137,6 +2229,7 @@ void cleanup_kernel_tracer()
                kernel_tracer_fd = -1;
        }
 
+       kernel_tracer_status = nonstd::nullopt;
        free(syscall_table);
 }
 
This page took 0.025817 seconds and 4 git commands to generate.