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