dd65c9
From d9df4d0ed03f56036b04e19a8e6be2c028c4a72e 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
c62b8e
index 20a5de8cae..182ba5240f 100644
99d80a
--- a/src/core/automount.c
99d80a
+++ b/src/core/automount.c
dd65c9
@@ -712,7 +712,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;
dd65c9
@@ -744,18 +744,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);
dd65c9
@@ -979,7 +983,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: