From: Lennart Poettering Date: Fri, 19 May 2023 13:52:43 +0000 (+0200) Subject: switch-root: disable sync() again when we switch root during shutdown X-Git-Tag: v254-rc1~298^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1795252caa681b6b16e575ae2e5bd24a48f4e376;p=thirdparty%2Fsystemd.git switch-root: disable sync() again when we switch root during shutdown Our shutdown binary that takes over as PID 1 when shutting down puts great efforts into a sync() that comes with a time-out once sync'ing process stops. If we'd add another dumb sync() here, we kinda defeat all it is good for. Hence, let's keep the sync() in for most codepats, but let's disable it for the final shutdown logic when we transition back into the exitrd. After all we sync()ed more than enough here, no need to sync() even more. --- diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index 333118f75fc..17078c04903 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 059b4603ea5..79e47c67f47 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 be4adb79d57..cdf828616ea 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: