]> git.lttng.org Git - lttng-tools.git/commitdiff
lttng-relayd: Write control, data, and live ports to rundir
authorKienan Stewart <kstewart@efficios.com>
Fri, 25 Oct 2024 20:58:46 +0000 (20:58 +0000)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 18 Dec 2024 15:53:34 +0000 (15:53 +0000)
Change-Id: I7ff61e5dc6612de80641ac36fa98abdce3da97b4
Signed-off-by: Kienan Stewart <kstewart@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/bin/lttng-relayd/health-relayd.cpp
src/bin/lttng-relayd/live.cpp
src/bin/lttng-relayd/main.cpp
src/bin/lttng-relayd/utils.cpp
src/bin/lttng-relayd/utils.hpp
src/common/defaults.hpp

index 17376757b81e30a095ea66308f7f475d70265ce3..9f131029e9eae0de296f606b109691df08791f44 100644 (file)
@@ -8,6 +8,7 @@
 #define _LGPL_SOURCE
 #include "health-relayd.hpp"
 #include "lttng-relayd.hpp"
+#include "utils.hpp"
 
 #include <common/common.hpp>
 #include <common/compat/getenv.hpp>
@@ -64,52 +65,6 @@ int send_unix_sock(int sock, void *buf, size_t len)
        return lttcomm_send_unix_sock(sock, buf, len);
 }
 
-void create_lttng_rundir_with_perm(const char *rundir)
-{
-       DBG_FMT("Creating LTTng run directory: `%s`", rundir);
-
-       const auto mkdir_ret = mkdir(rundir, S_IRWXU);
-       if (mkdir_ret < 0) {
-               if (errno != EEXIST) {
-                       LTTNG_THROW_POSIX(fmt::format("Failed to create rundir: path=`{}`", rundir),
-                                         errno);
-               }
-       }
-
-       const auto is_root = !getuid();
-       if (!is_root) {
-               /* Nothing more to do. */
-               return;
-       }
-
-       gid_t gid;
-       const auto get_group_id_ret = utils_get_group_id(tracing_group_name, true, &gid);
-       if (get_group_id_ret) {
-               /* Default to root group. */
-               gid = 0;
-       }
-
-       const auto chown_ret = chown(rundir, 0, gid);
-       if (chown_ret < 0) {
-               LTTNG_THROW_POSIX(
-                       fmt::format("Failed to set group on rundir: path=`{}`, group_id={}",
-                                   rundir,
-                                   gid),
-                       errno);
-       }
-
-       const auto permission_mask = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |
-               S_IXOTH;
-       const auto chmod_ret = chmod(rundir, permission_mask);
-       if (chmod_ret < 0) {
-               LTTNG_THROW_POSIX(
-                       fmt::format(
-                               "Failed to set permissions on rundir: path=`{}`, permission={:o}",
-                               rundir,
-                               permission_mask),
-                       errno);
-       }
-}
 
 void parse_health_env()
 {
index 48d0149562fbe33c33e0f357194a8827f771f9de..4c703421cc8aef24017cc415e7968c6e438f8ea0 100644 (file)
@@ -32,6 +32,7 @@
 #include <common/index/index.hpp>
 #include <common/make-unique-wrapper.hpp>
 #include <common/pthread-lock.hpp>
+#include <common/scope-exit.hpp>
 #include <common/sessiond-comm/inet.hpp>
 #include <common/sessiond-comm/relayd.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
@@ -754,14 +755,44 @@ end:
 static struct lttcomm_sock *init_socket(struct lttng_uri *uri, const char *name)
 {
        int ret, sock_fd;
-       struct lttcomm_sock *sock = nullptr;
        char uri_str[LTTNG_PATH_MAX];
-       char *formatted_name = nullptr;
+       char relayd_live_port_path[PATH_MAX];
 
-       sock = lttcomm_alloc_sock_from_uri(uri);
-       if (sock == nullptr) {
-               ERR("Allocating socket");
-               goto error;
+       const auto rundir_path =
+               lttng::make_unique_wrapper<char, lttng::memory::free>(utils_get_rundir(0));
+       if (!rundir_path) {
+               LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+                       "Failed to determine RUNDIR for socket creation");
+       }
+
+       auto relayd_rundir_path = [&rundir_path]() {
+               char *raw_relayd_path = nullptr;
+               const auto fmt_ret =
+                       asprintf(&raw_relayd_path, DEFAULT_RELAYD_PATH, rundir_path.get());
+               if (fmt_ret < 0) {
+                       LTTNG_THROW_POSIX("Failed to format relayd rundir path", errno);
+               }
+
+               return lttng::make_unique_wrapper<char, lttng::memory::free>(raw_relayd_path);
+       }();
+
+       create_lttng_rundir_with_perm(rundir_path.get());
+       create_lttng_rundir_with_perm(relayd_rundir_path.get());
+       ret = snprintf(relayd_live_port_path,
+                      sizeof(relayd_live_port_path),
+                      DEFAULT_RELAYD_LIVE_PORT_PATH,
+                      relayd_rundir_path.get());
+       if (ret < 0) {
+               LTTNG_THROW_ERROR("Failed to format relayd live port path");
+       }
+
+       auto sock = [uri]() {
+               auto raw_sock = lttcomm_alloc_sock_from_uri(uri);
+               return lttng::make_unique_wrapper<struct lttcomm_sock, lttcomm_destroy_sock>(
+                       raw_sock);
+       }();
+       if (!sock) {
+               LTTNG_THROW_ALLOCATION_FAILURE_ERROR("Failed to allocate socket");
        }
 
        /*
@@ -770,47 +801,65 @@ static struct lttcomm_sock *init_socket(struct lttng_uri *uri, const char *name)
         */
        ret = uri_to_str_url(uri, uri_str, sizeof(uri_str));
        uri_str[sizeof(uri_str) - 1] = '\0';
-       if (ret >= 0) {
-               ret = asprintf(&formatted_name, "%s socket @ %s", name, uri_str);
-               if (ret < 0) {
-                       formatted_name = nullptr;
-               }
-       }
-
+       auto formatted_name =
+               fmt::format("'{}' socket @ '{}'", name, ret < 0 ? uri_str : "Unknown");
+       /* Using '&' requires an lvalue. Using `formatted_name.data()` returns an rvalue. */
+       auto formatted_name_data = formatted_name.data();
        ret = fd_tracker_open_unsuspendable_fd(the_fd_tracker,
                                               &sock_fd,
-                                              (const char **) (formatted_name ? &formatted_name :
-                                                                               nullptr),
+                                              (const char **) &formatted_name_data,
                                               1,
                                               create_sock,
-                                              sock);
+                                              sock.get());
        if (ret) {
-               PERROR("Failed to create \"%s\" socket", formatted_name ?: "Unknown");
-               goto error;
-       }
-       DBG("Listening on %s socket %d", name, sock->fd);
+               LTTNG_THROW_ERROR(lttng::format("Failed to create \"{}\" socket", formatted_name));
+       }
+
+       auto fd_tracker_remove_on_error =
+               lttng::make_scope_exit([&sock, &sock_fd, &relayd_live_port_path]() noexcept {
+                       if (sock.get() != nullptr) {
+                               if (sock->fd >= 0) {
+                                       fd_tracker_close_unsuspendable_fd(the_fd_tracker,
+                                                                         &sock_fd,
+                                                                         1,
+                                                                         close_sock,
+                                                                         sock.get());
+                               }
+                       }
+               });
 
-       ret = sock->ops->bind(sock);
+       DBG("Listening on %s socket %d", name, sock->fd);
+       ret = sock->ops->bind(sock.get());
        if (ret < 0) {
-               PERROR("Failed to bind lttng-live socket");
-               goto error;
+               LTTNG_THROW_POSIX("Failed to bind lttng-live socket", errno);
        }
 
-       DBG("Bound %s socket fd %d to port %d", name, sock->fd, ntohs(sock->sockaddr.addr.sin.sin_port));
-       ret = sock->ops->listen(sock, -1);
-       if (ret < 0) {
-               goto error;
+       if (utils_create_pid_file((pid_t) ntohs(sock->sockaddr.addr.sin.sin_port),
+                                 relayd_live_port_path)) {
+               LTTNG_THROW_ERROR("Failed to create and write live port path");
        }
 
-       free(formatted_name);
-       return sock;
+       auto unlink_relayd_live_port_path_on_error =
+               lttng::make_scope_exit([&relayd_live_port_path]() noexcept {
+                       if (unlink(relayd_live_port_path)) {
+                               WARN_FMT("Failed to remove live port file at path '{}'",
+                                        relayd_live_port_path);
+                       }
+               });
 
-error:
-       if (sock) {
-               lttcomm_destroy_sock(sock);
+       DBG("Bound %s socket fd %d to port %d",
+           name,
+           sock->fd,
+           ntohs(sock->sockaddr.addr.sin.sin_port));
+       ret = sock->ops->listen(sock.get(), -1);
+       if (ret < 0) {
+               LTTNG_THROW_ERROR("Failed to listen on lttng-live socket");
        }
-       free(formatted_name);
-       return nullptr;
+
+       /* Stop destructors from being invoked when the scope_exits go out of scope. */
+       fd_tracker_remove_on_error.disarm();
+       unlink_relayd_live_port_path_on_error.disarm();
+       return sock.release();
 }
 
 /*
@@ -829,9 +878,10 @@ static void *thread_listener(void *data __attribute__((unused)))
        health_register(health_relayd, HEALTH_RELAYD_TYPE_LIVE_LISTENER);
 
        health_code_update();
-
-       live_control_sock = init_socket(live_uri, "Live listener");
-       if (!live_control_sock) {
+       try {
+               live_control_sock = init_socket(live_uri, "Live listener");
+       } catch(const lttng::runtime_error& ex) {
+               ERR("Failed to initialize live socket: %s", ex.what());
                goto error_sock_control;
        }
 
index 0045c5b5fad9b7d07d3fb06f135a82566b4a7717..f8fcee2a1d897726cf39f4d324e59b7013c08430 100644 (file)
@@ -1088,25 +1088,74 @@ static void *relay_thread_listener(void *data __attribute__((unused)))
        int i, ret, err = -1;
        uint32_t nb_fd;
        struct lttng_poll_event events;
-       struct lttcomm_sock *control_sock, *data_sock;
+       char relayd_data_port_path[PATH_MAX];
+       char relayd_control_port_path[PATH_MAX];
+       struct lttcomm_sock *control_sock = nullptr, *data_sock = nullptr;
+       auto relayd_rundir_path = lttng::make_unique_wrapper<char, lttng::memory::free>(nullptr);
 
        DBG("[thread] Relay listener started");
 
        rcu_register_thread();
        health_register(health_relayd, HEALTH_RELAYD_TYPE_LISTENER);
-
        health_code_update();
 
+       const auto rundir_path =
+               lttng::make_unique_wrapper<char, lttng::memory::free>(utils_get_rundir(0));
+       if (!rundir_path) {
+               ERR("Failed to determine RUNDIR for listener thread port files");
+               goto error_sock_control;
+       }
+
+       relayd_rundir_path = [&rundir_path]() {
+               char *raw_relayd_path = nullptr;
+               const auto fmt_ret =
+                       asprintf(&raw_relayd_path, DEFAULT_RELAYD_PATH, rundir_path.get());
+               if (fmt_ret < 0) {
+                       LTTNG_THROW_POSIX("Failed to fomat relayd rundir path", errno);
+               }
+
+               return lttng::make_unique_wrapper<char, lttng::memory::free>(raw_relayd_path);
+       }();
+
+       create_lttng_rundir_with_perm(rundir_path.get());
+       create_lttng_rundir_with_perm(relayd_rundir_path.get());
+       ret = snprintf(relayd_control_port_path, sizeof(relayd_control_port_path), DEFAULT_RELAYD_CONTROL_PORT_PATH, relayd_rundir_path.get());
+       if (ret < 0) {
+               ERR("Failed to format relayd_control_port_path");
+               goto error_sock_control;
+       }
+
+       ret = snprintf(relayd_data_port_path, sizeof(relayd_data_port_path), DEFAULT_RELAYD_DATA_PORT_PATH, relayd_rundir_path.get());
+       if (ret < 0) {
+               ERR("Failed to format relayd_data_port_path");
+               goto error_sock_control;
+       }
+
+       ret = 0;
+       health_code_update();
        control_sock = relay_socket_create(control_uri, "Control listener");
        if (!control_sock) {
                goto error_sock_control;
        }
 
+       if (auto _ret = utils_create_value_file(ntohs(control_sock->sockaddr.addr.sin.sin_port),
+                                   relayd_control_port_path)) {
+               ERR_FMT("Failed to create control port path file: port={}, path=`{}`, ret={}", ntohs(control_sock->sockaddr.addr.sin.sin_port), relayd_control_port_path, _ret);
+               goto error_create_poll;
+               goto error_sock_relay;
+       }
+
        data_sock = relay_socket_create(data_uri, "Data listener");
        if (!data_sock) {
                goto error_sock_relay;
        }
 
+       if (auto _ret = utils_create_value_file(ntohs(data_sock->sockaddr.addr.sin.sin_port),
+                                 relayd_data_port_path)) {
+               ERR_FMT("Failed to create data port path file: port={}, path=`{}`, ret={}", ntohs(data_sock->sockaddr.addr.sin.sin_port), relayd_data_port_path, _ret);
+               goto error_create_poll;
+       }
+
        /*
         * Pass 3 as size here for the thread quit pipe, control and
         * data socket.
@@ -1246,7 +1295,9 @@ error_poll_add:
 error_testpoint:
        (void) fd_tracker_util_poll_clean(the_fd_tracker, &events);
 error_create_poll:
-       if (data_sock->fd >= 0) {
+       DBG("Removing '%s'", relayd_data_port_path);
+       (void) unlink(relayd_data_port_path);
+       if (data_sock != nullptr && data_sock->fd >= 0) {
                int data_sock_fd = data_sock->fd;
 
                ret = fd_tracker_close_unsuspendable_fd(
@@ -1258,7 +1309,9 @@ error_create_poll:
        }
        lttcomm_destroy_sock(data_sock);
 error_sock_relay:
-       if (control_sock->fd >= 0) {
+       DBG("Removing '%s'", relayd_control_port_path);
+       (void) unlink(relayd_control_port_path);
+       if (control_sock != nullptr && control_sock->fd >= 0) {
                int control_sock_fd = control_sock->fd;
 
                ret = fd_tracker_close_unsuspendable_fd(
@@ -1274,6 +1327,7 @@ error_sock_control:
                health_error();
                ERR("Health error occurred in %s", __func__);
        }
+
        health_unregister(health_relayd);
        rcu_unregister_thread();
        DBG("Relay listener thread cleanup complete");
index 3d02f6044b20cd66b5a9920fc18ebdcedcf04a05..fc968ecd1cc9dac5fa76b697ad5ac337dd32b3aa 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <common/common.hpp>
 #include <common/defaults.hpp>
+#include <common/exception.hpp>
 #include <common/path.hpp>
 #include <common/utils.hpp>
 
@@ -76,3 +77,50 @@ char *create_output_path(const char *path_name)
                return create_output_path_noauto(path_name);
        }
 }
+
+void create_lttng_rundir_with_perm(const char *rundir)
+{
+       DBG_FMT("Creating LTTng run directory: `{}`", rundir);
+
+       const auto mkdir_ret = mkdir(rundir, S_IRWXU);
+       if (mkdir_ret < 0) {
+               if (errno != EEXIST) {
+                       LTTNG_THROW_POSIX(fmt::format("Failed to create rundir: path=`{}`", rundir),
+                                         errno);
+               }
+       }
+
+       const auto is_root = !getuid();
+       if (!is_root) {
+               /* Nothing more to do. */
+               return;
+       }
+
+       gid_t gid;
+       const auto get_group_id_ret = utils_get_group_id(tracing_group_name, true, &gid);
+       if (get_group_id_ret) {
+               /* Default to root group. */
+               gid = 0;
+       }
+
+       const auto chown_ret = chown(rundir, 0, gid);
+       if (chown_ret < 0) {
+               LTTNG_THROW_POSIX(
+                       fmt::format("Failed to set group on rundir: path=`{}`, group_id={}",
+                                   rundir,
+                                   gid),
+                       errno);
+       }
+
+       const auto permission_mask = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |
+               S_IXOTH;
+       const auto chmod_ret = chmod(rundir, permission_mask);
+       if (chmod_ret < 0) {
+               LTTNG_THROW_POSIX(
+                       fmt::format(
+                               "Failed to set permissions on rundir: path=`{}`, permission={:o}",
+                               rundir,
+                               permission_mask),
+                       errno);
+       }
+}
index b02a791b1c0a168dbc9d42e5d02ee3930bf7aa0b..c42ee82aecdc431654b9eb6dd191906f769567d4 100644 (file)
@@ -11,5 +11,6 @@
  */
 
 char *create_output_path(const char *path_name);
+void create_lttng_rundir_with_perm(const char* rundir);
 
 #endif /* RELAYD_UTILS_H */
index a0c218622187c0e5ceab26e2548808d6bfbceed6..5c296a389e470bf6d5d15658c29db1620e5486cd 100644 (file)
@@ -85,6 +85,9 @@
 /* Relayd path */
 #define DEFAULT_RELAYD_RUNDIR "%s"
 #define DEFAULT_RELAYD_PATH   DEFAULT_RELAYD_RUNDIR "/relayd"
+#define DEFAULT_RELAYD_CONTROL_PORT_PATH  DEFAULT_LTTNG_EXPLICIT_RUNDIR "/control.port"
+#define DEFAULT_RELAYD_DATA_PORT_PATH DEFAULT_LTTNG_EXPLICIT_RUNDIR "/data.port"
+#define DEFAULT_RELAYD_LIVE_PORT_PATH DEFAULT_LTTNG_EXPLICIT_RUNDIR "/live.port"
 
 #define DEFAULT_RELAYD_MIN_FD_POOL_SIZE 100
 /*
This page took 0.034434 seconds and 4 git commands to generate.