mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-05 18:07:30 +00:00
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 <normand@fr.ibm.com>
This commit is contained in:
parent
af06a4bf94
commit
d983b93c3a
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -21,12 +21,17 @@
|
||||
* 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;
|
||||
}
|
||||
|
@ -51,3 +51,4 @@
|
||||
#endif
|
||||
|
||||
extern int lxc_copy_file(const char *src, const char *dst);
|
||||
extern int lxc_fd_close_inherited(void);
|
||||
|
Loading…
Reference in New Issue
Block a user