Commit e9058dea by Serge Hallyn

Merge pull request #917 from amezin/master

Fix daemonized containers without autodev and/or /dev mount
parents 07e4c41f c44de748
......@@ -710,6 +710,7 @@ static int do_start(void *data)
{
struct lxc_list *iterator;
struct lxc_handler *handler = data;
int devnull_fd = -1;
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
SYSERROR("failed to set sigprocmask");
......@@ -788,6 +789,13 @@ static int do_start(void *data)
}
#endif
if (handler->backgrounded) {
devnull_fd = open_devnull();
if (devnull_fd < 0)
goto out_warn_father;
}
/* Setup the container, ip, names, utsname, ... */
if (lxc_setup(handler)) {
ERROR("failed to setup the container");
......@@ -796,7 +804,7 @@ static int do_start(void *data)
/* ask father to setup cgroups and wait for him to finish */
if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP))
return -1;
goto out_error;
/* Set the label to change to when we exec(2) the container's init */
if (lsm_process_label_set(NULL, handler->conf, 1, 1) < 0)
......@@ -853,9 +861,14 @@ static int do_start(void *data)
close(handler->sigfd);
if (handler->backgrounded && null_stdfds() < 0)
if (handler->backgrounded && set_stdfds(devnull_fd))
goto out_warn_father;
if (devnull_fd >= 0) {
close(devnull_fd);
devnull_fd = -1;
}
if (cgns_supported() && unshare(CLONE_NEWCGROUP) != 0) {
SYSERROR("Failed to unshare cgroup namespace");
goto out_warn_father;
......@@ -868,9 +881,14 @@ static int do_start(void *data)
handler->ops->start(handler, handler->data);
out_warn_father:
/* we want the parent to know something went wrong, so any
* value other than what it expects is ok. */
lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE);
/* we want the parent to know something went wrong, so we return a special
* error code. */
lxc_sync_wake_parent(handler, LXC_SYNC_ERROR);
out_error:
if (devnull_fd >= 0)
close(devnull_fd);
return -1;
}
......
......@@ -27,6 +27,7 @@
#include <errno.h>
#include <fcntl.h>
#include "sync.h"
#include "log.h"
#include "start.h"
......@@ -46,6 +47,12 @@ static int __sync_wait(int fd, int sequence)
if (!ret)
return 0;
if (sync == LXC_SYNC_ERROR) {
ERROR("An error occurred in another process "
"(expected sequence number %d)", sequence);
return -1;
}
if (sync != sequence) {
ERROR("invalid sequence number %d. expected %d",
sync, sequence);
......
......@@ -32,6 +32,7 @@ enum {
LXC_SYNC_POST_CGROUP,
LXC_SYNC_RESTART,
LXC_SYNC_POST_RESTART,
LXC_SYNC_ERROR = -1 /* Used to report errors from another process */
};
int lxc_sync_init(struct lxc_handler *handler);
......
......@@ -1752,24 +1752,41 @@ domount:
return 1;
}
int null_stdfds(void)
int open_devnull(void)
{
int fd, ret = -1;
int fd = open("/dev/null", O_RDWR);
if (fd < 0)
SYSERROR("Can't open /dev/null");
return fd;
}
fd = open("/dev/null", O_RDWR);
int set_stdfds(int fd)
{
if (fd < 0)
return -1;
if (dup2(fd, 0) < 0)
goto err;
return -1;
if (dup2(fd, 1) < 0)
goto err;
return -1;
if (dup2(fd, 2) < 0)
goto err;
return -1;
return 0;
}
int null_stdfds(void)
{
int ret = -1;
int fd = open_devnull();
if (fd >= 0) {
ret = set_stdfds(fd);
close(fd);
}
ret = 0;
err:
close(fd);
return ret;
}
......
......@@ -283,6 +283,8 @@ int setproctitle(char *title);
int safe_mount(const char *src, const char *dest, const char *fstype,
unsigned long flags, const void *data, const char *rootfs);
int mount_proc_if_needed(const char *rootfs);
int open_devnull(void);
int set_stdfds(int fd);
int null_stdfds(void);
int lxc_count_file_lines(const char *fn);
#endif /* __LXC_UTILS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment