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
This commit is contained in:
+15
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user