diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-04-21 18:33:23 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-04-22 19:38:04 +0200 |
commit | 86775e3524dcc1d719aa2c5ec39997f243e0a1e0 (patch) | |
tree | ab11e4b5701465c782f35664f597eb8be2d089ed | |
parent | 082814743f6d118e73dc4d38adc4c19f3b2a57ec (diff) | |
download | systemd-86775e3524dcc1d719aa2c5ec39997f243e0a1e0.tar.gz |
nspawn: beef up --resolve-conf= modes
Let's add flavours for copying stub/uplink resolv.conf versions.
Let's add a more brutal "replace" mode, where we'll replace any existing
destination file.
Let's also change what "auto" means: instead of copying the static file,
let's use the stub file, so that DNS search info is copied over.
Fixes: #15340
-rw-r--r-- | src/nspawn/nspawn-settings.c | 8 | ||||
-rw-r--r-- | src/nspawn/nspawn-settings.h | 12 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 33 |
3 files changed, 37 insertions, 16 deletions
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c index 5fb5b49bbc..4b1115b6e8 100644 --- a/src/nspawn/nspawn-settings.c +++ b/src/nspawn/nspawn-settings.c @@ -821,8 +821,16 @@ static const char *const resolv_conf_mode_table[_RESOLV_CONF_MODE_MAX] = { [RESOLV_CONF_OFF] = "off", [RESOLV_CONF_COPY_HOST] = "copy-host", [RESOLV_CONF_COPY_STATIC] = "copy-static", + [RESOLV_CONF_COPY_UPLINK] = "copy-uplink", + [RESOLV_CONF_COPY_STUB] = "copy-stub", + [RESOLV_CONF_REPLACE_HOST] = "replace-host", + [RESOLV_CONF_REPLACE_STATIC] = "replace-static", + [RESOLV_CONF_REPLACE_UPLINK] = "replace-uplink", + [RESOLV_CONF_REPLACE_STUB] = "replace-stub", [RESOLV_CONF_BIND_HOST] = "bind-host", [RESOLV_CONF_BIND_STATIC] = "bind-static", + [RESOLV_CONF_BIND_UPLINK] = "bind-uplink", + [RESOLV_CONF_BIND_STUB] = "bind-stub", [RESOLV_CONF_DELETE] = "delete", [RESOLV_CONF_AUTO] = "auto", }; diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h index f1a1a75466..6f2c1141e6 100644 --- a/src/nspawn/nspawn-settings.h +++ b/src/nspawn/nspawn-settings.h @@ -38,10 +38,18 @@ typedef enum UserNamespaceMode { typedef enum ResolvConfMode { RESOLV_CONF_OFF, - RESOLV_CONF_COPY_HOST, - RESOLV_CONF_COPY_STATIC, + RESOLV_CONF_COPY_HOST, /* /etc/resolv.conf */ + RESOLV_CONF_COPY_STATIC, /* /usr/lib/systemd/resolv.conf */ + RESOLV_CONF_COPY_UPLINK, /* /run/systemd/resolve/resolv.conf */ + RESOLV_CONF_COPY_STUB, /* /run/systemd/resolve/stub-resolv.conf */ + RESOLV_CONF_REPLACE_HOST, + RESOLV_CONF_REPLACE_STATIC, + RESOLV_CONF_REPLACE_UPLINK, + RESOLV_CONF_REPLACE_STUB, RESOLV_CONF_BIND_HOST, RESOLV_CONF_BIND_STATIC, + RESOLV_CONF_BIND_UPLINK, + RESOLV_CONF_BIND_STUB, RESOLV_CONF_DELETE, RESOLV_CONF_AUTO, _RESOLV_CONF_MODE_MAX, diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 1d7136cee5..9888c9e294 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -79,6 +79,7 @@ #include "ptyfwd.h" #include "random-util.h" #include "raw-clone.h" +#include "resolve-util.h" #include "rlimit-util.h" #include "rm-rf.h" #if HAVE_SECCOMP @@ -100,12 +101,6 @@ #include "user-util.h" #include "util.h" -#if HAVE_SPLIT_USR -#define STATIC_RESOLV_CONF "/lib/systemd/resolv.conf" -#else -#define STATIC_RESOLV_CONF "/usr/lib/systemd/resolv.conf" -#endif - /* nspawn is listening on the socket at the path in the constant nspawn_notify_socket_path * nspawn_notify_socket_path is relative to the container * the init process in the container pid can send messages to nspawn following the sd_notify(3) protocol */ @@ -1850,12 +1845,13 @@ static int setup_resolv_conf(const char *dest) { if (arg_resolv_conf == RESOLV_CONF_AUTO) { if (arg_private_network) m = RESOLV_CONF_OFF; - else if (have_resolv_conf(STATIC_RESOLV_CONF) > 0 && resolved_listening() > 0) - m = etc_writable() ? RESOLV_CONF_COPY_STATIC : RESOLV_CONF_BIND_STATIC; + else if (have_resolv_conf(PRIVATE_STUB_RESOLV_CONF) > 0 && resolved_listening() > 0) + m = etc_writable() ? RESOLV_CONF_COPY_STUB : RESOLV_CONF_BIND_STUB; else if (have_resolv_conf("/etc/resolv.conf") > 0) m = etc_writable() ? RESOLV_CONF_COPY_HOST : RESOLV_CONF_BIND_HOST; else m = etc_writable() ? RESOLV_CONF_DELETE : RESOLV_CONF_OFF; + } else m = arg_resolv_conf; @@ -1877,12 +1873,16 @@ static int setup_resolv_conf(const char *dest) { return 0; } - if (IN_SET(m, RESOLV_CONF_BIND_STATIC, RESOLV_CONF_COPY_STATIC)) - what = STATIC_RESOLV_CONF; + if (IN_SET(m, RESOLV_CONF_BIND_STATIC, RESOLV_CONF_REPLACE_STATIC, RESOLV_CONF_COPY_STATIC)) + what = PRIVATE_STATIC_RESOLV_CONF; + else if (IN_SET(m, RESOLV_CONF_BIND_UPLINK, RESOLV_CONF_REPLACE_UPLINK, RESOLV_CONF_COPY_UPLINK)) + what = PRIVATE_UPLINK_RESOLV_CONF; + else if (IN_SET(m, RESOLV_CONF_BIND_STUB, RESOLV_CONF_REPLACE_STUB, RESOLV_CONF_COPY_STUB)) + what = PRIVATE_STUB_RESOLV_CONF; else what = "/etc/resolv.conf"; - if (IN_SET(m, RESOLV_CONF_BIND_HOST, RESOLV_CONF_BIND_STATIC)) { + if (IN_SET(m, RESOLV_CONF_BIND_HOST, RESOLV_CONF_BIND_STATIC, RESOLV_CONF_BIND_UPLINK, RESOLV_CONF_BIND_STUB)) { _cleanup_free_ char *resolved = NULL; int found; @@ -1898,17 +1898,22 @@ static int setup_resolv_conf(const char *dest) { r = mount_verbose(LOG_WARNING, what, resolved, NULL, MS_BIND, NULL); if (r >= 0) return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL); + + /* If that didn't work, let's copy the file */ } - /* If that didn't work, let's copy the file */ - r = copy_file(what, where, O_TRUNC|O_NOFOLLOW, 0644, 0, 0, COPY_REFLINK); + if (IN_SET(m, RESOLV_CONF_REPLACE_HOST, RESOLV_CONF_REPLACE_STATIC, RESOLV_CONF_REPLACE_UPLINK, RESOLV_CONF_REPLACE_STUB)) + r = copy_file_atomic(what, where, 0644, 0, 0, COPY_REFLINK|COPY_REPLACE); + else + r = copy_file(what, where, O_TRUNC|O_NOFOLLOW, 0644, 0, 0, COPY_REFLINK); if (r < 0) { /* If the file already exists as symlink, let's suppress the warning, under the assumption that * resolved or something similar runs inside and the symlink points there. * * If the disk image is read-only, there's also no point in complaining. */ - log_full_errno(!IN_SET(RESOLV_CONF_COPY_HOST, RESOLV_CONF_COPY_STATIC) && IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r, + log_full_errno(!IN_SET(RESOLV_CONF_COPY_HOST, RESOLV_CONF_COPY_STATIC, RESOLV_CONF_COPY_UPLINK, RESOLV_CONF_COPY_STUB) && + IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r, "Failed to copy /etc/resolv.conf to %s, ignoring: %m", where); return 0; } |