diff options
author | Luca Boccassi <bluca@debian.org> | 2023-07-18 16:44:27 +0200 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2023-07-18 18:26:02 +0200 |
commit | 3f37a82545d461abdbdea8d6f255d63797e6660c (patch) | |
tree | f03dd4af07bdc373cd4218e383833612a7df2231 /src/core/execute.c | |
parent | Revert "packit: temporarily use older Rawhide spec" (diff) | |
download | systemd-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.c | 16 |
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 |