Fix: close all file descriptors when executed as daemon
[lttng-tools.git] / src / bin / lttng-consumerd / lttng-consumerd.c
index 32571bddf36cfc94483eaf0f180694ac21a99fae..3bc700dc948594a937c2ef543a8cbe4c3d4212f7 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ipc.h>
+#include <sys/resource.h>
 #include <sys/shm.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
@@ -38,6 +39,7 @@
 #include <assert.h>
 #include <config.h>
 #include <urcu/compiler.h>
+#include <ulimit.h>
 
 #include <common/defaults.h>
 #include <common/common.h>
@@ -227,6 +229,25 @@ static void parse_args(int argc, char **argv)
        }
 }
 
+/*
+ * Set open files limit to unlimited. This daemon can open a large number of
+ * file descriptors in order to consumer multiple kernel traces.
+ */
+static void set_ulimit(void)
+{
+       int ret;
+       struct rlimit lim;
+
+       /* The kernel does not allowed an infinite limit for open files */
+       lim.rlim_cur = 65535;
+       lim.rlim_max = 65535;
+
+       ret = setrlimit(RLIMIT_NOFILE, &lim);
+       if (ret < 0) {
+               PERROR("failed to set open files limit");
+       }
+}
+
 /*
  * main
  */
@@ -242,11 +263,26 @@ int main(int argc, char **argv)
 
        /* Daemonize */
        if (opt_daemon) {
+               int i;
+
+               /*
+                * fork
+                * child: setsid, close FD 0, 1, 2, chdir /
+                * parent: exit (if fork is successful)
+                */
                ret = daemon(0, 0);
                if (ret < 0) {
-                       perror("daemon");
+                       PERROR("daemon");
                        goto error;
                }
+               /*
+                * We are in the child. Make sure all other file
+                * descriptors are closed, in case we are called with
+                * more opened file descriptors than the standard ones.
+                */
+               for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
+                       (void) close(i);
+               }
        }
 
        if (strlen(command_sock_path) == 0) {
@@ -272,6 +308,11 @@ int main(int argc, char **argv)
        /* Init */
        lttng_consumer_init();
 
+       if (!getuid()) {
+               /* Set limit for open files */
+               set_ulimit();
+       }
+
        /* create the consumer instance with and assign the callbacks */
        ctx = lttng_consumer_create(opt_type, lttng_consumer_read_subbuffer,
                NULL, lttng_consumer_on_recv_stream, NULL);
This page took 0.025322 seconds and 4 git commands to generate.