]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/mount: properly handle REMOUNTING_* states in mount_stop()
authorMike Yuan <me@yhndnzj.com>
Sun, 9 Feb 2025 22:12:15 +0000 (23:12 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 6 Nov 2025 21:26:42 +0000 (21:26 +0000)
Currently, mount_stop() simply turns REMOUNTING_* into corresponding
UNMOUNTING_* states. However the transition is bogus, because
the interruption of remount does not bring down the mount.
Let's instead follow the logic of service_stop(), i.e. terminate
the remount process and spawn umount.

(cherry picked from commit 6ebb91d92fb5ea7d43b22bec1b76cde1230b0e12)

src/core/mount.c

index 4c7676bd590471f1f145bef4f59a2aa7ab243eec..c08ad1c98c3c87b7646050865311a6f737db9699 100644 (file)
@@ -1390,6 +1390,7 @@ static int mount_start(Unit *u) {
 
 static int mount_stop(Unit *u) {
         Mount *m = ASSERT_PTR(MOUNT(u));
+        int r;
 
         switch (m->state) {
 
@@ -1401,21 +1402,22 @@ static int mount_stop(Unit *u) {
 
         case MOUNT_MOUNTING:
         case MOUNT_MOUNTING_DONE:
-        case MOUNT_REMOUNTING:
                 /* If we are still waiting for /bin/mount, we go directly into kill mode. */
                 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_SUCCESS);
                 return 0;
 
+        case MOUNT_REMOUNTING:
         case MOUNT_REMOUNTING_SIGTERM:
-                /* If we are already waiting for a hung remount, convert this to the matching unmounting state */
-                mount_set_state(m, MOUNT_UNMOUNTING_SIGTERM);
-                return 0;
+                assert(pidref_is_set(&m->control_pid));
 
-        case MOUNT_REMOUNTING_SIGKILL:
-                /* as above */
-                mount_set_state(m, MOUNT_UNMOUNTING_SIGKILL);
-                return 0;
+                r = pidref_kill_and_sigcont(&m->control_pid, SIGKILL);
+                if (r < 0)
+                        log_unit_debug_errno(u, r,
+                                             "Failed to kill remount process " PID_FMT ", ignoring: %m",
+                                             m->control_pid.pid);
 
+                _fallthrough_;
+        case MOUNT_REMOUNTING_SIGKILL:
         case MOUNT_MOUNTED:
                 mount_enter_unmounting(m);
                 return 1;