diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-09-06 06:14:14 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-09-06 06:22:26 +0200 |
commit | 2c2511aa734c507e04e06d273b474acacac9d486 (patch) | |
tree | 8175d85c61437afe89e482585a957ad99676fed5 /src/nspawn/nspawn-mount.c | |
parent | nspawn: use strv_extend() and friends to build directories passed to remount_... (diff) | |
download | systemd-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.c | 35 |
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; |