]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-start should not hold inheritited fds
authorMichel Normand <normand@fr.ibm.com>
Wed, 15 Jul 2009 21:48:22 +0000 (23:48 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Wed, 15 Jul 2009 21:48:22 +0000 (23:48 +0200)
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 <normand@fr.ibm.com>
src/lxc/namespace.c
src/lxc/start.c
src/lxc/utils.c
src/lxc/utils.h

index 72b0fc9f35b68a8c073dbf5d56b4f6d0f746a7e5..73a22bb663dc2328935a1463f946affc9c61206c 100644 (file)
@@ -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);
index 037a229f4d8f77764fcdb3110fbb1fb7f095acfa..0c72c1a60a6990760e92c39e2c11c6a5a374aa9b 100644 (file)
@@ -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");
index 9a6b263c324f08db23a42b234fbbb8ba1815a4f4..140bab197cd1156a4520f2fa643943120b06c609 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#include <fcntl.h>
+#define _GNU_SOURCE
 #include <errno.h>
 #include <unistd.h>
+#include <stdlib.h>
+#include <stddef.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <fcntl.h>
 
 #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;
+}
index 2fe078946a9cd32d54512aa23230641d0bc84504..55165c0c6a35665d19b988af433f3de6c44a43cf 100644 (file)
@@ -51,3 +51,4 @@
 #endif
 
 extern int lxc_copy_file(const char *src, const char *dst);
+extern int lxc_fd_close_inherited(void);