|
|
99d80a |
From 164bd929f1c85026f21ed493d11d3b4d1b94421d Mon Sep 17 00:00:00 2001
|
|
|
99d80a |
From: Jan Synacek <jsynacek@redhat.com>
|
|
|
99d80a |
Date: Wed, 17 Jan 2018 09:13:24 +0100
|
|
|
99d80a |
Subject: [PATCH] automount: ack automount requests even when already mounted
|
|
|
99d80a |
|
|
|
99d80a |
If a process accesses an autofs filesystem while systemd is in the
|
|
|
99d80a |
middle of starting the mount unit on top of it, it is possible for the
|
|
|
99d80a |
autofs_ptype_missing_direct request from the kernel to be received after
|
|
|
99d80a |
the mount unit has been fully started:
|
|
|
99d80a |
|
|
|
99d80a |
systemd forks and execs mount ...
|
|
|
99d80a |
... access autofs, blocks
|
|
|
99d80a |
mount exits ...
|
|
|
99d80a |
systemd receives SIGCHLD ...
|
|
|
99d80a |
... kernel sends request
|
|
|
99d80a |
systemd receives request ...
|
|
|
99d80a |
|
|
|
99d80a |
systemd needs to respond to this request, otherwise the kernel will
|
|
|
99d80a |
continue to block access to the mount point.
|
|
|
99d80a |
|
|
|
99d80a |
(cherry picked from commit e7d54bf58789545a9eb0b3964233defa0b007318)
|
|
|
99d80a |
|
|
|
99d80a |
Resolves: #1535135
|
|
|
99d80a |
---
|
|
|
99d80a |
src/core/automount.c | 28 ++++++++++++++++------------
|
|
|
99d80a |
1 file changed, 16 insertions(+), 12 deletions(-)
|
|
|
99d80a |
|
|
|
99d80a |
diff --git a/src/core/automount.c b/src/core/automount.c
|
|
|
99d80a |
index 4e066613d..9e05963e9 100644
|
|
|
99d80a |
--- a/src/core/automount.c
|
|
|
99d80a |
+++ b/src/core/automount.c
|
|
|
99d80a |
@@ -692,7 +692,7 @@ static int automount_start_expire(Automount *a) {
|
|
|
99d80a |
automount_dispatch_expire, a);
|
|
|
99d80a |
}
|
|
|
99d80a |
|
|
|
99d80a |
-static void automount_enter_runnning(Automount *a) {
|
|
|
99d80a |
+static void automount_enter_running(Automount *a) {
|
|
|
99d80a |
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
|
|
|
99d80a |
struct stat st;
|
|
|
99d80a |
int r;
|
|
|
99d80a |
@@ -718,18 +718,22 @@ static void automount_enter_runnning(Automount *a) {
|
|
|
99d80a |
goto fail;
|
|
|
99d80a |
}
|
|
|
99d80a |
|
|
|
99d80a |
- if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
|
|
|
99d80a |
+ /* The mount unit may have been explicitly started before we got the
|
|
|
99d80a |
+ * autofs request. Ack it to unblock anything waiting on the mount point. */
|
|
|
99d80a |
+ if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) {
|
|
|
99d80a |
log_unit_info(UNIT(a)->id,
|
|
|
99d80a |
"%s's automount point already active?", UNIT(a)->id);
|
|
|
99d80a |
- else {
|
|
|
99d80a |
- r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
|
|
|
99d80a |
- JOB_REPLACE, true, &error, NULL);
|
|
|
99d80a |
- if (r < 0) {
|
|
|
99d80a |
- log_unit_warning(UNIT(a)->id,
|
|
|
99d80a |
- "%s failed to queue mount startup job: %s",
|
|
|
99d80a |
- UNIT(a)->id, bus_error_message(&error, r));
|
|
|
99d80a |
- goto fail;
|
|
|
99d80a |
- }
|
|
|
99d80a |
+ automount_send_ready(a, a->tokens, 0);
|
|
|
99d80a |
+ return;
|
|
|
99d80a |
+ }
|
|
|
99d80a |
+
|
|
|
99d80a |
+ r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
|
|
|
99d80a |
+ JOB_REPLACE, true, &error, NULL);
|
|
|
99d80a |
+ if (r < 0) {
|
|
|
99d80a |
+ log_unit_warning(UNIT(a)->id,
|
|
|
99d80a |
+ "%s failed to queue mount startup job: %s",
|
|
|
99d80a |
+ UNIT(a)->id, bus_error_message(&error, r));
|
|
|
99d80a |
+ goto fail;
|
|
|
99d80a |
}
|
|
|
99d80a |
|
|
|
99d80a |
r = automount_start_expire(a);
|
|
|
99d80a |
@@ -953,7 +957,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
|
|
|
99d80a |
goto fail;
|
|
|
99d80a |
}
|
|
|
99d80a |
|
|
|
99d80a |
- automount_enter_runnning(a);
|
|
|
99d80a |
+ automount_enter_running(a);
|
|
|
99d80a |
break;
|
|
|
99d80a |
|
|
|
99d80a |
case autofs_ptype_expire_direct:
|