]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
fix closed fd when they are inherited
authorDaniel Lezcano <dlezcano@fr.ibm.com>
Mon, 20 Jul 2009 15:57:31 +0000 (17:57 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Mon, 20 Jul 2009 15:57:31 +0000 (17:57 +0200)
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 <dlezcano@fr.ibm.com>
src/lxc/lxc_start.c
src/lxc/start.c
src/lxc/utils.c
src/lxc/utils.h

index 9c90771adeb1632e8565c030a2b52f245fc8cebf..1d3c81953e102e512c22993dcaf6d091a7ec4672 100644 (file)
@@ -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(11)) {
                        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);
index 9e5e0f04398f85df4879eb5e77fe08f443c40a1d..53df79b0a7ebc247b60fc992889d172bc7ca9064 100644 (file)
@@ -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;
index 140bab197cd1156a4520f2fa643943120b06c609..b6b99bf838afb947b19c92298bb0c04b21cd8179 100644 (file)
@@ -33,6 +33,7 @@
 #include <dirent.h>
 #include <fcntl.h>
 
+#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;
index 55165c0c6a35665d19b988af433f3de6c44a43cf..c0c47d0058a87315b7376b1a9d55434e03ce96ac 100644 (file)
@@ -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);