relayd: add fd-cap option to limit the number of opened FDs
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 26 Nov 2019 20:08:01 +0000 (15:08 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 30 Jan 2020 06:55:34 +0000 (01:55 -0500)
Add an --fd-cap option to the relay daemon in order to allow the
launch of the relay daemon with a maximal number of file descriptors
to be open at any given moment.

When the value of the --fd-cap parameter is left unset, the maximal
number of file descriptors is set to the system's NOFILE soft limit
(see GETRLIMIT(3P)).

A minimal number of file descriptors of 30 is imposed, mainly to
prevent absurd configurations (someone setting 1 fd) which would not
even allow one target to connect and stream traces. This also allows
a bit of leverage to open file descriptors that could be needed by
future changes without "breaking" an existing configuration.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Ibaf49b25ccf3e3a8013115c9478744ca3646e306

src/bin/lttng-relayd/main.c
src/common/defaults.h

index 4e30ac49882e5c392097b51dfedf95b0d7207686..f61f1f13e69ce72eedfc53d3a1941951ae50041c 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/resource.h>
 #include <inttypes.h>
 #include <urcu/futex.h>
 #include <urcu/uatomic.h>
@@ -41,6 +42,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <strings.h>
+#include <ctype.h>
 
 #include <lttng/lttng.h>
 #include <common/common.h>
@@ -160,6 +162,9 @@ static uint64_t last_relay_stream_id;
  */
 static struct relay_conn_queue relay_conn_queue;
 
+/* Cap of file desriptors to be in simultaneous use by the relay daemon. */
+static unsigned int lttng_opt_fd_cap;
+
 /* Global relay stream hash table. */
 struct lttng_ht *relay_streams_ht;
 
@@ -181,6 +186,7 @@ static struct option long_options[] = {
        { "daemonize", 0, 0, 'd', },
        { "background", 0, 0, 'b', },
        { "group", 1, 0, 'g', },
+       { "fd-cap", 1, 0, '\0', },
        { "help", 0, 0, 'h', },
        { "output", 1, 0, 'o', },
        { "verbose", 0, 0, 'v', },
@@ -224,9 +230,34 @@ static int set_option(int opt, const char *arg, const char *optname)
 
        switch (opt) {
        case 0:
-               fprintf(stderr, "option %s", optname);
-               if (arg) {
-                       fprintf(stderr, " with arg %s\n", arg);
+               if (!strcmp(optname, "fd-cap")) {
+                       unsigned long v;
+
+                       errno = 0;
+                       v = strtoul(arg, NULL, 0);
+                       if (errno != 0 || !isdigit(arg[0])) {
+                               ERR("Wrong value in --fd-cap parameter: %s",
+                                               arg);
+                               ret = -1;
+                               goto end;
+                       }
+                       if (v < DEFAULT_RELAYD_MINIMAL_FD_CAP) {
+                               ERR("File descriptor cap must be set to at least %d",
+                                               DEFAULT_RELAYD_MINIMAL_FD_CAP);
+                       }
+                       if (v >= UINT_MAX) {
+                               ERR("File descriptor cap overflow in --fd-cap parameter: %s",
+                                               arg);
+                               ret = -1;
+                               goto end;
+                       }
+                       lttng_opt_fd_cap = (unsigned int) v;
+                       DBG3("File descriptor cap set to %u", lttng_opt_fd_cap);
+               } else {
+                       fprintf(stderr, "unknown option %s", optname);
+                       if (arg) {
+                               fprintf(stderr, " with arg %s\n", arg);
+                       }
                }
                break;
        case 'C':
@@ -563,6 +594,18 @@ static int set_options(int argc, char **argv)
                        goto exit;
                }
        }
+       if (lttng_opt_fd_cap == 0) {
+               int ret;
+               struct rlimit rlimit;
+
+               ret = getrlimit(RLIMIT_NOFILE, &rlimit);
+               if (ret) {
+                       PERROR("Failed to get file descriptor limit");
+                       retval = -1;
+               }
+
+               lttng_opt_fd_cap = rlimit.rlim_cur;
+       }
 
        if (opt_group_output_by == RELAYD_GROUP_OUTPUT_BY_UNKNOWN) {
                opt_group_output_by = RELAYD_GROUP_OUTPUT_BY_HOST;
index 2c3e80f436d586f067339dad88f9b5c02f2db202..e57e6495fa7509056e308238caed41d6dfd60b54 100644 (file)
@@ -93,6 +93,8 @@
 #define DEFAULT_RELAYD_RUNDIR                  "%s"
 #define DEFAULT_RELAYD_PATH                    DEFAULT_RELAYD_RUNDIR "/relayd"
 
+#define DEFAULT_RELAYD_MINIMAL_FD_CAP          30
+
 /* Default lttng run directory */
 #define DEFAULT_LTTNG_HOME_ENV_VAR              "LTTNG_HOME"
 #define DEFAULT_LTTNG_FALLBACK_HOME_ENV_VAR    "HOME"
This page took 0.040241 seconds and 5 git commands to generate.