X Tutup
Skip to content

Commit 006aabb

Browse files
committed
mount: mountinfo event is supposed to always arrive before SIGCHLD
"Due to the io event priority logic we can be sure the new mountinfo is loaded before we process the SIGCHLD for the mount command." I think this is a reasonable expectation. But if it works, then the other comment must be false: "Note that mount(8) returning and the kernel sending us a mount table change event might happen out-of-order." Therefore we can clean up the code for the latter. If this is working as advertised, then we can make sure that mount units fail if the mount we thought we were creating did not actually appear, due to races or trickery (or because /sbin/mount did something unexpected despite returning EXIT_SUCCESS). Include a specific warning message for this failure. If we give up when the mount point is still mounted after 32 successful calls to /sbin/umount, that seems a fairly similar case. So make that message a LOG_WARN as well (not LOG_DEBUG). Also, this was recently changed to only retry while umount is returning EXIT_SUCCESS; in that case in particular there would be no other messages in the log to suggest what had happened.
1 parent 25cd496 commit 006aabb

File tree

2 files changed

+19
-16
lines changed

2 files changed

+19
-16
lines changed

src/core/mount.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,23 +1280,25 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
12801280
log_unit_full(u, f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,
12811281
"Mount process exited, code=%s status=%i", sigchld_code_to_string(code), status);
12821282

1283-
/* Note that mount(8) returning and the kernel sending us a mount table change event might happen
1284-
* out-of-order. If an operation succeed we assume the kernel will follow soon too and already change into the
1285-
* resulting state. If it fails we check if the kernel still knows about the mount. and change state
1286-
* accordingly. */
1283+
/* Note that due to the io event priority logic, we can be sure the new mountinfo is loaded
1284+
* before we process the SIGCHLD for the mount command. */
12871285

12881286
switch (m->state) {
12891287

12901288
case MOUNT_MOUNTING:
1291-
case MOUNT_MOUNTING_DONE:
1289+
/* Our mount point has not appeared in mountinfo. Something went wrong. */
12921290

1293-
if (f == MOUNT_SUCCESS || m->from_proc_self_mountinfo)
1294-
/* If /bin/mount returned success, or if we see the mount point in /proc/self/mountinfo we are
1295-
* happy. If we see the first condition first, we should see the second condition
1296-
* immediately after – or /bin/mount lies to us and is broken. */
1297-
mount_enter_mounted(m, f);
1298-
else
1299-
mount_enter_dead(m, f);
1291+
if (f == MOUNT_SUCCESS) {
1292+
/* Either /bin/mount has an unexpected definition of success,
1293+
* or someone raced us and we lost. */
1294+
log_unit_warning(UNIT(m), "Mount process finished, but there is no mount.");
1295+
f = MOUNT_FAILURE_PROTOCOL;
1296+
}
1297+
mount_enter_dead(m, f);
1298+
break;
1299+
1300+
case MOUNT_MOUNTING_DONE:
1301+
mount_enter_mounted(m, f);
13001302
break;
13011303

13021304
case MOUNT_REMOUNTING:
@@ -1312,15 +1314,14 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
13121314
if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {
13131315

13141316
/* Still a mount point? If so, let's try again. Most likely there were multiple mount points
1315-
* stacked on top of each other. Note that due to the io event priority logic we can be sure
1316-
* the new mountinfo is loaded before we process the SIGCHLD for the mount command. */
1317+
* stacked on top of each other. */
13171318

13181319
if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
13191320
log_unit_debug(u, "Mount still present, trying again.");
13201321
m->n_retry_umount++;
13211322
mount_enter_unmounting(m);
13221323
} else {
1323-
log_unit_debug(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
1324+
log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
13241325
mount_enter_mounted(m, f);
13251326
}
13261327
} else
@@ -1951,6 +1952,7 @@ static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
19511952
[MOUNT_FAILURE_SIGNAL] = "signal",
19521953
[MOUNT_FAILURE_CORE_DUMP] = "core-dump",
19531954
[MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
1955+
[MOUNT_FAILURE_PROTOCOL] = "protocol",
19541956
};
19551957

19561958
DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);

src/core/mount.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ typedef enum MountExecCommand {
3535

3636
typedef enum MountResult {
3737
MOUNT_SUCCESS,
38-
MOUNT_FAILURE_RESOURCES,
38+
MOUNT_FAILURE_RESOURCES, /* a bit of a misnomer, just our catch-all error for errnos we didn't expect */
3939
MOUNT_FAILURE_TIMEOUT,
4040
MOUNT_FAILURE_EXIT_CODE,
4141
MOUNT_FAILURE_SIGNAL,
4242
MOUNT_FAILURE_CORE_DUMP,
4343
MOUNT_FAILURE_START_LIMIT_HIT,
44+
MOUNT_FAILURE_PROTOCOL,
4445
_MOUNT_RESULT_MAX,
4546
_MOUNT_RESULT_INVALID = -1
4647
} MountResult;

0 commit comments

Comments
 (0)
X Tutup