diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index 333118f75f..17078c0490 100644 --- a/src/shared/switch-root.c +++ b/src/shared/switch-root.c @@ -89,7 +89,8 @@ int switch_root(const char *new_root, * all while making them invisible/inaccessible in the file system tree for later code. That makes * sync'ing them then difficult. Let's hence issue a manual sync() here, so that we at least can * guarantee all file systems are an a good state before entering this state. */ - sync(); + if (!FLAGS_SET(flags, SWITCH_ROOT_DONT_SYNC)) + sync(); /* Work-around for kernel design: the kernel refuses MS_MOVE if any file systems are mounted * MS_SHARED. Hence remount them MS_PRIVATE here as a work-around. diff --git a/src/shared/switch-root.h b/src/shared/switch-root.h index 059b4603ea..79e47c67f4 100644 --- a/src/shared/switch-root.h +++ b/src/shared/switch-root.h @@ -5,6 +5,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 */ } SwitchRootFlags; int switch_root(const char *new_root, const char *old_root_after, SwitchRootFlags flags); diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index be4adb79d5..cdf828616e 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -165,11 +165,15 @@ static int switch_root_initramfs(void) { if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) return log_error_errno(errno, "Failed to make /run/initramfs private mount: %m"); - /* Do not detach the old root, because /run/initramfs/shutdown needs to access it. */ + /* Do not detach the old root, because /run/initramfs/shutdown needs to access it. + * + * Disable sync() during switch-root, we after all sync'ed here plenty, and a dumb sync (as opposed + * to the "smart" sync() we did here that looks at progress parameters) would defeat much of our + * efforts here. */ return switch_root( /* new_root= */ "/run/initramfs", /* old_root_after= */ "/oldroot", - /* flags= */ 0); + /* flags= */ SWITCH_ROOT_DONT_SYNC); } /* Read the following fields from /proc/meminfo: