]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl-logind: auto soft-reboot only if /run/nextroot/ is mountpoint 32136/head
authorMike Yuan <me@yhndnzj.com>
Sun, 7 Apr 2024 11:33:37 +0000 (19:33 +0800)
committerMike Yuan <me@yhndnzj.com>
Sun, 7 Apr 2024 12:02:40 +0000 (20:02 +0800)
Consider the following case: a user sets up a minimum rootfs for
file system maintenance work in /run/nextroot/ dir directly. When
they're done, they expect 'systemctl reboot' to perform a full reboot.
But they keep soft-rebooting back to the tmpfs root, until they
find out about $SYSTEMCTL_SKIP_AUTO_SOFT_REBOOT.

So currently, when /run/nextroot/ is a normal dir, pid1 automatically
turns it into a bind mount to soft-reboot into. This is good, but when
combined with automatic soft-reboot it has an arguably unexpected
behavior, since /run/nextroot/ can never go away in such a case.
OTOH, if /run/nextroot/ is a mountpoint in the first place, the mount
is *moved* so a second reboot would not trigger auto soft-reboot.
Let's just make things more friendly to users, and do auto soft-reboot
only if /run/nextroot/ is also a mountpoint.

src/systemctl/systemctl-logind.c

index 2e35413b5fd2ccacbb6f3affa196a1700bcf2f27..1147c96683d8f0fe7b9b835fd9b3381c64304583 100644 (file)
@@ -7,6 +7,7 @@
 #include "bus-error.h"
 #include "bus-locator.h"
 #include "login-util.h"
+#include "mountpoint-util.h"
 #include "process-util.h"
 #include "systemctl-logind.h"
 #include "systemctl-start-unit.h"
@@ -84,9 +85,12 @@ int logind_reboot(enum action a) {
         SET_FLAG(flags,
                  SD_LOGIND_REBOOT_VIA_KEXEC,
                  a == ACTION_KEXEC || (a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_KEXEC") <= 0));
+        /* Try to soft-reboot if /run/nextroot/ is a valid OS tree, but only if it's also a mount point.
+         * Otherwise, if people store new rootfs directly on /run/ tmpfs, 'systemctl reboot' would always
+         * soft-reboot, as /run/nextroot/ can never go away. */
         SET_FLAG(flags,
                  SD_LOGIND_SOFT_REBOOT_IF_NEXTROOT_SET_UP,
-                 a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_SOFT_REBOOT") <= 0);
+                 a == ACTION_REBOOT && getenv_bool("SYSTEMCTL_SKIP_AUTO_SOFT_REBOOT") <= 0 && path_is_mount_point("/run/nextroot") > 0);
         SET_FLAG(flags, SD_LOGIND_SOFT_REBOOT, a == ACTION_SOFT_REBOOT);
 
         r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);