From 6ebb91d92fb5ea7d43b22bec1b76cde1230b0e12 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sun, 9 Feb 2025 23:12:15 +0100 Subject: [PATCH] core/mount: properly handle REMOUNTING_* states in mount_stop() 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. --- src/core/mount.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index edbf7d201ca..6e536ecc6b8 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -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; -- 2.47.3