Fix: close all file descriptors when executed as daemon
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 4 Jun 2012 22:08:24 +0000 (18:08 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 4 Jun 2012 22:08:24 +0000 (18:08 -0400)
Both sessiond and consumerd support the option "-d" to run as daemon. In
some specific cases, e.g. when launched from dpkg installation scripts,
file descriptors 3, 4, 5 are left open and don't seem to have O_CLOEXEC
flag set, so the install script hangs because the sessiond still holds a
reference to them. daemon(3) only closes standard FD 0, 1, 2.

Fix this issue by closing all file descriptors after calling daemon(3).
Note: we make sure no file descriptor is opened before calling daemon(3)
by moving the init_thread_quit_pipe() call after the FD close.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
src/bin/lttng-consumerd/lttng-consumerd.c
src/bin/lttng-sessiond/main.c

index 9f2f02feba03897b7462de3250c863ec2ec37b55..3bc700dc948594a937c2ef543a8cbe4c3d4212f7 100644 (file)
@@ -263,11 +263,26 @@ int main(int argc, char **argv)
 
        /* Daemonize */
        if (opt_daemon) {
 
        /* 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) {
                ret = daemon(0, 0);
                if (ret < 0) {
-                       perror("daemon");
+                       PERROR("daemon");
                        goto error;
                }
                        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) {
        }
 
        if (strlen(command_sock_path) == 0) {
index e8bd45f15ae7ee7ebda9239fd88cb7f0ea2b6ced..5cfd57971f7423fe21f69c1d58b2cfafca99a05b 100644 (file)
@@ -4547,11 +4547,6 @@ int main(int argc, char **argv)
 
        rcu_register_thread();
 
 
        rcu_register_thread();
 
-       /* Create thread quit pipe */
-       if ((ret = init_thread_quit_pipe()) < 0) {
-               goto error;
-       }
-
        setup_consumerd_path();
 
        /* Parse arguments */
        setup_consumerd_path();
 
        /* Parse arguments */
@@ -4562,11 +4557,31 @@ int main(int argc, char **argv)
 
        /* Daemonize */
        if (opt_daemon) {
 
        /* 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");
                        goto error;
                }
                ret = daemon(0, 0);
                if (ret < 0) {
                        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);
+               }
+       }
+
+       /* Create thread quit pipe */
+       if ((ret = init_thread_quit_pipe()) < 0) {
+               goto error;
        }
 
        /* Check if daemon is UID = 0 */
        }
 
        /* Check if daemon is UID = 0 */
This page took 0.037603 seconds and 4 git commands to generate.