From: Daniel Lezcano Date: Mon, 20 Jul 2009 15:57:31 +0000 (+0200) Subject: fix closed fd when they are inherited X-Git-Tag: lxc_0_6_3~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af795875875de1855ee251ba530fbe2b53463f6e;p=thirdparty%2Flxc.git fix closed fd when they are inherited This patch fix a problem with the commit d983b93c3ad860fa22ef760ae27a944d6000e35a When the lxc daemonize, it closes fd 0, 1 and 2. But these ones are coming from inherited fd and they are already in the inherited list of fd. When lxc creates some file descriptors, they have the number of the previous inherited file descriptor, so they are closed when we close all the inherited file descriptors. In order to fix that, the lxc_close_inherited_fd function has been implemented to close an inherited fd and remove it from the list. Signed-off-by: Daniel Lezcano --- diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index 9c90771ad..1d3c81953 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -143,14 +143,14 @@ int main(int argc, char *argv[]) * ourself because we don't want /dev/null * being reopened. */ - if (daemon(1 ,1)) { + if (daemon(1, 1)) { SYSERROR("failed to daemonize '%s'", my_args.name); return err; } - close(0); - close(1); - close(2); + lxc_close_inherited_fd(0); + lxc_close_inherited_fd(1); + lxc_close_inherited_fd(2); if (my_args.log_file) { open(my_args.log_file, O_WRONLY | O_CLOEXEC); diff --git a/src/lxc/start.c b/src/lxc/start.c index 9e5e0f043..53df79b0a 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -370,6 +370,7 @@ static int console_init(char *console, size_t size) SYSERROR("failed to retrieve tty name"); return -1; } + return 0; } @@ -629,7 +630,7 @@ int lxc_start(const char *name, char *const argv[]) goto out; } - err = lxc_fd_close_inherited(); + err = lxc_close_all_inherited_fd(); if (err) { ERROR("unable to close inherited fds"); goto out_abort; diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 140bab197..b6b99bf83 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -33,6 +33,7 @@ #include #include +#include "list.h" #include "log.h" lxc_log_define(lxc_utils, lxc); @@ -110,10 +111,10 @@ err: struct lxc_fd_entry { int fd; - struct lxc_fd_entry *next; + struct lxc_list list; }; -static struct lxc_fd_entry *lxc_fd_list; +struct lxc_list lxc_fd_list; static int fd_list_add(int fd) { @@ -126,16 +127,16 @@ static int fd_list_add(int fd) } entry->fd = fd; - entry->next = lxc_fd_list; - lxc_fd_list = entry; + entry->list.elem = entry; + lxc_list_add(&lxc_fd_list, &entry->list); return 0; } static void fd_list_del(struct lxc_fd_entry *entry) { - free(lxc_fd_list); - lxc_fd_list = entry; + lxc_list_del(&entry->list); + free(entry); } static void __attribute__((constructor)) __lxc_fd_collect_inherited(void) @@ -152,6 +153,8 @@ static void __attribute__((constructor)) __lxc_fd_collect_inherited(void) fddir = dirfd(dir); + lxc_list_init(&lxc_fd_list); + while (!readdir_r(dir, &dirent, &direntp)) { if (!direntp) @@ -176,25 +179,50 @@ static void __attribute__((constructor)) __lxc_fd_collect_inherited(void) WARN("failed to close directory"); } -int lxc_fd_close_inherited(void) +int lxc_close_inherited_fd(int fd) +{ + struct lxc_fd_entry *entry; + struct lxc_list *iterator; + + lxc_list_for_each(iterator, &lxc_fd_list) { + + entry = iterator->elem; + + if (entry->fd != fd) + continue; + + fd_list_del(entry); + + break; + } + + return close(fd); +} + +int lxc_close_all_inherited_fd(void) { - struct lxc_fd_entry *next; + struct lxc_fd_entry *entry; + struct lxc_list *iterator; - while (lxc_fd_list) { +again: + lxc_list_for_each(iterator, &lxc_fd_list) { + + entry = iterator->elem; /* 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 (entry->fd == 2 && isatty(entry->fd)) { + fd_list_del(entry); + continue; + } - if (close(lxc_fd_list->fd)) - WARN("failed to close fd '%d': %s", lxc_fd_list->fd, + if (close(entry->fd)) + WARN("failed to close fd '%d': %s", entry->fd, strerror(errno)); - next: - next = lxc_fd_list->next; - fd_list_del(next); + fd_list_del(entry); + goto again; } return 0; diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 55165c0c6..c0c47d005 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -51,4 +51,5 @@ #endif extern int lxc_copy_file(const char *src, const char *dst); -extern int lxc_fd_close_inherited(void); +extern int lxc_close_inherited_fd(int fd); +extern int lxc_close_all_inherited_fd(void);