X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=c346f58412e6add45d8d4a42752d2608a068e96a;hb=cb96a2c69a312fb089fef4501650f4fc40a1420b;hp=98b583d7479995828edef31524ade45ef51a8b75;hpb=acbeb42770e1e99955ebc4464a0439cf741b3aeb;p=elogind.git diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 98b583d74..c346f5841 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include "dev-setup.h" #include "fdset.h" #include "build.h" +#include "fileio.h" typedef enum LinkJournal { LINK_NO, @@ -96,7 +98,9 @@ static uint64_t arg_retain = (1ULL << CAP_SYS_PTRACE) | (1ULL << CAP_SYS_TTY_CONFIG) | (1ULL << CAP_SYS_RESOURCE) | - (1ULL << CAP_SYS_BOOT); + (1ULL << CAP_SYS_BOOT) | + (1ULL << CAP_AUDIT_WRITE) | + (1ULL << CAP_AUDIT_CONTROL); static int help(void) { @@ -263,6 +267,11 @@ static int parse_argv(int argc, char *argv[]) { } } + if (optind < argc && arg_boot) { + log_error("Cannot specify a command together with '-b'"); + return -EINVAL; + } + return 1; } @@ -883,8 +892,17 @@ static int process_pty(int master, pid_t pid, sigset_t *mask) { signal_ev.events = EPOLLIN; signal_ev.data.fd = signal_fd; - if (epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || - epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 || + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0) { + if (errno != EPERM) { + log_error("Failed to register stdout in epoll: %m"); + r = -errno; + goto finish; + } + /* stdout without epoll support. Likely redirected to regular file. */ + stdout_writable = true; + } + + if (epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 || epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) { log_error("Failed to register fds in epoll: %m"); r = -errno; @@ -1192,12 +1210,11 @@ int main(int argc, char *argv[]) { for (;;) { siginfo_t status; + int pipefd[2]; - if (saved_attr_valid) { - if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) { - log_error("Failed to set terminal attributes: %m"); - goto finish; - } + if(pipe2(pipefd, O_NONBLOCK|O_CLOEXEC) < 0) { + log_error("pipe2(): %m"); + goto finish; } pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL); @@ -1212,7 +1229,6 @@ int main(int argc, char *argv[]) { if (pid == 0) { /* child */ - const char *home = NULL; uid_t uid = (uid_t) -1; gid_t gid = (gid_t) -1; @@ -1233,9 +1249,20 @@ int main(int argc, char *argv[]) { envp[2] = strv_find_prefix(environ, "TERM="); n_env = 3; + close_nointr_nofail(pipefd[1]); + fd_wait_for_event(pipefd[0], POLLHUP, -1); + close_nointr_nofail(pipefd[0]); + close_nointr_nofail(master); master = -1; + if (saved_attr_valid) { + if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) { + log_error("Failed to set terminal attributes: %m"); + goto child_fail; + } + } + close_nointr(STDIN_FILENO); close_nointr(STDOUT_FILENO); close_nointr(STDERR_FILENO); @@ -1470,6 +1497,10 @@ int main(int argc, char *argv[]) { _exit(EXIT_FAILURE); } + log_info("Init process in the container running as PID %d", pid); + close_nointr_nofail(pipefd[0]); + close_nointr_nofail(pipefd[1]); + fdset_free(fds); fds = NULL;