summaryrefslogtreecommitdiff
path: root/src/nspawn/nspawn.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-07-27 14:50:45 +0200
committerLennart Poettering <lennart@poettering.net>2016-08-03 14:52:16 +0200
commit3539724c26a1b2b00c4eb3c004b635a4b8647de6 (patch)
tree0d1e2b77892fab6400dd731b1a58c921a31414d8 /src/nspawn/nspawn.c
parent5e0bb1a6287387f179540895e43647a0baa8c724 (diff)
nspawn: try to bind mount resolved's resolv.conf snippet into the container
This has the benefit that the container can follow the host's DNS server changes without us having to constantly update the container's resolv.conf settings.
Diffstat (limited to 'src/nspawn/nspawn.c')
-rw-r--r--src/nspawn/nspawn.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 6cc1b9177d..05e1fc1ab7 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1254,24 +1254,39 @@ static int setup_resolv_conf(const char *dest) {
/* Fix resolv.conf, if possible */
where = prefix_roota(dest, "/etc/resolv.conf");
+ if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0) {
+ /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
+ * container, so that the container can use the host's resolver. Given that network namespacing is
+ * disabled it's only natural of the container also uses the host's resolver. It also has the big
+ * advantage that the container will be able to follow the host's DNS server configuration changes
+ * transparently. */
+
+ if (mount("/usr/lib/systemd/resolv.conf", where, NULL, MS_BIND, NULL) < 0)
+ log_warning_errno(errno, "Failed to mount /etc/resolv.conf in the container, ignoring: %m");
+ else {
+ if (mount(NULL, where, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL) < 0)
+ return log_error_errno(errno, "Failed to remount /etc/resolv.conf read-only: %m");
+
+ return 0;
+ }
+ }
+
+ /* If that didn't work, let's copy the file */
r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644, 0);
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 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.
+ * If the disk image is read-only, there's also no point in complaining.
*/
log_full_errno(IN_SET(r, -ELOOP, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
- "Failed to copy /etc/resolv.conf to %s: %m", where);
+ "Failed to copy /etc/resolv.conf to %s, ignoring: %m", where);
return 0;
}
r = userns_lchown(where, 0, 0);
if (r < 0)
- log_warning_errno(r, "Failed to chown /etc/resolv.conf: %m");
+ log_warning_errno(r, "Failed to chown /etc/resolv.conf, ignoring: %m");
return 0;
}