]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/nspawn/nspawn-mount.c
nspawn: split out VolatileMode definitions
[thirdparty/systemd.git] / src / nspawn / nspawn-mount.c
index 291a88a9ac5035a013d79b65a35b9db9aac23fc0..72c007f204c657472dc153f3b247bb6f0a5cc025 100644 (file)
@@ -75,6 +75,11 @@ void custom_mount_free_all(CustomMount *l, unsigned n) {
                         free(m->work_dir);
                 }
 
+                if (m->rm_rf_tmpdir) {
+                        (void) rm_rf(m->rm_rf_tmpdir, REMOVE_ROOT|REMOVE_PHYSICAL);
+                        free(m->rm_rf_tmpdir);
+                }
+
                 strv_free(m->lower);
         }
 
@@ -142,6 +147,24 @@ int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
 
                         free(m->source);
                         m->source = s;
+                } else {
+                        /* No source specified? In that case, use a throw-away temporary directory in /var/tmp */
+
+                        m->rm_rf_tmpdir = strdup("/var/tmp/nspawn-temp-XXXXXX");
+                        if (!m->rm_rf_tmpdir)
+                                return log_oom();
+
+                        if (!mkdtemp(m->rm_rf_tmpdir)) {
+                                m->rm_rf_tmpdir = mfree(m->rm_rf_tmpdir);
+                                return log_error_errno(errno, "Failed to acquire temporary directory: %m");
+                        }
+
+                        m->source = strjoin(m->rm_rf_tmpdir, "/src");
+                        if (!m->source)
+                                return log_oom();
+
+                        if (mkdir(m->source, 0755) < 0)
+                                return log_error_errno(errno, "Failed to create %s: %m", m->source);
                 }
 
                 if (m->type == CUSTOM_MOUNT_OVERLAY) {
@@ -207,8 +230,11 @@ int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only
                         return -ENOMEM;
         }
 
-        if (!source_path_is_valid(source))
+        if (isempty(source))
+                source = NULL;
+        else if (!source_path_is_valid(source))
                 return -EINVAL;
+
         if (!path_is_absolute(destination))
                 return -EINVAL;
 
@@ -288,19 +314,26 @@ int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_o
                 if (!destination)
                         return -ENOMEM;
         } else {
-                int i;
+                char **i;
 
                 /* If more than two parameters are specified, the last one is the destination, the second to last one
                  * the "upper", and all before that the "lower" directories. */
 
-                for (i = 0; i < k - 1; i++)
-                        if (!source_path_is_valid(lower[i]))
-                                return -EINVAL;
-
                 destination = lower[k - 1];
                 upper = lower[k - 2];
                 lower[k - 2] = NULL;
 
+                STRV_FOREACH(i, lower)
+                        if (!source_path_is_valid(*i))
+                                return -EINVAL;
+
+                /* If the upper directory is unspecified, then let's create it automatically as a throw-away directory
+                 * in /var/tmp */
+                if (isempty(upper))
+                        upper = NULL;
+                else if (!source_path_is_valid(upper))
+                        return -EINVAL;
+
                 if (!path_is_absolute(destination))
                         return -EINVAL;
         }
@@ -517,9 +550,9 @@ int mount_all(const char *dest,
                 { NULL,                  "/proc/sys",           NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
                 { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND,                                                               MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ...*/
                 { NULL,                  "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,             MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
-                { "tmpfs",               "/tmp",                "tmpfs", "mode=1777", MS_STRICTATIME,                                            MOUNT_FATAL|MOUNT_IN_USERNS },
 
                 /* outer child mounts */
+                { "tmpfs",               "/tmp",                "tmpfs", "mode=1777", MS_STRICTATIME,                                            MOUNT_FATAL },
                 { "tmpfs",               "/sys",                "tmpfs", "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV,                              MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
                 { "sysfs",               "/sys",                "sysfs", NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,                    MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO },    /* skipped if above was mounted */
                 { "sysfs",               "/sys",                "sysfs", NULL,                  MS_NOSUID|MS_NOEXEC|MS_NODEV,                    MOUNT_FATAL },                          /* skipped if above was mounted */
@@ -554,9 +587,9 @@ int mount_all(const char *dest,
                 if (!ro && (bool)(mount_table[k].mount_settings & MOUNT_APPLY_APIVFS_RO))
                         continue;
 
-                r = chase_symlinks(mount_table[k].where, dest, CHASE_NON_EXISTING|CHASE_PREFIX_ROOT, &where);
+                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: %m", mount_table[k].where);
+                        return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where);
 
                 r = path_is_mount_point(where, NULL, 0);
                 if (r < 0 && r != -ENOENT)
@@ -653,9 +686,9 @@ static int mount_bind(const char *dest, CustomMount *m) {
         if (stat(m->source, &source_st) < 0)
                 return log_error_errno(errno, "Failed to stat %s: %m", m->source);
 
-        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NON_EXISTING, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
         if (r < 0)
-                return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
+                return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
         if (r > 0) { /* Path exists already? */
 
                 if (stat(where, &dest_st) < 0)
@@ -715,9 +748,9 @@ static int mount_tmpfs(
         assert(dest);
         assert(m);
 
-        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NON_EXISTING, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
         if (r < 0)
-                return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
+                return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
         if (r == 0) { /* Doesn't exist yet? */
                 r = mkdir_p_label(where, 0755);
                 if (r < 0)
@@ -756,9 +789,9 @@ static int mount_overlay(const char *dest, CustomMount *m) {
         assert(dest);
         assert(m);
 
-        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NON_EXISTING, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &where);
         if (r < 0)
-                return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
+                return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, m->destination);
         if (r == 0) { /* Doesn't exist yet? */
                 r = mkdir_label(where, 0755);
                 if (r < 0)
@@ -1316,21 +1349,3 @@ fail:
         (void) rmdir(template);
         return r;
 }
-
-VolatileMode volatile_mode_from_string(const char *s) {
-        int b;
-
-        if (isempty(s))
-                return _VOLATILE_MODE_INVALID;
-
-        b = parse_boolean(s);
-        if (b > 0)
-                return VOLATILE_YES;
-        if (b == 0)
-                return VOLATILE_NO;
-
-        if (streq(s, "state"))
-                return VOLATILE_STATE;
-
-        return _VOLATILE_MODE_INVALID;
-}