diff options
author | Alban Crequy <alban@endocode.com> | 2015-05-18 16:45:30 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-05-18 22:24:15 +0200 |
commit | 6b7d2e9ea4cdb4cfa1512d37548a1a967623d7f2 (patch) | |
tree | 6d5d468c937a6da40631af5d84621d6e6068f168 | |
parent | 8dc26de6da7a7611ecf0362ffc4f178569109d23 (diff) |
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
-rw-r--r-- | src/nspawn/nspawn.c | 15 |
1 files changed, 12 insertions, 3 deletions
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); } |