]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: mount /var/ after remount_idmap() when --volatile=state
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 6 Sep 2024 04:14:14 +0000 (13:14 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 6 Sep 2024 04:22:26 +0000 (13:22 +0900)
Previously, remount_idmap() failed as /var/ was already mounted, thus
remounting (strictly speaking, unmounting old root directory) failed
with -EBUSY.

As tmpfs /var/ is mounted with picked UID shift, it should not be
remounted with idmap, but needs to be mounted after the root directory
being remounted.

This makes '-U --volatile=state' work as expected.

src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn.c

index c2bd4f6c307f4c4606318bcfdb5ee5a830fb0e05..874d54e73462cc4a79f55ee95c64eb6f4b669fc2 100644 (file)
@@ -1061,19 +1061,30 @@ bool has_custom_root_mount(const CustomMount *mounts, size_t n) {
         return false;
 }
 
-static int setup_volatile_state(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
-        _cleanup_free_ char *buf = NULL;
-        const char *p, *options;
+static int setup_volatile_state(const char *directory) {
         int r;
 
         assert(directory);
 
         /* --volatile=state means we simply overmount /var with a tmpfs, and the rest read-only. */
 
+        /* First, remount the root directory. */
         r = bind_remount_recursive(directory, MS_RDONLY, MS_RDONLY, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to remount %s read-only: %m", directory);
 
+        return 0;
+}
+
+static int setup_volatile_state_after_remount_idmap(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
+        _cleanup_free_ char *buf = NULL;
+        const char *p, *options;
+        int r;
+
+        assert(directory);
+
+        /* Then, after remount_idmap(), overmount /var/ with a tmpfs. */
+
         p = prefix_roota(directory, "/var");
         r = mkdir(p, 0755);
         if (r < 0 && errno != EEXIST)
@@ -1249,7 +1260,7 @@ int setup_volatile_mode(
                 return setup_volatile_yes(directory, uid_shift, selinux_apifs_context);
 
         case VOLATILE_STATE:
-                return setup_volatile_state(directory, uid_shift, selinux_apifs_context);
+                return setup_volatile_state(directory);
 
         case VOLATILE_OVERLAY:
                 return setup_volatile_overlay(directory, uid_shift, selinux_apifs_context);
@@ -1259,6 +1270,22 @@ int setup_volatile_mode(
         }
 }
 
+int setup_volatile_mode_after_remount_idmap(
+                const char *directory,
+                VolatileMode mode,
+                uid_t uid_shift,
+                const char *selinux_apifs_context) {
+
+        switch (mode) {
+
+        case VOLATILE_STATE:
+                return setup_volatile_state_after_remount_idmap(directory, uid_shift, selinux_apifs_context);
+
+        default:
+                return 0;
+        }
+}
+
 /* Expects *pivot_root_new and *pivot_root_old to be initialised to allocated memory or NULL. */
 int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s) {
         _cleanup_free_ char *root_new = NULL, *root_old = NULL;
index 54dafa78d9e82fd65fa6ffedce618ca79b144b35..5f66bc7328da90672e4ca618c42dec7941724e85 100644 (file)
@@ -63,6 +63,11 @@ int mount_custom(const char *dest, CustomMount *mounts, size_t n, uid_t uid_shif
 bool has_custom_root_mount(const CustomMount *mounts, size_t n);
 
 int setup_volatile_mode(const char *directory, VolatileMode mode, uid_t uid_shift, const char *selinux_apifs_context);
+int setup_volatile_mode_after_remount_idmap(
+                const char *directory,
+                VolatileMode mode,
+                uid_t uid_shift,
+                const char *selinux_apifs_context);
 
 int pivot_root_parse(char **pivot_root_new, char **pivot_root_old, const char *s);
 int setup_pivot_root(const char *directory, const char *pivot_root_new, const char *pivot_root_old);
index 9b8c8973d8a777daa0b73e14f6469529361dd8ac..655dc7c697646d5b2696e84b98c94b7d414166a9 100644 (file)
@@ -4028,6 +4028,14 @@ static int outer_child(
                 }
         }
 
+        r = setup_volatile_mode_after_remount_idmap(
+                        directory,
+                        arg_volatile_mode,
+                        arg_uid_shift,
+                        arg_selinux_apifs_context);
+        if (r < 0)
+                return r;
+
         if (dissected_image) {
                 /* Now we know the uid shift, let's now mount everything else that might be in the image. */
                 r = dissected_image_mount_and_warn(