X Tutup
Skip to content

Commit 7d54a03

Browse files
committed
core: retry unmounting until we are done, in case of stacked mounts
1 parent b1acce8 commit 7d54a03

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/core/mount.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
#include "exit-status.h"
4646
#include "def.h"
4747

48+
#define RETRY_UMOUNT_MAX 32
49+
4850
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
4951
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
5052

@@ -867,20 +869,28 @@ static void mount_enter_unmounting(Mount *m) {
867869

868870
assert(m);
869871

872+
/* Start counting our attempts */
873+
if (!IN_SET(m->state,
874+
MOUNT_UNMOUNTING,
875+
MOUNT_UNMOUNTING_SIGTERM,
876+
MOUNT_UNMOUNTING_SIGKILL))
877+
m->n_retry_umount = 0;
878+
870879
m->control_command_id = MOUNT_EXEC_UNMOUNT;
871880
m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
872881

873-
if ((r = exec_command_set(
874-
m->control_command,
882+
r = exec_command_set(m->control_command,
875883
"/bin/umount",
876884
"-n",
877885
m->where,
878-
NULL)) < 0)
886+
NULL);
887+
if (r < 0)
879888
goto fail;
880889

881890
mount_unwatch_control_pid(m);
882891

883-
if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
892+
r = mount_spawn(m, m->control_command, &m->control_pid);
893+
if (r < 0)
884894
goto fail;
885895

886896
mount_set_state(m, MOUNT_UNMOUNTING);
@@ -1239,9 +1249,31 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
12391249
case MOUNT_UNMOUNTING_SIGKILL:
12401250
case MOUNT_UNMOUNTING_SIGTERM:
12411251

1242-
if (f == MOUNT_SUCCESS)
1243-
mount_enter_dead(m, f);
1244-
else if (m->from_proc_self_mountinfo)
1252+
if (f == MOUNT_SUCCESS) {
1253+
1254+
if (m->from_proc_self_mountinfo) {
1255+
1256+
/* Still a mount point? If so, let's
1257+
* try again. Most likely there were
1258+
* multiple mount points stacked on
1259+
* top of each other. Note that due to
1260+
* the io event priority logic we can
1261+
* be sure the new mountinfo is loaded
1262+
* before we process the SIGCHLD for
1263+
* the mount command. */
1264+
1265+
if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
1266+
log_unit_debug(u->id, "%s: mount still present, trying again.", u->id);
1267+
m->n_retry_umount++;
1268+
mount_enter_unmounting(m);
1269+
} else {
1270+
log_unit_debug(u->id, "%s: mount still present after %u attempts to unmount, giving up.", u->id, m->n_retry_umount);
1271+
mount_enter_mounted(m, f);
1272+
}
1273+
} else
1274+
mount_enter_dead(m, f);
1275+
1276+
} else if (m->from_proc_self_mountinfo)
12451277
mount_enter_mounted(m, f);
12461278
else
12471279
mount_enter_dead(m, f);

src/core/mount.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ struct Mount {
112112
pid_t control_pid;
113113

114114
sd_event_source *timer_event_source;
115+
116+
unsigned n_retry_umount;
115117
};
116118

117119
extern const UnitVTable mount_vtable;

0 commit comments

Comments
 (0)
X Tutup