mirror of
git://github.com/lxc/lxc
synced 2025-08-31 02:39:36 +00:00
fix closed fd when they are inherited
This patch fix a problem with the commit d983b93c3a
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>
This commit is contained in:
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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 *next;
|
||||
struct lxc_fd_entry *entry;
|
||||
struct lxc_list *iterator;
|
||||
|
||||
while (lxc_fd_list) {
|
||||
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 *entry;
|
||||
struct lxc_list *iterator;
|
||||
|
||||
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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user