summaryrefslogtreecommitdiffstats
path: root/src/nspawn/nspawn-mount.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-09-06 06:14:14 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-09-06 06:22:26 +0200
commit2c2511aa734c507e04e06d273b474acacac9d486 (patch)
tree8175d85c61437afe89e482585a957ad99676fed5 /src/nspawn/nspawn-mount.c
parentnspawn: use strv_extend() and friends to build directories passed to remount_... (diff)
downloadsystemd-2c2511aa734c507e04e06d273b474acacac9d486.tar.xz
systemd-2c2511aa734c507e04e06d273b474acacac9d486.zip
nspawn: mount /var/ after remount_idmap() when --volatile=state
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.
Diffstat (limited to 'src/nspawn/nspawn-mount.c')
-rw-r--r--src/nspawn/nspawn-mount.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index c2bd4f6c30..874d54e734 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -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;