Skip to content

Commit

Permalink
switch-root: use MS_REC for /run, unless we are soft-rebooting
Browse files Browse the repository at this point in the history
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 7c764d4

Fixes systemd#28452
  • Loading branch information
bluca committed Jul 22, 2023
1 parent acfff02 commit 378a6b8
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_SOFT_REBOOT : 0));
if (r < 0)
log_error_errno(r, "Failed to switch root, trying to continue: %m");
}
Expand Down
7 changes: 6 additions & 1 deletion src/shared/switch-root.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@ 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_SOFT_REBOOT) ? MS_REC : 0);
struct {
const char *path;
unsigned long mount_flags;
} 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 */
{ "/run", run_mount_flags}, /* Recursive except on soft reboot, see above */
{ 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 */
Expand Down
1 change: 1 addition & 0 deletions src/shared/switch-root.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
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_SOFT_REBOOT = 1 << 2, /* move /run without MS_REC */
} SwitchRootFlags;

int switch_root(const char *new_root, const char *old_root_after, SwitchRootFlags flags);

0 comments on commit 378a6b8

Please sign in to comment.