dryang / rpms / systemd

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