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) ...@@ -710,6 +710,7 @@ static int do_start(void *data)
{ {
struct lxc_list *iterator; struct lxc_list *iterator;
struct lxc_handler *handler = data; struct lxc_handler *handler = data;
int devnull_fd = -1;
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
SYSERROR("failed to set sigprocmask"); SYSERROR("failed to set sigprocmask");
...@@ -788,6 +789,13 @@ static int do_start(void *data) ...@@ -788,6 +789,13 @@ static int do_start(void *data)
} }
#endif #endif
if (handler->backgrounded) {
devnull_fd = open_devnull();
if (devnull_fd < 0)
goto out_warn_father;
}
/* Setup the container, ip, names, utsname, ... */ /* Setup the container, ip, names, utsname, ... */
if (lxc_setup(handler)) { if (lxc_setup(handler)) {
ERROR("failed to setup the container"); ERROR("failed to setup the container");
...@@ -796,7 +804,7 @@ static int do_start(void *data) ...@@ -796,7 +804,7 @@ static int do_start(void *data)
/* ask father to setup cgroups and wait for him to finish */ /* ask father to setup cgroups and wait for him to finish */
if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP)) 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 */ /* 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) if (lsm_process_label_set(NULL, handler->conf, 1, 1) < 0)
...@@ -853,9 +861,14 @@ static int do_start(void *data) ...@@ -853,9 +861,14 @@ static int do_start(void *data)
close(handler->sigfd); close(handler->sigfd);
if (handler->backgrounded && null_stdfds() < 0) if (handler->backgrounded && set_stdfds(devnull_fd))
goto out_warn_father; goto out_warn_father;
if (devnull_fd >= 0) {
close(devnull_fd);
devnull_fd = -1;
}
if (cgns_supported() && unshare(CLONE_NEWCGROUP) != 0) { if (cgns_supported() && unshare(CLONE_NEWCGROUP) != 0) {
SYSERROR("Failed to unshare cgroup namespace"); SYSERROR("Failed to unshare cgroup namespace");
goto out_warn_father; goto out_warn_father;
...@@ -868,9 +881,14 @@ static int do_start(void *data) ...@@ -868,9 +881,14 @@ static int do_start(void *data)
handler->ops->start(handler, handler->data); handler->ops->start(handler, handler->data);
out_warn_father: out_warn_father:
/* we want the parent to know something went wrong, so any /* we want the parent to know something went wrong, so we return a special
* value other than what it expects is ok. */ * error code. */
lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE); lxc_sync_wake_parent(handler, LXC_SYNC_ERROR);
out_error:
if (devnull_fd >= 0)
close(devnull_fd);
return -1; return -1;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include "sync.h"
#include "log.h" #include "log.h"
#include "start.h" #include "start.h"
...@@ -46,6 +47,12 @@ static int __sync_wait(int fd, int sequence) ...@@ -46,6 +47,12 @@ static int __sync_wait(int fd, int sequence)
if (!ret) if (!ret)
return 0; return 0;
if (sync == LXC_SYNC_ERROR) {
ERROR("An error occurred in another process "
"(expected sequence number %d)", sequence);
return -1;
}
if (sync != sequence) { if (sync != sequence) {
ERROR("invalid sequence number %d. expected %d", ERROR("invalid sequence number %d. expected %d",
sync, sequence); sync, sequence);
......
...@@ -32,6 +32,7 @@ enum { ...@@ -32,6 +32,7 @@ enum {
LXC_SYNC_POST_CGROUP, LXC_SYNC_POST_CGROUP,
LXC_SYNC_RESTART, LXC_SYNC_RESTART,
LXC_SYNC_POST_RESTART, LXC_SYNC_POST_RESTART,
LXC_SYNC_ERROR = -1 /* Used to report errors from another process */
}; };
int lxc_sync_init(struct lxc_handler *handler); int lxc_sync_init(struct lxc_handler *handler);
......
...@@ -1752,24 +1752,41 @@ domount: ...@@ -1752,24 +1752,41 @@ domount:
return 1; 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) if (fd < 0)
return -1; return -1;
if (dup2(fd, 0) < 0) if (dup2(fd, 0) < 0)
goto err; return -1;
if (dup2(fd, 1) < 0) if (dup2(fd, 1) < 0)
goto err; return -1;
if (dup2(fd, 2) < 0) 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; return ret;
} }
......
...@@ -283,6 +283,8 @@ int setproctitle(char *title); ...@@ -283,6 +283,8 @@ int setproctitle(char *title);
int safe_mount(const char *src, const char *dest, const char *fstype, int safe_mount(const char *src, const char *dest, const char *fstype,
unsigned long flags, const void *data, const char *rootfs); unsigned long flags, const void *data, const char *rootfs);
int mount_proc_if_needed(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 null_stdfds(void);
int lxc_count_file_lines(const char *fn); int lxc_count_file_lines(const char *fn);
#endif /* __LXC_UTILS_H */ #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