+ r = mkdir_parents(where, 0755);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to create parent directory for resolv.conf %s: %m", where);
+
+ return 0;
+ }
+
+ r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to copy /etc/resolv.conf to %s: %m", where);
+
+ return 0;
+ }
+
+ return 0;
+}
+
+static int setup_volatile_state(const char *directory) {
+ const char *p;
+ int r;
+
+ assert(directory);
+
+ if (arg_volatile != VOLATILE_STATE)
+ return 0;
+
+ /* --volatile=state means we simply overmount /var
+ with a tmpfs, and the rest read-only. */
+
+ r = bind_remount_recursive(directory, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to remount %s read-only: %m", directory);
+
+ p = strappenda(directory, "/var");
+ r = mkdir(p, 0755);
+ if (r < 0 && errno != EEXIST)
+ return log_error_errno(errno, "Failed to create %s: %m", directory);
+
+ if (mount("tmpfs", p, "tmpfs", MS_STRICTATIME, "mode=755") < 0)
+ return log_error_errno(errno, "Failed to mount tmpfs to /var: %m");
+
+ return 0;
+}
+
+static int setup_volatile(const char *directory) {
+ bool tmpfs_mounted = false, bind_mounted = false;
+ char template[] = "/tmp/nspawn-volatile-XXXXXX";
+ const char *f, *t;
+ int r;
+
+ assert(directory);
+
+ if (arg_volatile != VOLATILE_YES)
+ return 0;
+
+ /* --volatile=yes means we mount a tmpfs to the root dir, and
+ the original /usr to use inside it, and that read-only. */
+
+ if (!mkdtemp(template))
+ return log_error_errno(errno, "Failed to create temporary directory: %m");
+
+ if (mount("tmpfs", template, "tmpfs", MS_STRICTATIME, "mode=755") < 0) {
+ log_error_errno(errno, "Failed to mount tmpfs for root directory: %m");
+ r = -errno;
+ goto fail;
+ }
+
+ tmpfs_mounted = true;
+
+ f = strappenda(directory, "/usr");
+ t = strappenda(template, "/usr");
+
+ r = mkdir(t, 0755);
+ if (r < 0 && errno != EEXIST) {
+ log_error_errno(errno, "Failed to create %s: %m", t);
+ r = -errno;
+ goto fail;
+ }
+
+ if (mount(f, t, "bind", MS_BIND|MS_REC, NULL) < 0) {
+ log_error_errno(errno, "Failed to create /usr bind mount: %m");
+ r = -errno;
+ goto fail;
+ }
+
+ bind_mounted = true;
+
+ r = bind_remount_recursive(t, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to remount %s read-only: %m", t);
+ goto fail;
+ }
+
+ if (mount(template, directory, NULL, MS_MOVE, NULL) < 0) {
+ log_error_errno(errno, "Failed to move root mount: %m");
+ r = -errno;
+ goto fail;
+ }
+
+ rmdir(template);