From: Mathieu Desnoyers Date: Mon, 4 Jun 2012 22:08:24 +0000 (-0400) Subject: Fix: close all file descriptors when executed as daemon X-Git-Tag: v2.1.0-rc1~117 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=ceed52b545103258e84f1c7040700be9dbbbaec6 Fix: close all file descriptors when executed as daemon 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 --- diff --git a/src/bin/lttng-consumerd/lttng-consumerd.c b/src/bin/lttng-consumerd/lttng-consumerd.c index 9f2f02feb..3bc700dc9 100644 --- a/src/bin/lttng-consumerd/lttng-consumerd.c +++ b/src/bin/lttng-consumerd/lttng-consumerd.c @@ -263,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) { diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index e8bd45f15..5cfd57971 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -4547,11 +4547,6 @@ int main(int argc, char **argv) rcu_register_thread(); - /* Create thread quit pipe */ - if ((ret = init_thread_quit_pipe()) < 0) { - goto error; - } - setup_consumerd_path(); /* Parse arguments */ @@ -4562,11 +4557,31 @@ 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"); 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 */