summaryrefslogtreecommitdiffstats
path: root/src/core/execute.c
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2023-07-18 16:44:27 +0200
committerLuca Boccassi <bluca@debian.org>2023-07-18 18:26:02 +0200
commit3f37a82545d461abdbdea8d6f255d63797e6660c (patch)
treef03dd4af07bdc373cd4218e383833612a7df2231 /src/core/execute.c
parentRevert "packit: temporarily use older Rawhide spec" (diff)
downloadsystemd-3f37a82545d461abdbdea8d6f255d63797e6660c.tar.xz
systemd-3f37a82545d461abdbdea8d6f255d63797e6660c.zip
core: copy the host's os-release for /run/host/os-release
Currently for portable services we automatically add a bind mount os-release -> /run/host/os-release. This becomes problematic for the soft-reboot case, as it's likely that portable services will be configured to survive it, and thus would forever keep a reference to the old host's os-release, which would be a problem because it becomes outdated, and also it stops the old rootfs from being garbage collected. Create a copy when the manager starts under /run/systemd/propagate instead, and bind mount that for all services using RootDirectory=/RootImage=, so that on soft-reboot the content gets updated (without creating a new file, so the existing bind mounts will see the new content too). This expands the /run/host/os-release protocol to more services, but I think that's a nice thing to have too. Closes https://github.com/systemd/systemd/issues/28023
Diffstat (limited to 'src/core/execute.c')
-rw-r--r--src/core/execute.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index 067f7bdb8b..9dafdffa08 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -3967,7 +3967,7 @@ static int apply_mount_namespace(
_cleanup_strv_free_ char **empty_directories = NULL, **symlinks = NULL,
**read_write_paths_cleanup = NULL;
_cleanup_free_ char *creds_path = NULL, *incoming_dir = NULL, *propagate_dir = NULL,
- *extension_dir = NULL;
+ *extension_dir = NULL, *host_os_release = NULL;
const char *root_dir = NULL, *root_image = NULL, *tmp_dir = NULL, *var_tmp_dir = NULL;
char **read_write_paths;
NamespaceInfo ns_info;
@@ -4087,11 +4087,24 @@ static int apply_mount_namespace(
extension_dir = strdup("/run/systemd/unit-extensions");
if (!extension_dir)
return -ENOMEM;
+
+ /* If running under a different root filesystem, propagate the host's os-release. We make a
+ * copy rather than just bind mounting it, so that it can be updated on soft-reboot. */
+ if (root_dir || root_image) {
+ host_os_release = strdup("/run/systemd/propagate/os-release");
+ if (!host_os_release)
+ return -ENOMEM;
+ }
} else {
assert(params->runtime_scope == RUNTIME_SCOPE_USER);
if (asprintf(&extension_dir, "/run/user/" UID_FMT "/systemd/unit-extensions", geteuid()) < 0)
return -ENOMEM;
+
+ if (root_dir || root_image) {
+ if (asprintf(&host_os_release, "/run/user/" UID_FMT "/systemd/propagate/os-release", geteuid()) < 0)
+ return -ENOMEM;
+ }
}
if (root_image) {
@@ -4139,6 +4152,7 @@ static int apply_mount_namespace(
incoming_dir,
extension_dir,
root_dir || root_image ? params->notify_socket : NULL,
+ host_os_release,
error_path);
/* If we couldn't set up the namespace this is probably due to a missing capability. setup_namespace() reports