mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
switch-root: use MS_REC for /run, unless we are soft-rebooting
There are applications that rely on mounts under /run surviving the
switch from initrd to rootfs, so use MS_REC unless we are soft
rebooting.
Follow-up for 7c764d4599
Fixes https://github.com/systemd/systemd/issues/28452
This commit is contained in:
parent
acfff02c8f
commit
b12d41a8bb
@ -1884,7 +1884,8 @@ static int do_reexecute(
|
||||
if (switch_root_dir) {
|
||||
r = switch_root(/* new_root= */ switch_root_dir,
|
||||
/* old_root_after= */ NULL,
|
||||
/* flags= */ objective == MANAGER_SWITCH_ROOT ? SWITCH_ROOT_DESTROY_OLD_ROOT : 0);
|
||||
/* flags= */ (objective == MANAGER_SWITCH_ROOT ? SWITCH_ROOT_DESTROY_OLD_ROOT : 0) |
|
||||
(objective == MANAGER_SOFT_REBOOT ? SWITCH_ROOT_SKIP_RECURSIVE_RUN : 0));
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to switch root, trying to continue: %m");
|
||||
}
|
||||
|
@ -30,17 +30,23 @@ int switch_root(const char *new_root,
|
||||
const char *old_root_after, /* path below the new root, where to place the old root after the transition; may be NULL to unmount it */
|
||||
SwitchRootFlags flags) {
|
||||
|
||||
/* Stuff mounted below /run we don't save on soft reboot, as it might have lost its relevance, i.e.
|
||||
* credentials, removable media and such, we rather want that the new boot mounts this fresh.
|
||||
* But on the switch from initrd we do use MS_REC, as it is expected that mounts set up in /run
|
||||
* are maintained. */
|
||||
unsigned long run_mount_flags = MS_BIND|(!FLAGS_SET(flags, SWITCH_ROOT_SKIP_RECURSIVE_RUN) ? MS_REC : 0);
|
||||
struct {
|
||||
const char *path;
|
||||
unsigned long mount_flags;
|
||||
bool skip_if_run_is_rec; /* For child mounts of /run, if it's moved recursively no need to handle */
|
||||
} transfer_table[] = {
|
||||
{ "/dev", MS_BIND|MS_REC }, /* Recursive, because we want to save the original /dev/shm + /dev/pts and similar */
|
||||
{ "/sys", MS_BIND|MS_REC }, /* Similar, we want to retain various API VFS, or the cgroupv1 /sys/fs/cgroup/ tree */
|
||||
{ "/proc", MS_BIND|MS_REC }, /* Similar */
|
||||
{ "/run", MS_BIND }, /* Stuff mounted below this we don't save, as it might have lost its relevance, i.e. credentials, removable media and such, we rather want that the new boot mounts this fresh */
|
||||
{ SYSTEM_CREDENTIALS_DIRECTORY, MS_BIND }, /* Credentials passed into the system should survive */
|
||||
{ ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, MS_BIND }, /* Similar */
|
||||
{ "/run/host", MS_BIND|MS_REC }, /* Host supplied hierarchy should also survive */
|
||||
{ "/dev", MS_BIND|MS_REC, false }, /* Recursive, because we want to save the original /dev/shm + /dev/pts and similar */
|
||||
{ "/sys", MS_BIND|MS_REC, false }, /* Similar, we want to retain various API VFS, or the cgroupv1 /sys/fs/cgroup/ tree */
|
||||
{ "/proc", MS_BIND|MS_REC, false }, /* Similar */
|
||||
{ "/run", run_mount_flags, false }, /* Recursive except on soft reboot, see above */
|
||||
{ SYSTEM_CREDENTIALS_DIRECTORY, MS_BIND, true }, /* Credentials passed into the system should survive */
|
||||
{ ENCRYPTED_SYSTEM_CREDENTIALS_DIRECTORY, MS_BIND, true }, /* Similar */
|
||||
{ "/run/host", MS_BIND|MS_REC, true }, /* Host supplied hierarchy should also survive */
|
||||
};
|
||||
|
||||
_cleanup_close_ int old_root_fd = -EBADF, new_root_fd = -EBADF;
|
||||
@ -112,6 +118,9 @@ int switch_root(const char *new_root,
|
||||
FOREACH_ARRAY(transfer, transfer_table, ELEMENTSOF(transfer_table)) {
|
||||
_cleanup_free_ char *chased = NULL;
|
||||
|
||||
if (transfer->skip_if_run_is_rec && !FLAGS_SET(flags, SWITCH_ROOT_SKIP_RECURSIVE_RUN))
|
||||
continue;
|
||||
|
||||
if (access(transfer->path, F_OK) < 0) {
|
||||
log_debug_errno(errno, "Path '%s' to move to target root directory, not found, ignoring: %m", transfer->path);
|
||||
continue;
|
||||
|
@ -4,8 +4,9 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum SwitchRootFlags {
|
||||
SWITCH_ROOT_DESTROY_OLD_ROOT = 1 << 0, /* rm -rf old root when switching – under the condition that it is backed by non-persistent tmpfs/ramfs/… */
|
||||
SWITCH_ROOT_DONT_SYNC = 1 << 1, /* don't call sync() immediately before switching root */
|
||||
SWITCH_ROOT_DESTROY_OLD_ROOT = 1 << 0, /* rm -rf old root when switching – under the condition that it is backed by non-persistent tmpfs/ramfs/… */
|
||||
SWITCH_ROOT_DONT_SYNC = 1 << 1, /* don't call sync() immediately before switching root */
|
||||
SWITCH_ROOT_SKIP_RECURSIVE_RUN = 1 << 2, /* move /run without MS_REC */
|
||||
} SwitchRootFlags;
|
||||
|
||||
int switch_root(const char *new_root, const char *old_root_after, SwitchRootFlags flags);
|
||||
|
Loading…
Reference in New Issue
Block a user