Skip to content

(RHEL-13159) core/mount: if umount(8) fails but mount disappeared, assume success #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/core/mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,8 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {

if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM))
mount_set_reload_result(m, f);
else if (m->result == MOUNT_SUCCESS)
else if (m->result == MOUNT_SUCCESS && !IN_SET(m->state, MOUNT_MOUNTING, MOUNT_UNMOUNTING))
/* MOUNT_MOUNTING and MOUNT_UNMOUNTING states need to be patched, see below. */
m->result = f;

if (m->control_command) {
Expand All @@ -1462,11 +1463,11 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
switch (m->state) {

case MOUNT_MOUNTING:
/* Our mount point has not appeared in mountinfo. Something went wrong. */
/* Our mount point has not appeared in mountinfo. Something went wrong. */

if (f == MOUNT_SUCCESS) {
/* Either /bin/mount has an unexpected definition of success,
* or someone raced us and we lost. */
/* Either /bin/mount has an unexpected definition of success, or someone raced us
* and we lost. */
log_unit_warning(UNIT(m), "Mount process finished, but there is no mount.");
f = MOUNT_FAILURE_PROTOCOL;
}
Expand All @@ -1484,9 +1485,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
break;

case MOUNT_UNMOUNTING:

if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {

/* Still a mount point? If so, let's try again. Most likely there were multiple mount points
* stacked on top of each other. We might exceed the timeout specified by the user overall,
* but we will stop as soon as any one umount times out. */
Expand All @@ -1499,13 +1498,18 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
mount_enter_mounted(m, f);
}
} else if (f == MOUNT_FAILURE_EXIT_CODE && !m->from_proc_self_mountinfo) {
/* Hmm, umount process spawned by us failed, but the mount disappeared anyway?
* Maybe someone else is trying to unmount at the same time. */
log_unit_notice(u, "Mount disappeared even though umount process failed, continuing.");
mount_enter_dead(m, MOUNT_SUCCESS);
} else
mount_enter_dead_or_mounted(m, f);

break;

case MOUNT_UNMOUNTING_SIGKILL:
case MOUNT_UNMOUNTING_SIGTERM:
case MOUNT_UNMOUNTING_SIGKILL:
mount_enter_dead_or_mounted(m, f);
break;

Expand Down Expand Up @@ -2040,7 +2044,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
* then remove it because of an internal error. E.g., fuse.sshfs seems
* to do that when the connection fails. See #17617. To handle such the
* case, let's once set the state back to mounting. Then, the unit can
* correctly enter the failed state later in mount_sigchld(). */
* correctly enter the failed state later in mount_sigchld_event(). */
mount_set_state(mount, MOUNT_MOUNTING);
break;

Expand Down