summaryrefslogtreecommitdiffstats
path: root/src/nspawn
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-09-09 17:11:11 +0200
committerGitHub <noreply@github.com>2024-09-09 17:11:11 +0200
commit7a3223f509f2d3a569cb16fa88d17df90888c3af (patch)
treea49096ed0784ffc68f1f25ec66ecce0d00024007 /src/nspawn
parentsysupdate: Add --transfer-source= (diff)
parenttest: add test cases for --volatile= with -U (diff)
downloadsystemd-7a3223f509f2d3a569cb16fa88d17df90888c3af.tar.xz
systemd-7a3223f509f2d3a569cb16fa88d17df90888c3af.zip
Merge pull request #34258 from yuwata/nspawn-volatile-u
nspawn: make --volatile work with -U
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-mount.c35
-rw-r--r--src/nspawn/nspawn-mount.h5
-rw-r--r--src/nspawn/nspawn.c31
3 files changed, 57 insertions, 14 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;
diff --git a/src/nspawn/nspawn-mount.h b/src/nspawn/nspawn-mount.h
index 54dafa78d9..5f66bc7328 100644
--- a/src/nspawn/nspawn-mount.h
+++ b/src/nspawn/nspawn-mount.h
@@ -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);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f8bcf26b58..c911b3ff2f 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -4083,22 +4083,25 @@ static int outer_child(
if (arg_userns_mode != USER_NAMESPACE_NO &&
IN_SET(arg_userns_ownership, USER_NAMESPACE_OWNERSHIP_MAP, USER_NAMESPACE_OWNERSHIP_AUTO) &&
arg_uid_shift != 0) {
- _cleanup_free_ char *usr_subtree = NULL;
- char *dirs[3];
- size_t i = 0;
+ _cleanup_strv_free_ char **dirs = NULL;
- dirs[i++] = (char*) directory;
+ if (arg_volatile_mode != VOLATILE_YES) {
+ r = strv_extend(&dirs, directory);
+ if (r < 0)
+ return log_oom();
+ }
- if (dissected_image && dissected_image->partitions[PARTITION_USR].found) {
- usr_subtree = path_join(directory, "/usr");
- if (!usr_subtree)
+ if ((dissected_image && dissected_image->partitions[PARTITION_USR].found) ||
+ arg_volatile_mode == VOLATILE_YES) {
+ char *s = path_join(directory, "/usr");
+ if (!s)
return log_oom();
- dirs[i++] = usr_subtree;
+ r = strv_consume(&dirs, s);
+ if (r < 0)
+ return log_oom();
}
- dirs[i] = NULL;
-
r = remount_idmap(dirs, arg_uid_shift, arg_uid_range, UID_INVALID, UID_INVALID, REMOUNT_IDMAPPING_HOST_ROOT);
if (r == -EINVAL || ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
/* This might fail because the kernel or file system doesn't support idmapping. We
@@ -4118,6 +4121,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(