]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: try to bind mount resolved's resolv.conf snippet into the container
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Jul 2016 12:50:45 +0000 (14:50 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Aug 2016 12:52:16 +0000 (14:52 +0200)
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.

src/nspawn/nspawn.c

index 6cc1b9177d828fc53a3c6b9a7a632c3544c35f15..05e1fc1ab7611d80d70f7fdcd738a5ace3ade957 100644 (file)
@@ -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;
 }