From 6b7d2e9ea4cdb4cfa1512d37548a1a967623d7f2 Mon Sep 17 00:00:00 2001 From: Alban Crequy Date: Mon, 18 May 2015 16:45:30 +0200 Subject: nspawn: close extra fds before execing init When systemd-nspawn gets exec*()ed, it inherits the followings file descriptors: - 0, 1, 2: stdin, stdout, stderr - SD_LISTEN_FDS_START, ... SD_LISTEN_FDS_START+LISTEN_FDS: file descriptors passed by the system manager (useful for socket activation). They are passed to the child process (process leader). - extra lock fd: rkt passes a locked directory as an extra fd, so the directory remains locked as long as the container is alive. systemd-nspawn used to close all open fds except 0, 1, 2 and the SD_LISTEN_FDS_START..SD_LISTEN_FDS_START+LISTEN_FDS. This patch delays the close just before the exec so the nspawn process (parent) keeps the extra fds open. This patch supersedes the previous attempt ("cloexec extraneous fds"): http://lists.freedesktop.org/archives/systemd-devel/2015-May/031608.html --- src/nspawn/nspawn.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/nspawn') diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4095c77fdf..a38f47dd0a 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3990,7 +3990,6 @@ int main(int argc, char *argv[]) { goto finish; } - log_close(); n_fd_passed = sd_listen_fds(false); if (n_fd_passed > 0) { r = fdset_new_listen_fds(&fds, false); @@ -3999,8 +3998,6 @@ int main(int argc, char *argv[]) { goto finish; } } - fdset_close_others(fds); - log_open(); if (arg_directory) { assert(!arg_image); @@ -4510,6 +4507,17 @@ int main(int argc, char *argv[]) { * setup, too... */ (void) barrier_place_and_sync(&barrier); /* #5 */ + /* Now, explicitly close the log, so that we + * then can close all remaining fds. Closing + * the log explicitly first has the benefit + * that the logging subsystem knows about it, + * and is thus ready to be reopened should we + * need it again. Note that the other fds + * closed here are at least the locking and + * barrier fds. */ + log_close(); + (void) fdset_close_others(fds); + if (arg_boot) { char **a; size_t l; @@ -4536,6 +4544,7 @@ int main(int argc, char *argv[]) { execle("/bin/sh", "-sh", NULL, env_use); } + (void) log_open(); log_error_errno(errno, "execv() failed: %m"); _exit(EXIT_FAILURE); } -- cgit v1.2.3-54-g00ecf