From: Mike Yuan Date: Sun, 9 Feb 2025 22:12:15 +0000 (+0100) Subject: core/mount: properly handle REMOUNTING_* states in mount_stop() X-Git-Tag: v258.2~75 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=21389c1e22bedff813ef39307356482b8a1f8cc3;p=thirdparty%2Fsystemd.git 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. (cherry picked from commit 6ebb91d92fb5ea7d43b22bec1b76cde1230b0e12) --- diff --git a/src/core/mount.c b/src/core/mount.c index 4c7676bd590..c08ad1c98c3 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;