nspawn: optionally don't mount a tmpfs over /tmp (#10294)
authorLennart Poettering <lennart@poettering.net>
Mon, 8 Oct 2018 16:32:03 +0000 (18:32 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 8 Oct 2018 16:32:03 +0000 (18:32 +0200)
nspawn: optionally, don't mount a tmpfs on /tmp

Fixes: #10260

docs/ENVIRONMENT.md
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn.c

index 9d598a6..0c99152 100644 (file)
@@ -73,6 +73,9 @@ systemd-nspawn:
 
 * `$SYSTEMD_NSPAWN_LOCK=0` — if set, do not lock container images when running.
 
+* `$SYSTEMD_NSPAWN_TMPFS_TMP=0` — if set, do not overmount /tmp in the
+  container with a tmpfs, but leave the directory from the image in place.
+
 systemd-logind:
 
 * `$SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1` — if set, report that
index 5bef6ae..322b974 100644 (file)
@@ -543,7 +543,7 @@ int mount_all(const char *dest,
 
                 /* Then we list outer child mounts (i.e. mounts applied *before* entering user namespacing) */
                 { "tmpfs",           "/tmp",            "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
-                  MOUNT_FATAL },
+                  MOUNT_FATAL|MOUNT_APPLY_TMPFS_TMP },
                 { "tmpfs",           "/sys",            "tmpfs", "mode=555",  MS_NOSUID|MS_NOEXEC|MS_NODEV,
                   MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
                 { "sysfs",           "/sys",            "sysfs", NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,
@@ -570,6 +570,7 @@ int mount_all(const char *dest,
         bool netns = (mount_settings & MOUNT_APPLY_APIVFS_NETNS);
         bool ro = (mount_settings & MOUNT_APPLY_APIVFS_RO);
         bool in_userns = (mount_settings & MOUNT_IN_USERNS);
+        bool tmpfs_tmp = (mount_settings & MOUNT_APPLY_TMPFS_TMP);
         size_t k;
         int r;
 
@@ -587,6 +588,9 @@ int mount_all(const char *dest,
                 if (!ro && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_APIVFS_RO))
                         continue;
 
+                if (!tmpfs_tmp && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_TMPFS_TMP))
+                        continue;
+
                 r = chase_symlinks(mount_table[k].where, dest, CHASE_NONEXISTENT|CHASE_PREFIX_ROOT, &where);
                 if (r < 0)
                         return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where);
index db55759..8051a7d 100644 (file)
@@ -14,6 +14,7 @@ typedef enum MountSettingsMask {
         MOUNT_APPLY_APIVFS_NETNS = 1 << 4, /* if set, /proc/sys/net will be mounted read-write.
                                                Works only if MOUNT_APPLY_APIVFS_RO is also set. */
         MOUNT_INACCESSIBLE_REG   = 1 << 5, /* if set, create an inaccessible regular file first and use as bind mount source */
+        MOUNT_APPLY_TMPFS_TMP    = 1 << 6, /* if set, /tmp will be mounted as tmpfs */
 } MountSettingsMask;
 
 typedef enum CustomMountType {
index 1e20f46..3afc66f 100644 (file)
@@ -189,7 +189,7 @@ static const char *arg_container_service_name = "systemd-nspawn";
 static bool arg_notify_ready = false;
 static bool arg_use_cgns = true;
 static unsigned long arg_clone_ns_flags = CLONE_NEWIPC|CLONE_NEWPID|CLONE_NEWUTS;
-static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO;
+static MountSettingsMask arg_mount_settings = MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_TMPFS_TMP;
 static void *arg_root_hash = NULL;
 static size_t arg_root_hash_size = 0;
 static char **arg_syscall_whitelist = NULL;
@@ -402,8 +402,14 @@ static void parse_share_ns_env(const char *name, unsigned long ns_flag) {
 }
 
 static void parse_mount_settings_env(void) {
-        int r;
         const char *e;
+        int r;
+
+        r = getenv_bool("SYSTEMD_NSPAWN_TMPFS_TMP");
+        if (r >= 0)
+                SET_FLAG(arg_mount_settings, MOUNT_APPLY_TMPFS_TMP, r > 0);
+        else if (r != -ENXIO)
+                log_warning_errno(r, "Failed to parse $SYSTEMD_NSPAWN_TMPFS_TMP, ignoring: %m");
 
         e = getenv("SYSTEMD_NSPAWN_API_VFS_WRITABLE");
         if (!e)