sessiond/lttng-ctl: Introduce LTTNG_RUNDIR
authorKienan Stewart <kstewart@efficios.com>
Thu, 18 Apr 2024 20:35:40 +0000 (16:35 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 31 Oct 2024 16:06:08 +0000 (12:06 -0400)
Observed issue
==============

Starting multiple instances of lttng-sessiond as the root user isn't
possible, even with setting different values for the `LTTNG_HOME`
environment variable.

Cause
=====

When starting `lttng-sessiond` the `apps_unix_sock_path`,
`client_unix_sock_path`, and `health_unix_sock_path` are set to
configure time static defines under `CONFIG_LTTNG_SYSTEM_RUNDIR`,
e.g. `/var/lib/lttng`.

Solution
========

A new environment variable `LTTNG_RUNDIR` is introduced to control the
base directory used by applications to find communication sockets.

The default behaviour is to emulate the existing divide: if
`LTTNG_RUNDIR` is not set the root `lttng-sessiond` will continue to
use `CONFIG_LTTNG_SYSTEM_RUNDIR`, and a non-root user `lttng-sessiond`
will use `LTTNG_HOME/.lttng`.

When `LTTNG_RUNDIR` is set, it takes priority over `LTTNG_HOME` for
determining the base directory. The output directory for traces is
not affected by `LTTNG_RUNDIR`, it continues to respect `LTTNG_HOME`.

Example with starting multiple root `lttng-sessiond`s:

```
DIR_A=$(mktemp -d)
DIR_B=$(mktemp -d)

LTTNG_RUNDIR="${DIR_A}" lttng-sessiond -b
LTTNG_RUNDIR="${DIR_B}" lttng-sessiond -b

LTTNG_RUNDIR="${DIR_A}" lttng list

LTTNG_RUNDIR="${DIR_B}" lttng list
```

In the example above, as `LTTNG_HOME` is not set, the default output
directory for traces by both over the `lttng-sessiond` instances will
be `$HOME/lttng-traces`.

The following will also work:

```
DIR_A=$(mktemp -d)
LTTNG_RUNDIR="${DIR_A}" lttng create
LTTNG_RUNDIR="${DIR_A}" lttng enable-event -u --all
LTTNG_RUNDIR="${DIR_A}" lttng start

LTTNG_UST_APP_PATH="${DIR_A}" test-application
```

The `LTTNG_UST_CTL_PATH` can be set to a location other than the
rundir as follows;

```
DIR_A=$(mktemp -d)
DIR_B=$(mktemp -d)
LTTNG_UST_CTL_PATH="${DIR_B}" LTTNG_RUNDIR="${DIR_A}" lttng create
LTTNG_RUNDIR="${DIR_A}" lttng enable-event -u -all
LTTNG_RUNDIR="${DIR_A}" lttng start

LTTNG_UST_APP_PATH="${DIR_B}" test-application

LTTNG_UST_APP_PATH="${DIR_A}" test-application
```

Known drawbacks
===============

None.

Change-Id: I371c2c72644277b7dcafaf970ee7b75d9bfbaedc
Signed-off-by: Kienan Stewart <kstewart@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
22 files changed:
doc/man/lttng-sessiond.8.txt
src/bin/lttng-consumerd/health-consumerd.cpp
src/bin/lttng-relayd/health-relayd.cpp
src/bin/lttng-sessiond/client.cpp
src/bin/lttng-sessiond/main.cpp
src/bin/lttng-sessiond/notification-thread.cpp
src/bin/lttng-sessiond/sessiond-config.cpp
src/common/config/session-config.cpp
src/common/consumer/consumer.hpp
src/common/defaults.hpp
src/common/exception.cpp
src/common/exception.hpp
src/common/format.hpp
src/common/utils.cpp
src/common/utils.hpp
src/lib/lttng-ctl/channel.cpp
src/lib/lttng-ctl/lttng-ctl-health.cpp
src/lib/lttng-ctl/lttng-ctl.cpp
tests/regression/tools/config-directory/test_config.py.in
tests/regression/ust/ust-app-ctl-paths/test_blocking
tests/regression/ust/ust-app-ctl-paths/test_ust_app_ctl_paths
tests/utils/lttngtest/lttng.py

index 60382d59d04e87df89581018e3efb1a457e28fa3..a987ba58d1b46c549a9aac40688766c107d6a2e7 100644 (file)
@@ -379,6 +379,15 @@ variable.
 +
 Set to `0` or `-1` to use the timeout of the operating system (default).
 
+`LTTNG_RUN_DIR`::
+    The directory for the session daemon's control files. For session
+    daemons running as the root user, this path defaults to the configured
+    `LTTNG_SYSTEM_RUNDIR` (e.g. `/var/run/lttng`). For session daemons
+    running as non-root users, this defaults to `$LTTNG_HOME/.lttng`.
++
+This environment variable is particularly useful for running multiple
+session daemons as the root user.
+
 `LTTNG_SESSION_CONFIG_XSD_PATH`::
     Recording session configuration XML schema definition (XSD) path.
 
index d0a6ce14fd451e35cc3036533dc8fcb59bc71352..16e9a19de549d6ce3308a547ca0094f27e0ddb65 100644 (file)
@@ -14,6 +14,8 @@
 #include <common/consumer/consumer-timer.hpp>
 #include <common/consumer/consumer.hpp>
 #include <common/defaults.hpp>
+#include <common/exception.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
 #include <common/utils.hpp>
 
 #include <urcu/compiler.h>
 #include <urcu/list.h>
 
-/* Global health check unix path */
-static char health_unix_sock_path[PATH_MAX];
-
 int health_quit_pipe[2] = { -1, -1 };
 
+namespace {
+/* Global health check unix path */
+char health_unix_sock_path[PATH_MAX];
+
 /*
  * Send data on a unix socket using the liblttsessiondcomm API.
  *
  * Return lttcomm error code.
  */
-static int send_unix_sock(int sock, void *buf, size_t len)
+int send_unix_sock(int sock, void *buf, size_t len)
 {
        /* Check valid length */
        if (len == 0) {
@@ -60,79 +63,56 @@ static int send_unix_sock(int sock, void *buf, size_t len)
        return lttcomm_send_unix_sock(sock, buf, len);
 }
 
-static int setup_health_path()
+void setup_health_path()
 {
-       int is_root, ret = 0;
-       enum lttng_consumer_type type;
-       const char *home_path;
+       if (strlen(health_unix_sock_path) != 0) {
+               return;
+       }
 
-       type = lttng_consumer_get_type();
-       is_root = !getuid();
+       const char *consumer_health_socket_fmt_string;
+       const auto consumer_type = lttng_consumer_get_type();
+       switch (consumer_type) {
+       case LTTNG_CONSUMER_KERNEL:
+       {
+               consumer_health_socket_fmt_string = DEFAULT_KCONSUMER_HEALTH_UNIX_SOCK;
+               break;
+       }
+       case LTTNG_CONSUMER64_UST:
+       {
+               consumer_health_socket_fmt_string = DEFAULT_USTCONSUMER64_HEALTH_UNIX_SOCK;
+               break;
+       }
+       case LTTNG_CONSUMER32_UST:
+       {
+               consumer_health_socket_fmt_string = DEFAULT_USTCONSUMER32_HEALTH_UNIX_SOCK;
+               break;
+       }
+       default:
+               LTTNG_THROW_INVALID_ARGUMENT_ERROR(
+                       "Invalid consumer type encountered while setting up consumerd health socket path");
+       }
 
-       if (is_root) {
-               if (strlen(health_unix_sock_path) != 0) {
-                       goto end;
-               }
-               switch (type) {
-               case LTTNG_CONSUMER_KERNEL:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_GLOBAL_KCONSUMER_HEALTH_UNIX_SOCK);
-                       break;
-               case LTTNG_CONSUMER64_UST:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_GLOBAL_USTCONSUMER64_HEALTH_UNIX_SOCK);
-                       break;
-               case LTTNG_CONSUMER32_UST:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_GLOBAL_USTCONSUMER32_HEALTH_UNIX_SOCK);
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto end;
-               }
-       } else {
-               home_path = utils_get_home_dir();
-               if (home_path == nullptr) {
-                       /* TODO: Add --socket PATH option */
-                       ERR("Can't get HOME directory for sockets creation.");
-                       ret = -EPERM;
-                       goto end;
-               }
+       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 health socket creation");
+       }
 
-               /* Set health check Unix path */
-               if (strlen(health_unix_sock_path) != 0) {
-                       goto end;
-               }
-               switch (type) {
-               case LTTNG_CONSUMER_KERNEL:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_HOME_KCONSUMER_HEALTH_UNIX_SOCK,
-                                home_path);
-                       break;
-               case LTTNG_CONSUMER64_UST:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_HOME_USTCONSUMER64_HEALTH_UNIX_SOCK,
-                                home_path);
-                       break;
-               case LTTNG_CONSUMER32_UST:
-                       snprintf(health_unix_sock_path,
-                                sizeof(health_unix_sock_path),
-                                DEFAULT_HOME_USTCONSUMER32_HEALTH_UNIX_SOCK,
-                                home_path);
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto end;
-               }
+       DIAGNOSTIC_PUSH
+       DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+       const auto fmt_ret = snprintf(health_unix_sock_path,
+                                     sizeof(health_unix_sock_path),
+                                     consumer_health_socket_fmt_string,
+                                     rundir_path.get());
+       DIAGNOSTIC_POP
+       if (fmt_ret < 0) {
+               LTTNG_THROW_POSIX(fmt::format("Failed to format {} health socket path",
+                                             consumer_type),
+                                 errno);
        }
-end:
-       return ret;
 }
+} /* namespace */
 
 /*
  * Thread managing health check socket.
@@ -148,7 +128,13 @@ void *thread_manage_health_consumerd(void *data __attribute__((unused)))
 
        DBG("[thread] Manage health check started");
 
-       setup_health_path();
+       try {
+               setup_health_path();
+       } catch (const lttng::runtime_error& ex) {
+               ERR("Failed to setup health path: %s", ex.what());
+               err = -1;
+               goto error;
+       }
 
        rcu_register_thread();
 
index 614c7f7d9c2bb9283f072553ca54abe02dbdcbab..c7bd0ed6ac81ab0a765faac09c85f6d46728f3b2 100644 (file)
@@ -15,7 +15,9 @@
 #include <common/consumer/consumer-timer.hpp>
 #include <common/consumer/consumer.hpp>
 #include <common/defaults.hpp>
+#include <common/exception.hpp>
 #include <common/fd-tracker/utils.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/sessiond-comm/sessiond-comm.hpp>
 #include <common/utils.hpp>
 
 #include <urcu/compiler.h>
 #include <urcu/list.h>
 
-/* Global health check unix path */
-static char health_unix_sock_path[PATH_MAX];
-
 int health_quit_pipe[2] = { -1, -1 };
 
+namespace {
+/* Global health check unix path */
+char health_unix_sock_path[PATH_MAX];
+
 /*
  * Send data on a unix socket using the liblttsessiondcomm API.
  *
  * Return lttcomm error code.
  */
-static int send_unix_sock(int sock, void *buf, size_t len)
+int send_unix_sock(int sock, void *buf, size_t len)
 {
        /* Check valid length */
        if (len == 0) {
@@ -61,57 +64,54 @@ static int send_unix_sock(int sock, void *buf, size_t len)
        return lttcomm_send_unix_sock(sock, buf, len);
 }
 
-static int create_lttng_rundir_with_perm(const char *rundir)
+void create_lttng_rundir_with_perm(const char *rundir)
 {
-       int ret;
-
-       DBG3("Creating LTTng run directory: %s", rundir);
+       DBG_FMT("Creating LTTng run directory: `%s`", rundir);
 
-       ret = mkdir(rundir, S_IRWXU);
-       if (ret < 0) {
+       const auto mkdir_ret = mkdir(rundir, S_IRWXU);
+       if (mkdir_ret < 0) {
                if (errno != EEXIST) {
-                       ERR("Unable to create %s", rundir);
-                       goto error;
-               } else {
-                       ret = 0;
+                       LTTNG_THROW_POSIX(fmt::format("Failed to create rundir: path=`{}`", rundir),
+                                         errno);
                }
-       } else if (ret == 0) {
-               const int is_root = !getuid();
-
-               if (is_root) {
-                       gid_t gid;
+       }
 
-                       ret = utils_get_group_id(tracing_group_name, true, &gid);
-                       if (ret) {
-                               /* Default to root group. */
-                               gid = 0;
-                       }
+       const auto is_root = !getuid();
+       if (!is_root) {
+               /* Nothing more to do. */
+               return;
+       }
 
-                       ret = chown(rundir, 0, gid);
-                       if (ret < 0) {
-                               ERR("Unable to set group on %s", rundir);
-                               PERROR("chown");
-                               ret = -1;
-                               goto error;
-                       }
+       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;
+       }
 
-                       ret = chmod(rundir,
-                                   S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH |
-                                           S_IXOTH);
-                       if (ret < 0) {
-                               ERR("Unable to set permissions on %s", rundir);
-                               PERROR("chmod");
-                               ret = -1;
-                               goto error;
-                       }
-               }
+       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);
        }
 
-error:
-       return ret;
+       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);
+       }
 }
 
-static int parse_health_env()
+void parse_health_env()
 {
        const char *health_path;
 
@@ -120,94 +120,45 @@ static int parse_health_env()
                strncpy(health_unix_sock_path, health_path, PATH_MAX);
                health_unix_sock_path[PATH_MAX - 1] = '\0';
        }
-
-       return 0;
 }
 
-static int setup_health_path()
+void setup_health_path()
 {
-       int is_root, ret = 0;
-       const char *home_path = nullptr;
-       char *rundir = nullptr, *relayd_path = nullptr;
+       parse_health_env();
 
-       ret = parse_health_env();
-       if (ret) {
-               return ret;
+       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 health socket creation");
        }
 
-       is_root = !getuid();
-
-       if (is_root) {
-               rundir = strdup(DEFAULT_LTTNG_RUNDIR);
-               if (!rundir) {
-                       ret = -ENOMEM;
-                       goto end;
-               }
-       } else {
-               /*
-                * Create rundir from home path. This will create something like
-                * $HOME/.lttng
-                */
-               home_path = utils_get_home_dir();
-
-               if (home_path == nullptr) {
-                       /* TODO: Add --socket PATH option */
-                       ERR("Can't get HOME directory for sockets creation.");
-                       ret = -EPERM;
-                       goto end;
+       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 fomat relayd rundir path", errno);
                }
 
-               ret = asprintf(&rundir, DEFAULT_LTTNG_HOME_RUNDIR, home_path);
-               if (ret < 0) {
-                       ret = -ENOMEM;
-                       goto end;
-               }
-       }
+               return lttng::make_unique_wrapper<char, lttng::memory::free>(raw_relayd_path);
+       }();
 
-       ret = asprintf(&relayd_path, DEFAULT_RELAYD_PATH, rundir);
-       if (ret < 0) {
-               ret = -ENOMEM;
-               goto end;
-       }
+       create_lttng_rundir_with_perm(rundir_path.get());
+       create_lttng_rundir_with_perm(relayd_rundir_path.get());
 
-       ret = create_lttng_rundir_with_perm(rundir);
-       if (ret < 0) {
-               goto end;
+       if (strlen(health_unix_sock_path) != 0) {
+               return;
        }
 
-       ret = create_lttng_rundir_with_perm(relayd_path);
-       if (ret < 0) {
-               goto end;
-       }
-
-       if (is_root) {
-               if (strlen(health_unix_sock_path) != 0) {
-                       goto end;
-               }
-               snprintf(health_unix_sock_path,
-                        sizeof(health_unix_sock_path),
-                        DEFAULT_GLOBAL_RELAY_HEALTH_UNIX_SOCK,
-                        (int) getpid());
-       } else {
-               /* Set health check Unix path */
-               if (strlen(health_unix_sock_path) != 0) {
-                       goto end;
-               }
-
-               snprintf(health_unix_sock_path,
-                        sizeof(health_unix_sock_path),
-                        DEFAULT_HOME_RELAY_HEALTH_UNIX_SOCK,
-                        home_path,
-                        (int) getpid());
-       }
-
-end:
-       free(rundir);
-       free(relayd_path);
-       return ret;
+       snprintf(health_unix_sock_path,
+                sizeof(health_unix_sock_path),
+                DEFAULT_RELAY_HEALTH_UNIX_SOCK,
+                rundir_path.get(),
+                (int) getpid());
 }
 
-static int accept_unix_socket(void *data, int *out_fd)
+int accept_unix_socket(void *data, int *out_fd)
 {
        int ret;
        const int accepting_sock = *((int *) data);
@@ -223,7 +174,7 @@ end:
        return ret;
 }
 
-static int open_unix_socket(void *data, int *out_fd)
+int open_unix_socket(void *data, int *out_fd)
 {
        int ret;
        const char *path = (const char *) data;
@@ -238,6 +189,7 @@ static int open_unix_socket(void *data, int *out_fd)
 end:
        return ret;
 }
+} /* namespace */
 
 /*
  * Thread managing health check socket.
@@ -254,7 +206,12 @@ void *thread_manage_health_relayd(void *data __attribute__((unused)))
 
        DBG("[thread] Manage health check started");
 
-       setup_health_path();
+       try {
+               setup_health_path();
+       } catch (const lttng::runtime_error& ex) {
+               ERR_FMT("Failed to setup health socket path of relay daemon: {}", ex.what());
+               goto error;
+       }
 
        rcu_register_thread();
 
index 310b79f8b381dfb8884519049a187ef41dabd697..536e2671466f442e2c690035c323dda8721e1fa4 100644 (file)
@@ -111,7 +111,7 @@ static void setup_lttng_msg(struct command_ctx *cmd_ctx,
 
        /* Append reply header. */
        if (lttng_dynamic_buffer_append(&cmd_ctx->reply_payload.buffer, &llm, sizeof(llm))) {
-               LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+               LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
                        "Failed to append the reply header to a client reply", sizeof(llm));
        }
 
@@ -119,7 +119,7 @@ static void setup_lttng_msg(struct command_ctx *cmd_ctx,
        if (cmd_header_len) {
                if (lttng_dynamic_buffer_append(
                            &cmd_ctx->reply_payload.buffer, cmd_header_buf, cmd_header_len)) {
-                       LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+                       LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
                                "Failed to append the command header to a client reply",
                                cmd_header_len);
                }
@@ -129,7 +129,7 @@ static void setup_lttng_msg(struct command_ctx *cmd_ctx,
        if (payload_len) {
                if (lttng_dynamic_buffer_append(
                            &cmd_ctx->reply_payload.buffer, payload_buf, payload_len)) {
-                       LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+                       LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
                                "Failed to append the payload to a client reply", payload_len);
                }
        }
@@ -144,7 +144,7 @@ static void setup_empty_lttng_msg(struct command_ctx *cmd_ctx)
 
        /* Append place-holder reply header. */
        if (lttng_dynamic_buffer_append(&cmd_ctx->reply_payload.buffer, &llm, sizeof(llm))) {
-               LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+               LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
                        "Failed to append the reply header to a client reply", sizeof(llm));
        }
 
@@ -1890,7 +1890,7 @@ skip_domain:
                                (sizeof(struct lttng_session_extended) * nr_sessions);
                        sessions_payload = zmalloc<lttng_session>(payload_len);
                        if (!sessions_payload) {
-                               LTTNG_THROW_ALLOCATION_FAILURE_ERROR(
+                               LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
                                        "Failed to allocate session list reply payload",
                                        payload_len);
                        }
index cb3896e27d0c5f8f0d320e90921bde2e5acd0b87..a7920a541ef583f904337e735b061f53d2c8fb5e 100644 (file)
@@ -948,8 +948,8 @@ std::string dirname_str(const char *dir)
        auto dir_copy = lttng::make_unique_wrapper<char, lttng::memory::free>(strdup(dir));
 
        if (!dir_copy) {
-               LTTNG_THROW_ALLOCATION_FAILURE_ERROR("Failed to copy path before use of dirname",
-                                                    strlen(dir) + 1);
+               LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(
+                       "Failed to copy path before use of dirname", strlen(dir) + 1);
        }
 
        return std::string(dirname(dir_copy.get()));
index 82272fedc2a53e021bc73e89e9102b08fc96ac36..76165a96e0ae81528fbec0f47f46c35b9ee6d0f9 100644 (file)
@@ -20,6 +20,7 @@
 #include <common/defaults.hpp>
 #include <common/error.hpp>
 #include <common/kernel-ctl/kernel-ctl.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/time.hpp>
 #include <common/utils.hpp>
 
@@ -155,42 +156,29 @@ error:
 
 static char *get_notification_channel_sock_path()
 {
-       int ret;
-       const bool is_root = !getuid();
-       char *sock_path;
-
-       sock_path = calloc<char>(LTTNG_PATH_MAX);
+       auto sock_path = lttng::make_unique_wrapper<char, lttng::memory::free>(
+               zmalloc<char>(LTTNG_PATH_MAX));
        if (!sock_path) {
-               goto error;
+               ERR("Failed to allocate notification channel socket path");
+               return nullptr;
        }
 
-       if (is_root) {
-               ret = snprintf(
-                       sock_path, LTTNG_PATH_MAX, DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK);
-               if (ret < 0) {
-                       goto error;
-               }
-       } else {
-               const char *home_path = utils_get_home_dir();
-
-               if (!home_path) {
-                       ERR("Can't get HOME directory for socket creation");
-                       goto error;
-               }
+       auto rundir_path =
+               lttng::make_unique_wrapper<char, lttng::memory::free>(utils_get_rundir(0));
+       if (!rundir_path) {
+               ERR("Can't get RUNDIR directory for socket creation");
+               return nullptr;
+       }
 
-               ret = snprintf(sock_path,
-                              LTTNG_PATH_MAX,
-                              DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK,
-                              home_path);
-               if (ret < 0) {
-                       goto error;
-               }
+       const auto fmt_ret = snprintf(sock_path.get(),
+                                     LTTNG_PATH_MAX,
+                                     DEFAULT_NOTIFICATION_CHANNEL_UNIX_SOCK,
+                                     rundir_path.get());
+       if (fmt_ret < 0) {
+               return nullptr;
        }
 
-       return sock_path;
-error:
-       free(sock_path);
-       return nullptr;
+       return sock_path.release();
 }
 
 static void notification_channel_socket_destroy(int fd)
index 0a12d9d7f80759bff3d174c1a592daa7dd3965b3..7923dbf234f366c734dfb020ac2fded754ecc6fe 100644 (file)
@@ -189,91 +189,77 @@ static int config_set_ust_ctl_paths(struct sessiond_config *config,
        return 0;
 }
 
-static int config_set_paths_root(struct sessiond_config *config)
+static int config_set_paths(struct sessiond_config *config)
 {
-       int ret = 0;
-
-       config_string_set(&config->rundir, strdup(DEFAULT_LTTNG_RUNDIR));
+       config_string_set(&config->rundir, utils_get_rundir(0));
        if (!config->rundir.value) {
-               ERR("Failed to set rundir");
-               ret = -1;
-               goto end;
+               ERR("Failed to set rundir in session daemon's configuration");
+               return -1;
        }
 
-       config_string_set_static(&config->apps_unix_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
-       config_string_set_static(&config->wait_shm.path, DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH);
-       config_string_set_static(&config->client_unix_sock_path, DEFAULT_GLOBAL_CLIENT_UNIX_SOCK);
-       config_string_set_static(&config->health_unix_sock_path, DEFAULT_GLOBAL_HEALTH_UNIX_SOCK);
-end:
-       return ret;
-}
+       {
+               char *app_sock_path;
 
-static int config_set_paths_non_root(struct sessiond_config *config)
-{
-       int ret = 0;
-       const char *home_path = utils_get_home_dir();
-       char *str;
+               const auto fmt_ret =
+                       asprintf(&app_sock_path, DEFAULT_APPS_UNIX_SOCK, config->rundir.value);
+               if (fmt_ret < 0) {
+                       ERR("Failed to format apps unix socket path");
+                       return -1;
+               }
 
-       if (home_path == nullptr) {
-               ERR("Can't get HOME directory for sockets creation.");
-               ret = -1;
-               goto end;
+               /* Ownership of app_sock_path transfered to config. */
+               config_string_set(&config->apps_unix_sock_path, app_sock_path);
        }
 
-       /*
-        * Create rundir from home path. This will create something like
-        * $HOME/.lttng
-        */
-       ret = asprintf(&str, DEFAULT_LTTNG_HOME_RUNDIR, home_path);
-       if (ret < 0) {
-               ERR("Failed to set rundir");
-               goto end;
-       }
-       config_string_set(&config->rundir, str);
-       str = nullptr;
+       const auto current_uid = getuid();
+       if (current_uid == 0) {
+               config_string_set_static(&config->wait_shm.path, DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH);
+       } else {
+               char *home_apps_wait_shm_path;
 
-       ret = asprintf(&str, DEFAULT_HOME_APPS_UNIX_SOCK, home_path);
-       if (ret < 0) {
-               ERR("Failed to set default home apps unix socket path");
-               goto end;
-       }
+               const auto fmt_ret = asprintf(
+                       &home_apps_wait_shm_path, DEFAULT_HOME_APPS_WAIT_SHM_PATH, current_uid);
+               if (fmt_ret < 0) {
+                       ERR("Failed to set default home apps wait shm path");
+                       return -1;
+               }
 
-       config_string_set(&config->apps_unix_sock_path, str);
-       str = nullptr;
-       ret = asprintf(&str, DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
-       if (ret < 0) {
-               ERR("Failed to set default home apps wait shm path");
-               goto end;
+               /* Ownership of home_apps_wait_shm_path transfered to config. */
+               config_string_set(&config->wait_shm.path, home_apps_wait_shm_path);
        }
 
-       config_string_set(&config->wait_shm.path, str);
-       str = nullptr;
+       {
+               char *client_unix_sock_path;
 
-       ret = asprintf(&str, DEFAULT_HOME_CLIENT_UNIX_SOCK, home_path);
-       if (ret < 0) {
-               ERR("Failed to set default home client unix socket path");
-               goto end;
+               const auto fmt_ret = asprintf(
+                       &client_unix_sock_path, DEFAULT_CLIENT_UNIX_SOCK, config->rundir.value);
+               if (fmt_ret < 0) {
+                       ERR("Failed to format client unix sock path");
+                       return -1;
+               }
+
+               config_string_set(&config->client_unix_sock_path, client_unix_sock_path);
        }
-       config_string_set(&config->client_unix_sock_path, str);
-       str = nullptr;
 
-       ret = asprintf(&str, DEFAULT_HOME_HEALTH_UNIX_SOCK, home_path);
-       if (ret < 0) {
-               ERR("Failed to set default home health UNIX socket path");
-               goto end;
+       {
+               char *health_unix_sock_path;
+
+               const auto fmt_ret = asprintf(
+                       &health_unix_sock_path, DEFAULT_HEALTH_UNIX_SOCK, config->rundir.value);
+               if (fmt_ret < 0) {
+                       ERR("Failed to format health unix sock path");
+                       return -1;
+               }
+
+               config_string_set(&config->health_unix_sock_path, health_unix_sock_path);
        }
-       config_string_set(&config->health_unix_sock_path, str);
-       str = nullptr;
 
-       ret = 0;
-end:
-       return ret;
+       return 0;
 }
 
 int sessiond_config_init(struct sessiond_config *config)
 {
        int ret;
-       const bool is_root = (getuid() == 0);
        char *str;
        auto lttng_ust_ctl_path_override = lttng::make_unique_wrapper<char, lttng::memory::free>(
                utils_get_lttng_ust_ctl_path_override_dir());
@@ -281,11 +267,7 @@ int sessiond_config_init(struct sessiond_config *config)
        LTTNG_ASSERT(config);
        memcpy(config, &sessiond_config_build_defaults, sizeof(*config));
 
-       if (is_root) {
-               ret = config_set_paths_root(config);
-       } else {
-               ret = config_set_paths_non_root(config);
-       }
+       ret = config_set_paths(config);
        if (ret < 0) {
                goto error;
        }
index 6dddbe41e7e4a06193add51d1c7e21166764526d..608710e975a0ed155e1195e12b99a10f2d1edfb1 100644 (file)
@@ -15,6 +15,7 @@
 #include <common/dynamic-buffer.hpp>
 #include <common/error.hpp>
 #include <common/macros.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/utils.hpp>
 
 #include <lttng/lttng-error.h>
@@ -1089,7 +1090,7 @@ static int create_snapshot_session(const char *session_name,
                                   xmlNodePtr output_node,
                                   const struct config_load_session_override_attr *overrides)
 {
-       int ret;
+       int ret = 0;
        enum lttng_error_code ret_code;
        xmlNodePtr node = nullptr;
        xmlNodePtr snapshot_output_list_node;
@@ -3097,7 +3098,7 @@ static int process_session_node(xmlNodePtr session_node,
                                int overwrite,
                                const struct config_load_session_override_attr *overrides)
 {
-       int ret, started = -1, snapshot_mode = -1;
+       int ret = -1, started = -1, snapshot_mode = -1;
        uint64_t live_timer_interval = UINT64_MAX, rotation_timer_interval = 0, rotation_size = 0;
        xmlChar *name = nullptr;
        xmlChar *shm_path = nullptr;
@@ -3686,6 +3687,8 @@ int config_load_session(const char *path,
        bool session_loaded = false;
        const char *path_ptr = nullptr;
        struct session_config_validation_ctx validation_ctx = {};
+       const char *home_path = nullptr;
+       char path_buf[PATH_MAX];
 
        ret = init_session_config_validation_ctx(&validation_ctx);
        if (ret) {
@@ -3693,14 +3696,9 @@ int config_load_session(const char *path,
        }
 
        if (!path) {
-               const char *home_path;
-               const char *sys_path;
-
                /* Try home path */
                home_path = utils_get_home_dir();
                if (home_path) {
-                       char path_buf[PATH_MAX];
-
                        /*
                         * Try user session configuration path. Ignore error here so we can
                         * continue loading the system wide sessions.
@@ -3759,16 +3757,38 @@ int config_load_session(const char *path,
                path_ptr = nullptr;
 
                /* Try system wide configuration directory. */
+               const auto sys_path =
+                       lttng::make_unique_wrapper<char, lttng::memory::free>(utils_get_rundir(0));
+               if (!sys_path) {
+                       ret = -LTTNG_ERR_INVALID;
+                       goto end;
+               }
+
                if (autoload) {
-                       sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH
-                               "/" DEFAULT_SESSION_CONFIG_AUTOLOAD;
-                       ret = validate_path_creds(sys_path);
+                       ret = snprintf(path_buf,
+                                      sizeof(path_buf),
+                                      DEFAULT_SESSION_CONFIGPATH
+                                      "/" DEFAULT_SESSION_CONFIG_AUTOLOAD,
+                                      sys_path.get());
+                       if (ret < 0) {
+                               PERROR("snprintf session auto sys config path");
+                               ret = -LTTNG_ERR_INVALID;
+                               goto end;
+                       }
+                       ret = validate_path_creds(sys_path.get());
                        if (ret) {
-                               path_ptr = sys_path;
+                               path_ptr = sys_path.get();
                        }
                } else {
-                       sys_path = DEFAULT_SESSION_SYSTEM_CONFIGPATH;
-                       path_ptr = sys_path;
+                       ret = snprintf(path_buf,
+                                      sizeof(path_buf),
+                                      DEFAULT_SESSION_CONFIGPATH,
+                                      sys_path.get());
+                       if (ret < 0) {
+                               PERROR("snprintf session sys config path");
+                               ret = -LTTNG_ERR_INVALID;
+                               goto end;
+                       }
                }
 
                if (path_ptr) {
index cad2e2c5611139d814168807e73a0a3abad1fcc4..ff5a91f8a172072ba0b339ea174ac6e6bfdb76f0 100644 (file)
@@ -76,6 +76,39 @@ enum lttng_consumer_type {
        LTTNG_CONSUMER32_UST,
 };
 
+/*
+ * Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace,
+ * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
+ */
+namespace fmt {
+template <>
+struct formatter<lttng_consumer_type> : formatter<std::string> {
+       template <typename FormatContextType>
+       typename FormatContextType::iterator format(lttng_consumer_type consumer_type,
+                                                   FormatContextType& ctx) const
+       {
+               const char *name;
+
+               switch (consumer_type) {
+               case LTTNG_CONSUMER_KERNEL:
+                       name = "kernel consumer";
+                       break;
+               case LTTNG_CONSUMER64_UST:
+                       name = "64-bit user space consumer";
+                       break;
+               case LTTNG_CONSUMER32_UST:
+                       name = "32-bit user space consumer";
+                       break;
+               case LTTNG_CONSUMER_UNKNOWN:
+                       name = "unknown consumer";
+                       break;
+               }
+
+               return format_to(ctx.out(), name);
+       }
+};
+} /* namespace fmt */
+
 enum consumer_endpoint_status {
        CONSUMER_ENDPOINT_ACTIVE,
        CONSUMER_ENDPOINT_INACTIVE,
index a2664a433c85479bb4fef4e134b3f8a727dceead..8ca8bc02665ff2d3380e8251705a637fde5f324a 100644 (file)
 #define DEFAULT_HT_SIZE 4
 
 /* Default session daemon paths */
-#define DEFAULT_HOME_DIR        "/tmp"
-#define DEFAULT_UST_SOCK_DIR    DEFAULT_HOME_DIR "/ust-app-socks"
-#define DEFAULT_GLOBAL_APPS_PIPE DEFAULT_UST_SOCK_DIR "/global"
-#define DEFAULT_TRACE_OUTPUT    DEFAULT_HOME_DIR "/lttng"
+#define DEFAULT_HOME_DIR     "/tmp"
+#define DEFAULT_UST_SOCK_DIR DEFAULT_HOME_DIR "/ust-app-socks"
+#define DEFAULT_TRACE_OUTPUT DEFAULT_HOME_DIR "/lttng"
 
 /* Default directory where the trace are written in per domain */
 #define DEFAULT_KERNEL_TRACE_DIR "kernel"
 #define DEFAULT_LTTNG_FALLBACK_HOME_ENV_VAR   "HOME"
 #define DEFAULT_LTTNG_UST_CTL_PATH_ENV_VAR    "LTTNG_UST_CTL_PATH"
 #define DEFAULT_LTTNG_UST_APP_PATH_ENV_VAR    "LTTNG_UST_APP_PATH"
+#define DEFAULT_LTTNG_RUNDIR_ENV_VAR         "LTTNG_RUNDIR"
 #define DEFAULT_LTTNG_RUNDIR                 CONFIG_LTTNG_SYSTEM_RUNDIR
+#define DEFAULT_LTTNG_EXPLICIT_RUNDIR        "%s"
 #define DEFAULT_LTTNG_HOME_RUNDIR            "%s/.lttng"
 #define DEFAULT_LTTNG_SESSIOND_PIDFILE       "lttng-sessiond.pid"
 #define DEFAULT_LTTNG_SESSIOND_AGENTPORT_FILE "agent.port"
 #define DEFAULT_LTTNG_EXTRA_KMOD_PROBES "LTTNG_EXTRA_KMOD_PROBES"
 
 /* Default unix socket path */
-#define DEFAULT_GLOBAL_CLIENT_UNIX_SOCK                      DEFAULT_LTTNG_RUNDIR "/client-lttng-sessiond"
-#define DEFAULT_HOME_CLIENT_UNIX_SOCK                DEFAULT_LTTNG_HOME_RUNDIR "/client-lttng-sessiond"
-#define DEFAULT_GLOBAL_HEALTH_UNIX_SOCK                      DEFAULT_LTTNG_RUNDIR "/sessiond-health"
-#define DEFAULT_HOME_HEALTH_UNIX_SOCK                DEFAULT_LTTNG_HOME_RUNDIR "/sessiond-health"
-#define DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/sessiond-notification"
-#define DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK \
-       DEFAULT_LTTNG_HOME_RUNDIR "/sessiond-notification"
+#define DEFAULT_CLIENT_UNIX_SOCK DEFAULT_LTTNG_EXPLICIT_RUNDIR "/client-lttng-sessiond"
+#define DEFAULT_HEALTH_UNIX_SOCK DEFAULT_LTTNG_EXPLICIT_RUNDIR "/sessiond-health"
+#define DEFAULT_NOTIFICATION_CHANNEL_UNIX_SOCK \
+       DEFAULT_LTTNG_EXPLICIT_RUNDIR "/sessiond-notification"
 
 /* Default consumer health unix socket path */
-#define DEFAULT_GLOBAL_USTCONSUMER32_HEALTH_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/ustconsumerd32/health"
-#define DEFAULT_HOME_USTCONSUMER32_HEALTH_UNIX_SOCK \
-       DEFAULT_LTTNG_HOME_RUNDIR "/ustconsumerd32/health"
-#define DEFAULT_GLOBAL_USTCONSUMER64_HEALTH_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/ustconsumerd64/health"
-#define DEFAULT_HOME_USTCONSUMER64_HEALTH_UNIX_SOCK \
-       DEFAULT_LTTNG_HOME_RUNDIR "/ustconsumerd64/health"
-#define DEFAULT_GLOBAL_KCONSUMER_HEALTH_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/kconsumerd/health"
-#define DEFAULT_HOME_KCONSUMER_HEALTH_UNIX_SOCK          DEFAULT_LTTNG_HOME_RUNDIR "/kconsumerd/health"
+#define DEFAULT_USTCONSUMER32_HEALTH_UNIX_SOCK \
+       DEFAULT_LTTNG_EXPLICIT_RUNDIR "/ustconsumerd32/health"
+#define DEFAULT_USTCONSUMER64_HEALTH_UNIX_SOCK \
+       DEFAULT_LTTNG_EXPLICIT_RUNDIR "/ustconsumerd64/health"
+#define DEFAULT_KCONSUMER_HEALTH_UNIX_SOCK DEFAULT_LTTNG_EXPLICIT_RUNDIR "/kconsumerd/health"
 
 /* Default relay health unix socket path */
-#define DEFAULT_GLOBAL_RELAY_HEALTH_UNIX_SOCK DEFAULT_LTTNG_RUNDIR "/relayd/health-%d"
-#define DEFAULT_HOME_RELAY_HEALTH_UNIX_SOCK   DEFAULT_LTTNG_HOME_RUNDIR "/relayd/health-%d"
+#define DEFAULT_RELAY_HEALTH_UNIX_SOCK DEFAULT_LTTNG_EXPLICIT_RUNDIR "/relayd/health-%d"
 
 /* Default daemon configuration file path */
 #define DEFAULT_SYSTEM_CONFIGPATH     \
 #define DEFAULT_DAEMON_CONFIG_FILE      "lttng.conf"
 #define DEFAULT_DAEMON_HOME_CONFIGPATH  DEFAULT_LTTNG_HOME_RUNDIR "/" DEFAULT_DAEMON_CONFIG_FILE
 #define DEFAULT_DAEMON_SYSTEM_CONFIGPATH DEFAULT_SYSTEM_CONFIGPATH "/" DEFAULT_DAEMON_CONFIG_FILE
+#define DEFAULT_DAEMON_CONFIGPATH       DEFAULT_LTTNG_EXPLICIT_RUNDIR "/" DEFAULT_DAEMON_CONFIG_FILE
 
 /* Default session configuration file path */
 #define DEFAULT_SESSION_PATH "sessions"
 #define DEFAULT_SESSION_CONFIG_AUTOLOAD              "auto"
 #define DEFAULT_SESSION_HOME_CONFIGPATH              DEFAULT_LTTNG_HOME_RUNDIR "/" DEFAULT_SESSION_PATH
 #define DEFAULT_SESSION_SYSTEM_CONFIGPATH     DEFAULT_SYSTEM_CONFIGPATH "/" DEFAULT_SESSION_PATH
+#define DEFAULT_SESSION_CONFIGPATH           DEFAULT_LTTNG_EXPLICIT_RUNDIR "/" DEFAULT_SESSION_PATH
 #define DEFAULT_SESSION_CONFIG_FILE_EXTENSION ".lttng"
 #define DEFAULT_SESSION_CONFIG_XSD_FILENAME   "session.xsd"
 #define DEFAULT_SESSION_CONFIG_XSD_PATH              CONFIG_LTTNG_SYSTEM_DATADIR "/xml/lttng/"
 #define DEFAULT_SESSION_CONFIG_XSD_PATH_ENV   "LTTNG_SESSION_CONFIG_XSD_PATH"
 
-#define DEFAULT_GLOBAL_APPS_UNIX_SOCK    DEFAULT_LTTNG_RUNDIR "/" LTTNG_UST_SOCK_FILENAME
-#define DEFAULT_HOME_APPS_UNIX_SOCK      DEFAULT_LTTNG_HOME_RUNDIR "/" LTTNG_UST_SOCK_FILENAME
+#define DEFAULT_APPS_UNIX_SOCK           DEFAULT_LTTNG_EXPLICIT_RUNDIR "/" LTTNG_UST_SOCK_FILENAME
 #define DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH "/" LTTNG_UST_WAIT_FILENAME
 #define DEFAULT_HOME_APPS_WAIT_SHM_PATH          DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH "-%d"
 
index 9288aaa07924ab0e645f58efdb37ed59024b6d28..a41aea16d637d61006dca33d2c6b84683986ac4b 100644 (file)
@@ -31,6 +31,12 @@ lttng::runtime_error::runtime_error(const std::string& msg,
 {
 }
 
+lttng::allocation_failure::allocation_failure(const std::string& msg,
+                                             const lttng::source_location& location) :
+       lttng::runtime_error(msg, location)
+{
+}
+
 lttng::allocation_failure::allocation_failure(const std::string& msg,
                                              std::size_t allocation_size_,
                                              const lttng::source_location& location) :
index da6997d4207ffc080e69e6db98818aec8675ef3c..1d53e6402ee06c16461d742ac99420ccf01fd777 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <lttng/lttng-error.h>
 
+#include <vendor/optional.hpp>
+
 #include <stdexcept>
 #include <string>
 #include <system_error>
@@ -24,7 +26,9 @@
        throw lttng::posix_error(msg, errno_code, LTTNG_SOURCE_LOCATION())
 #define LTTNG_THROW_ERROR(msg)       throw lttng::runtime_error(msg, LTTNG_SOURCE_LOCATION())
 #define LTTNG_THROW_OUT_OF_RANGE(msg) throw lttng::out_of_range(msg, LTTNG_SOURCE_LOCATION())
-#define LTTNG_THROW_ALLOCATION_FAILURE_ERROR(msg, allocation_size) \
+#define LTTNG_THROW_ALLOCATION_FAILURE_ERROR(msg) \
+       throw lttng::allocation_failure(msg, LTTNG_SOURCE_LOCATION())
+#define LTTNG_THROW_ALLOCATION_FAILURE_WITH_SIZE_ERROR(msg, allocation_size) \
        throw lttng::allocation_failure(msg, allocation_size, LTTNG_SOURCE_LOCATION())
 #define LTTNG_THROW_UNSUPPORTED_ERROR(msg) \
        throw lttng::unsupported_error(msg, LTTNG_SOURCE_LOCATION())
@@ -104,11 +108,13 @@ public:
  */
 class allocation_failure : public lttng::runtime_error {
 public:
+       explicit allocation_failure(const std::string& msg,
+                                   const lttng::source_location& source_location);
        explicit allocation_failure(const std::string& msg,
                                    std::size_t allocation_size,
                                    const lttng::source_location& source_location);
 
-       std::size_t allocation_size;
+       nonstd::optional<std::size_t> allocation_size;
 };
 
 /*
index 59ed1637cecee878b29ee7609c0fc8b1c19d38c5..6334aaecb133c2af306f13e84ee68fda05d897c1 100644 (file)
@@ -8,6 +8,7 @@
 #define LTTNG_FORMAT_H
 
 #include <common/macros.hpp>
+#include <common/make-unique.hpp>
 
 #include <cxxabi.h>
 #include <string>
index 0f9fae7638aa0cb9156223c3edb9db486e8a83da..701a9f275b4a44568a74ca025b25719c80bc31bd 100644 (file)
@@ -782,6 +782,60 @@ char *utils_get_lttng_ust_ctl_path_override_dir()
        return new_val;
 }
 
+/*
+ * Get configured run directory. Dynamically allocated, must be freed
+ * by the caller.
+ */
+char *utils_get_rundir(gid_t tracing_group_id)
+{
+       char *run_dir = nullptr;
+       int ret = -1;
+
+       const auto *run_dir_env = lttng_secure_getenv(DEFAULT_LTTNG_RUNDIR_ENV_VAR);
+       if (run_dir_env) {
+               run_dir = strdup(run_dir_env);
+               if (!run_dir) {
+                       PERROR("Failed to duplicate `%s` environment variable contents",
+                              DEFAULT_LTTNG_RUNDIR_ENV_VAR);
+                       return nullptr;
+               }
+       } else {
+               /*
+                * Legacy behaviour: if the user is root, use the system rundir.
+                * Else, use the HOME_RUNDIR.
+                */
+               if (getuid() == 0 || tracing_group_id != 0) {
+                       run_dir = strdup(DEFAULT_LTTNG_RUNDIR);
+                       if (!run_dir) {
+                               PERROR("Failed to duplicate default run directory path");
+                               return nullptr;
+                       }
+               } else {
+                       const auto *home_dir = utils_get_home_dir();
+                       if (!home_dir) {
+                               ERR("Failed to get home directory while determining run directory path");
+                               return nullptr;
+                       }
+
+                       ret = asprintf(&run_dir, DEFAULT_LTTNG_HOME_RUNDIR, home_dir);
+                       if (ret < 0) {
+                               /*
+                                * The contents of run_dir during an error may be undefined. Set
+                                * the value to nullptr to avoid a potentially non-pointer from
+                                * being returned.
+                                */
+                               run_dir = nullptr;
+                               PERROR("Failed to format run directory path: default_home_rundir=`%s`, home_dir=`%s`",
+                                      DEFAULT_LTTNG_HOME_RUNDIR,
+                                      home_dir);
+                               return nullptr;
+                       }
+               }
+       }
+
+       return run_dir;
+}
+
 /*
  * Get user's home directory. Dynamically allocated, must be freed
  * by the caller.
index ed9cff8053b85e717fd11391328a8379e81fe1d8..a15aa02a7d89f1995e483b93eaf28f8bdbf9f1cc 100644 (file)
@@ -42,6 +42,7 @@ int utils_parse_size_suffix(const char *const str, uint64_t *const size);
 int utils_parse_time_suffix(const char *const str, uint64_t *const time_us);
 int utils_get_count_order_u32(uint32_t x);
 int utils_get_count_order_u64(uint64_t x);
+char *utils_get_rundir(gid_t tracing_group);
 const char *utils_get_home_dir();
 char *utils_get_user_home_dir(uid_t uid);
 char *utils_get_lttng_ust_ctl_path_override_dir();
index a5ad2843cee1054c22504acc1db8e1205b1d3265..9e5fc409c218f29fd2a54514703c0a5021a7a710 100644 (file)
@@ -11,6 +11,7 @@
 #include <common/defaults.hpp>
 #include <common/dynamic-buffer.hpp>
 #include <common/error.hpp>
+#include <common/make-unique-wrapper.hpp>
 #include <common/payload-view.hpp>
 #include <common/payload.hpp>
 #include <common/unix.hpp>
@@ -21,6 +22,8 @@
 #include <lttng/notification/channel-internal.hpp>
 #include <lttng/notification/notification-internal.hpp>
 
+#include <vector>
+
 static int handshake(struct lttng_notification_channel *channel);
 
 /*
@@ -134,16 +137,15 @@ struct lttng_notification_channel *
 lttng_notification_channel_create(struct lttng_endpoint *endpoint)
 {
        int fd, ret;
-       bool is_in_tracing_group = false, is_root = false;
-       char *sock_path = nullptr;
        struct lttng_notification_channel *channel = nullptr;
 
-       if (!endpoint || endpoint != lttng_session_daemon_notification_endpoint) {
-               goto end;
+       const auto rundir_path =
+               lttng::make_unique_wrapper<char, lttng::memory::free>(utils_get_rundir(0));
+       if (!rundir_path) {
+               goto error;
        }
 
-       sock_path = calloc<char>(LTTNG_PATH_MAX);
-       if (!sock_path) {
+       if (!endpoint || endpoint != lttng_session_daemon_notification_endpoint) {
                goto end;
        }
 
@@ -151,56 +153,42 @@ lttng_notification_channel_create(struct lttng_endpoint *endpoint)
        if (!channel) {
                goto end;
        }
+
        channel->socket = -1;
        pthread_mutex_init(&channel->lock, nullptr);
        lttng_payload_init(&channel->reception_payload);
        CDS_INIT_LIST_HEAD(&channel->pending_notifications.list);
 
-       is_root = (getuid() == 0);
-       if (!is_root) {
-               is_in_tracing_group = lttng_check_tracing_group();
-       }
-
-       if (is_root || is_in_tracing_group) {
-               ret = lttng_strncpy(
-                       sock_path, DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK, LTTNG_PATH_MAX);
-               if (ret) {
-                       ret = -LTTNG_ERR_INVALID;
+       {
+               const auto length = std::snprintf(
+                       nullptr, 0, DEFAULT_NOTIFICATION_CHANNEL_UNIX_SOCK, rundir_path.get()) + 1;
+
+               std::vector<char> sock_path;
+               sock_path.reserve(length);
+               ret = std::snprintf(sock_path.data(),
+                                   length,
+                                   DEFAULT_NOTIFICATION_CHANNEL_UNIX_SOCK,
+                                   rundir_path.get());
+               if (ret < 0 || ret >= LTTNG_PATH_MAX) {
                        goto error;
                }
 
-               ret = lttcomm_connect_unix_sock(sock_path);
-               if (ret >= 0) {
-                       fd = ret;
-                       goto set_fd;
+               ret = lttcomm_connect_unix_sock(sock_path.data());
+               if (ret < 0) {
+                       goto error;
                }
        }
 
-       /* Fallback to local session daemon. */
-       ret = snprintf(sock_path,
-                      LTTNG_PATH_MAX,
-                      DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK,
-                      utils_get_home_dir());
-       if (ret < 0 || ret >= LTTNG_PATH_MAX) {
-               goto error;
-       }
-
-       ret = lttcomm_connect_unix_sock(sock_path);
-       if (ret < 0) {
-               goto error;
-       }
        fd = ret;
-
-set_fd:
        channel->socket = fd;
-
        ret = handshake(channel);
        if (ret) {
                goto error;
        }
+
 end:
-       free(sock_path);
        return channel;
+
 error:
        lttng_notification_channel_destroy(channel);
        channel = nullptr;
index c490f8993c0c1ca55b31613dbad82d1142bce47b..41c2cf3ee1f7612c753ae1c7c776b26605e1b633 100644 (file)
@@ -149,30 +149,23 @@ static const char *get_thread_name(int comp, int nr)
  */
 static int set_health_socket_path(struct lttng_health *lh, int tracing_group)
 {
-       uid_t uid;
-       const char *home;
        int ret;
-       /* Global and home format strings */
-       const char *global_str, *home_str;
+       const char *health_unix_sock_fmt_string;
 
        switch (lh->component) {
        case HEALTH_COMPONENT_SESSIOND:
-               global_str = DEFAULT_GLOBAL_HEALTH_UNIX_SOCK;
-               home_str = DEFAULT_HOME_HEALTH_UNIX_SOCK;
+               health_unix_sock_fmt_string = DEFAULT_HEALTH_UNIX_SOCK;
                break;
        case HEALTH_COMPONENT_CONSUMERD:
                switch (lh->consumerd_type) {
                case LTTNG_HEALTH_CONSUMERD_UST_32:
-                       global_str = DEFAULT_GLOBAL_USTCONSUMER32_HEALTH_UNIX_SOCK;
-                       home_str = DEFAULT_HOME_USTCONSUMER32_HEALTH_UNIX_SOCK;
+                       health_unix_sock_fmt_string = DEFAULT_USTCONSUMER32_HEALTH_UNIX_SOCK;
                        break;
                case LTTNG_HEALTH_CONSUMERD_UST_64:
-                       global_str = DEFAULT_GLOBAL_USTCONSUMER64_HEALTH_UNIX_SOCK;
-                       home_str = DEFAULT_HOME_USTCONSUMER64_HEALTH_UNIX_SOCK;
+                       health_unix_sock_fmt_string = DEFAULT_USTCONSUMER64_HEALTH_UNIX_SOCK;
                        break;
                case LTTNG_HEALTH_CONSUMERD_KERNEL:
-                       global_str = DEFAULT_GLOBAL_KCONSUMER_HEALTH_UNIX_SOCK;
-                       home_str = DEFAULT_HOME_KCONSUMER_HEALTH_UNIX_SOCK;
+                       health_unix_sock_fmt_string = DEFAULT_KCONSUMER_HEALTH_UNIX_SOCK;
                        break;
                default:
                        return -EINVAL;
@@ -189,11 +182,11 @@ static int set_health_socket_path(struct lttng_health *lh, int tracing_group)
                return -EINVAL;
        }
 
-       uid = getuid();
-
-       if (uid == 0 || tracing_group) {
-               ret = lttng_strncpy(lh->health_sock_path, global_str, sizeof(lh->health_sock_path));
-               return ret == 0 ? 0 : -EINVAL;
+       bool use_default_rundir_path = false;
+       auto rundir_path = lttng::make_unique_wrapper<char, lttng::memory::free>(
+               utils_get_rundir(tracing_group));
+       if (!rundir_path) {
+               use_default_rundir_path = true;
        }
 
        /*
@@ -201,18 +194,15 @@ static int set_health_socket_path(struct lttng_health *lh, int tracing_group)
         * is too small; With GNU C >= 2.1, snprintf returns the
         * required size (excluding closing null).
         */
-       home = utils_get_home_dir();
-       if (home == nullptr) {
-               /* Fallback in /tmp */
-               home = "/tmp";
-       }
-
        DIAGNOSTIC_PUSH
        DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
-       ret = snprintf(lh->health_sock_path, sizeof(lh->health_sock_path), home_str, home);
+       ret = snprintf(lh->health_sock_path,
+                      sizeof(lh->health_sock_path),
+                      health_unix_sock_fmt_string,
+                      use_default_rundir_path ? DEFAULT_HOME_DIR : rundir_path.get());
        DIAGNOSTIC_POP
        if ((ret < 0) || (ret >= sizeof(lh->health_sock_path))) {
-               return -ENOMEM;
+               return -EINVAL;
        }
 
        return 0;
index c5c04c262870711d573ea64c72e674a9979725c4..73bfd0db7ca17fcb72667f5c9d8366713497a888 100644 (file)
@@ -17,6 +17,7 @@
 #include <common/bytecode/bytecode.hpp>
 #include <common/common.hpp>
 #include <common/compat/errno.hpp>
+#include <common/compat/getenv.hpp>
 #include <common/compat/string.hpp>
 #include <common/defaults.hpp>
 #include <common/dynamic-array.hpp>
@@ -404,12 +405,19 @@ static int set_session_daemon_path()
                in_tgroup = lttng_check_tracing_group();
        }
 
+       auto rundir = lttng::make_unique_wrapper<char, lttng::memory::free>();
        if ((uid == 0) || in_tgroup == 1) {
-               const int ret = lttng_strncpy(sessiond_sock_path,
-                                             DEFAULT_GLOBAL_CLIENT_UNIX_SOCK,
-                                             sizeof(sessiond_sock_path));
+               int ret = -1;
 
-               if (ret) {
+               rundir.reset(utils_get_rundir(in_tgroup));
+               if (!rundir) {
+                       goto error;
+               }
+               ret = snprintf(sessiond_sock_path,
+                              sizeof(sessiond_sock_path),
+                              DEFAULT_CLIENT_UNIX_SOCK,
+                              rundir.get());
+               if ((ret < 0) || (ret >= sizeof(sessiond_sock_path))) {
                        goto error;
                }
        }
@@ -417,6 +425,11 @@ static int set_session_daemon_path()
        if (uid != 0) {
                int ret;
 
+               rundir.reset(utils_get_rundir(0));
+               if (!rundir) {
+                       goto error;
+               }
+
                if (in_tgroup) {
                        /* Tracing group. */
                        ret = try_connect_sessiond(sessiond_sock_path);
@@ -435,8 +448,8 @@ static int set_session_daemon_path()
                 */
                ret = snprintf(sessiond_sock_path,
                               sizeof(sessiond_sock_path),
-                              DEFAULT_HOME_CLIENT_UNIX_SOCK,
-                              utils_get_home_dir());
+                              DEFAULT_CLIENT_UNIX_SOCK,
+                              rundir.get());
                if ((ret < 0) || (ret >= sizeof(sessiond_sock_path))) {
                        goto error;
                }
index 016634713bfafdad7bfcfb872d7046f7bc0f6a3c..11b0ad4a14c1915c9650933358db9d755a3a2726 100755 (executable)
@@ -141,6 +141,42 @@ tests = {
         "substitutions": DEFAULT_SUBSTITUTIONS,
         "expected_paths": _ust_ctl_path_expected_paths,
     },
+    "lttng_rundir": {
+        "description": "LTTng with LTTNG_RUNDIR set",
+        "environment_variables": {
+            "LTTNG_RUNDIR": True,
+        },
+        "substitutions": DEFAULT_SUBSTITUTIONS,
+        "expected_paths": DEFAULT_EXPECTED_PATHS,
+    },
+    "lttng_home_and_rundir": {
+        "description": "LTTng with LTTNG_RUNDIR and LTTNG_HOME set",
+        "environment_variables": {
+            "LTTNG_RUNDIR": True,
+            "LTTNG_HOME": True,
+        },
+        "substitutions": DEFAULT_SUBSTITUTIONS,
+        "expected_paths": DEFAULT_EXPECTED_PATHS,
+    },
+    "lttng_rundir_and_ust_ctl_path": {
+        "description": "LTTng with LTTNG_RUNDIR and LTTNG_UST_CTL_PATH set",
+        "environment_variables": {
+            "LTTNG_RUNDIR": True,
+            "LTTNG_UST_CTL_PATH": True,
+        },
+        "substitutions": DEFAULT_SUBSTITUTIONS,
+        "expected_paths": _ust_ctl_path_expected_paths,
+    },
+    "lttng_home_and_rundir_and_ust_ctl_path": {
+        "description": "LTTng with LTTNG_RUNDIR, LTTNG_HOME, and LTTNG_UST_CTL_PATH set",
+        "environment_variables": {
+            "LTTNG_RUNDIR": True,
+            "LTTNG_HOME": True,
+            "LTTNG_UST_CTL_PATH": True,
+        },
+        "substitutions": DEFAULT_SUBSTITUTIONS,
+        "expected_paths": _ust_ctl_path_expected_paths,
+    },
 }
 
 
@@ -171,7 +207,9 @@ def test_config_and_socket_paths(
 
     substitutions["RELAYD_PID"] = test_env._relayd.pid
 
-    client = lttngtest.LTTngClient(test_env, log=tap.diagnostic)
+    client = lttngtest.LTTngClient(
+        test_env, log=tap.diagnostic, extra_env_vars=environment_variables
+    )
     session_output_location = lttngtest.LocalSessionOutputLocation(
         test_env.create_temporary_directory("trace")
     )
@@ -193,6 +231,8 @@ def test_config_and_socket_paths(
     test_app.wait_for_exit()
 
     errors = []
+    if "LTTNG_RUNDIR" in environment_variables:
+        os.system("find {}".format(environment_variables["LTTNG_RUNDIR"]))
     for path_id, path_conf in expected_paths.items():
         path = path_conf["path"]
         while re.search("\{\w+\}", path) is not None:
@@ -267,6 +307,10 @@ if __name__ == "__main__":
                 -1
             ].name
             temp_conf["substitutions"]["LTTNG_UST_CTL_PATH"] = tempfiles[-1].name
+        if "LTTNG_RUNDIR" in test_configuration["environment_variables"]:
+            tempfiles.append(tempfile.TemporaryDirectory())
+            temp_conf["environment_variables"]["LTTNG_RUNDIR"] = tempfiles[-1].name
+            temp_conf["substitutions"]["RUNDIR"] = tempfiles[-1].name
         with lttngtest.test_environment(
             with_sessiond=True,
             log=tap.diagnostic,
index ed587938f5c2be97de5d1a00d067940a24925f44..104352ba980cc1d1e1596bb2bdf5c65cfafe4208 100755 (executable)
@@ -10,7 +10,7 @@ TEST_DESC="Verifies that the sessiond starts (or doesn't start) appropriately de
 CURDIR="$(dirname "${0}")"
 TESTDIR="${CURDIR}/../../../"
 
-NUM_TESTS=33
+NUM_TESTS=34
 
 # shellcheck source=../../../utils/utils.sh
 source "${TESTDIR}/utils/utils.sh"
@@ -46,7 +46,7 @@ function test_blocking_mode_app_path()
        rm -rf "${APP_PATH}" "${TRACE_PATH}"
 }
 
-function test_blocking_mode_defaults_paths()
+function test_blocking_mode_default_paths()
 {
        diag "Test starting sessiond in blocking with neither LTTNG_UST_APP_PATH nor LTTNG_UST_CTL_PATH set"
        env_vars=(
index d5c43870f161abb4ae1e27e69d04d30f814b2764..d57e9794d6cd380d997aeffd20f66c7438678feb 100755 (executable)
@@ -75,12 +75,6 @@ function test_sessiond_started_after_app()
 
 function test_multi_sessiond()
 {
-       # Multiple root sessionds cannot be started
-       if [ "${UID}" == "0" ] ; then
-               skip 0 "Multiple root sessionds aren't supported" 28
-               return
-       fi
-
        N_SESSIOND=3
        CTL_PATH_BASE="$(mktemp -d -t "tmp.${FUNCNAME[0]}.ctl.XXXXXX")"
        TRACE_PATH_BASE="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace.XXXXXX")"
@@ -97,6 +91,9 @@ function test_multi_sessiond()
                        LTTNG_UST_CTL_PATH="${CTL_PATH}"
                        TEST_IGNORE_EXISTING_SESSIOND=1
                )
+               if [ "${UID}" == "0" ] ; then
+                       env_vars+=(LTTNG_RUNDIR="${LTTNG_HOME_BASE}/$i")
+               fi
                # shellcheck disable=SC2119
                LTTNG_SESSIOND_ENV_VARS="${env_vars[*]}" start_lttng_sessiond
                export "${env_vars[@]}"
@@ -105,6 +102,7 @@ function test_multi_sessiond()
                enable_ust_lttng_event_ok "${SESSION_NAME}" "--all" "${CHANNEL_NAME}"
                start_lttng_tracing_ok "${SESSION_NAME}"
                unset LTTNG_HOME
+               unset LTTNG_RUNDIR
                unset LTTNG_UST_CTL_PATH
        done
        for i in $(seq 1 "${N_SESSIOND}") ; do
@@ -114,10 +112,13 @@ function test_multi_sessiond()
                env_vars=(
                        LTTNG_HOME="${LTTNG_HOME_BASE}/$i"
                )
+               if [ "${UID}" == "0" ] ; then
+                       env_vars+=(LTTNG_RUNDIR="${LTTNG_HOME_BASE}/$i")
+               fi
                export "${env_vars[@]}"
                stop_lttng_tracing_ok "${SESSION_NAME}"
                destroy_lttng_session_ok "${SESSION_NAME}" --no-wait
-               unset LTTNG_HOME
+               unset LTTNG_HOME LTTNG_RUNDIR
                validate_trace_count "${EVENT_NAMES}" "${TRACE_PATH_BASE}/$i" 100
        done
        # shellcheck disable=SC2119
@@ -135,12 +136,6 @@ function test_multi_sessiond_default()
 {
        diag "Verifies that the lttng_session_daemon_alive()/set_session_daemon_path() in liblttng is coherent with LTTNG_UST_CTL_PATH"
 
-       # Multiple root sessionds cannot be started
-       if [ "${UID}" == "0" ] ; then
-               skip 0 "Multiple root sessionds aren't supported" 11
-               return
-       fi
-
        LTTNG_HOME_B="$(mktemp -d -t "tmp.${FUNCNAME[0]}.lttng-home.XXXXXX")"
        TRACE_PATH="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace.XXXXXX")"
        LTTNG_HOME_ORIG="${LTTNG_HOME}"
@@ -153,6 +148,10 @@ function test_multi_sessiond_default()
                LTTNG_HOME="${LTTNG_HOME_B}"
                TEST_IGNORE_EXISTING_SESSIOND=1
        )
+       if [ "${UID}" == "0" ] ; then
+               env_vars_b+=(LTTNG_RUNDIR="${LTTNG_HOME_B}")
+               LTTNG_UST_APP_PATH="${LTTNG_HOME_B}"
+       fi
        export "${env_vars_b[@]}"
        # shellcheck disable=SC2119
        LTTNG_SESSIOND_ENV_VARS="${env_vars_b[*]}" start_lttng_sessiond
@@ -170,7 +169,7 @@ function test_multi_sessiond_default()
        # shellcheck disable=SC2119
        stop_lttng_sessiond
 
-       unset LTTNG_HOME TEST_IGNORE_EXISTING_SESSIOND
+       unset LTTNG_HOME LTTNG_RUNDIR TEST_IGNORE_EXISTING_SESSIOND
        if [ "${LTTNG_HOME_ORIG}" != "" ] ; then
                export LTTNG_HOME="${LTTNG_HOME_ORIG}"
        fi
@@ -179,11 +178,6 @@ function test_multi_sessiond_default()
 
 function test_trace_another_sessiond()
 {
-       if [ "${UID}" == "0" ] ; then
-               skip 0 "Multiple root sessionds aren't supported" 18
-               return
-       fi
-
        CTL_PATH="$(mktemp -d -t "tmp.${FUNCNAME[0]}.ctl.XXXXXX")"
        TRACE_PATH_A="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace_a.XXXXXX")"
        TRACE_PATH_B="$(mktemp -d -t "tmp.${FUNCNAME[0]}.trace_b.XXXXXX")"
@@ -196,6 +190,9 @@ function test_trace_another_sessiond()
                LTTNG_HOME="${LTTNG_HOME_A}"
                TEST_IGNORE_EXISTING_SESSIOND=1
        )
+       if [ "${UID}" == "0" ] ; then
+               env_vars_a+=(LTTNG_RUNDIR="${LTTNG_HOME_A}")
+       fi
        export "${env_vars_a[@]}"
 
        # shellcheck disable=SC2119
@@ -204,7 +201,7 @@ function test_trace_another_sessiond()
        enable_ust_lttng_channel_ok "${SESSION_NAME}" "${CHANNEL_NAME}"
        enable_ust_lttng_event_ok "${SESSION_NAME}" "--all" "${CHANNEL_NAME}"
        start_lttng_tracing_ok "${SESSION_NAME}"
-       unset LTTNG_HOME LTTNG_UST_CTL_PATH
+       unset LTTNG_HOME LTTNG_RUNDIR LTTNG_UST_CTL_PATH
 
        if [ "${LTTNG_HOME_ORIG}" != "" ] ; then
                export LTTNG_HOME="${LTTNG_HOME_ORIG}"
@@ -228,9 +225,10 @@ function test_trace_another_sessiond()
        stop_lttng_tracing_ok "${SESSION_NAME}"
        destroy_lttng_session_ok "${SESSION_NAME}" --no-wait
        validate_trace_count "${EVENT_NAMES}" "${TRACE_PATH_B}" 100
+       unset LTTNG_HOME LTTNG_RUNDIR LTTNG_UST_CTL_PATH TEST_IGNORE_EXISTING_SESSIOND
 
        # Confirm that we get traced data from the subordinate sessiond
-       export LTTNG_HOME="${LTTNG_HOME_A}"
+       export "${env_vars_a[@]}"
        stop_lttng_tracing_ok "${SESSION_NAME}"
        destroy_lttng_session_ok "${SESSION_NAME}" --no-wait
        EVENT_COUNT="$("${BABELTRACE_BIN}" "${TRACE_PATH_A}" | wc -l)"
@@ -241,7 +239,7 @@ function test_trace_another_sessiond()
 
        # Cleanup
        rm -rf "${TRACE_PATH_A}" "{$TRACE_PATH_B}" "${LTTNG_HOME_A}" "${CTL_PATH}"
-       unset LTTNG_HOME LTTNG_UST_CTL_PATH TEST_IGNORE_EXISTING_SESSIOND
+       unset LTTNG_HOME LTTNG_RUNDIR LTTNG_UST_CTL_PATH TEST_IGNORE_EXISTING_SESSIOND
        if [ "${LTTNG_HOME_ORIG}" != "" ] ; then
                export LTTNG_HOME="${LTTNG_HOME_ORIG}"
        fi
index 3365cd0d8788e9b4a897f881ee7b24bc397531c3..31575a68ee8e6f94b06c58faadcef99aac41c667 100644 (file)
@@ -658,9 +658,11 @@ class LTTngClient(logger._Logger, lttngctl.Controller):
         self,
         test_environment,  # type: environment._Environment
         log,  # type: Optional[Callable[[str], None]]
+        extra_env_vars=dict(),  # type: dict
     ):
         logger._Logger.__init__(self, log)
         self._environment = test_environment  # type: environment._Environment
+        self._extra_env_vars = extra_env_vars
 
     @staticmethod
     def _namespaced_mi_element(property):
@@ -684,6 +686,7 @@ class LTTngClient(logger._Logger, lttngctl.Controller):
         client_env = os.environ.copy()  # type: dict[str, str]
         if self._environment.lttng_home_location is not None:
             client_env["LTTNG_HOME"] = str(self._environment.lttng_home_location)
+        client_env.update(self._extra_env_vars)
 
         process = subprocess.Popen(
             args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=client_env
This page took 0.050086 seconds and 4 git commands to generate.