From: Michel Normand Date: Wed, 15 Jul 2009 21:48:22 +0000 (+0200) Subject: lxc-start should not hold inheritited fds X-Git-Tag: lxc_0_6_3~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d983b93c3ad860fa22ef760ae27a944d6000e35a;p=thirdparty%2Flxc.git lxc-start should not hold inheritited fds This patch makes the intermediate lxc processes to close the inherited file descriptor. The child process will inherit these fd in any case and that will be up to it to handle them. Signed-off-by: Michel Normand --- diff --git a/src/lxc/namespace.c b/src/lxc/namespace.c index 72b0fc9f3..73a22bb66 100644 --- a/src/lxc/namespace.c +++ b/src/lxc/namespace.c @@ -50,7 +50,7 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags) }; long stack_size = sysconf(_SC_PAGESIZE); - void *stack = alloca(stack_size) + stack_size; + void *stack = alloca(stack_size) + stack_size; pid_t ret; ret = clone(do_clone, stack, flags | SIGCHLD, &clone_arg); diff --git a/src/lxc/start.c b/src/lxc/start.c index 037a229f4..0c72c1a60 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -614,6 +614,12 @@ int lxc_start(const char *name, char *const argv[]) goto out; } + err = lxc_fd_close_inherited(); + if (err) { + ERROR("unable to close inherited fds"); + goto out_abort; + } + err = lxc_poll(name, &handler); if (err) { ERROR("mainloop exited with an error"); diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 9a6b263c3..140bab197 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -21,12 +21,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#define _GNU_SOURCE #include #include +#include +#include #include #include #include +#include +#include +#include #include "log.h" @@ -102,3 +107,95 @@ err: unlink(dstfile); goto out_mmap; } + +struct lxc_fd_entry { + int fd; + struct lxc_fd_entry *next; +}; + +static struct lxc_fd_entry *lxc_fd_list; + +static int fd_list_add(int fd) +{ + struct lxc_fd_entry *entry; + + entry = malloc(sizeof(struct lxc_fd_entry)); + if (!entry) { + SYSERROR("malloc"); + return -1; + } + + entry->fd = fd; + entry->next = lxc_fd_list; + lxc_fd_list = entry; + + return 0; +} + +static void fd_list_del(struct lxc_fd_entry *entry) +{ + free(lxc_fd_list); + lxc_fd_list = entry; +} + +static void __attribute__((constructor)) __lxc_fd_collect_inherited(void) +{ + struct dirent dirent, *direntp; + int fd, fddir; + DIR *dir; + + dir = opendir("/proc/self/fd"); + if (!dir) { + WARN("failed to open directory: %s", strerror(errno)); + return; + } + + fddir = dirfd(dir); + + while (!readdir_r(dir, &dirent, &direntp)) { + + if (!direntp) + break; + + if (!strcmp(direntp->d_name, ".")) + continue; + + if (!strcmp(direntp->d_name, "..")) + continue; + + fd = atoi(direntp->d_name); + + if (fd == fddir) + continue; + + if (fd_list_add(fd)) + WARN("failed to add fd '%d' to the list", fd); + } + + if (closedir(dir)) + WARN("failed to close directory"); +} + +int lxc_fd_close_inherited(void) +{ + struct lxc_fd_entry *next; + + while (lxc_fd_list) { + + /* do not close the stderr fd to keep open default + * error reporting path. + */ + if (lxc_fd_list->fd == 2 && isatty(lxc_fd_list->fd)) + goto next; + + if (close(lxc_fd_list->fd)) + WARN("failed to close fd '%d': %s", lxc_fd_list->fd, + strerror(errno)); + + next: + next = lxc_fd_list->next; + fd_list_del(next); + } + + return 0; +} diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 2fe078946..55165c0c6 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -51,3 +51,4 @@ #endif extern int lxc_copy_file(const char *src, const char *dst); +extern int lxc_fd_close_inherited(void);