1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-10 05:18:17 +03:00

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.
This commit is contained in:
Yu Watanabe 2024-09-06 13:14:14 +09:00
parent 21cd84df69
commit 2c2511aa73
3 changed files with 44 additions and 4 deletions

View 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;

View 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);

View 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(