1ff636
From 6b8fedd82c23f1d8c334c3081a1befebedc40f1f Mon Sep 17 00:00:00 2001
1ff636
From: Lennart Poettering <lennart@poettering.net>
1ff636
Date: Tue, 19 May 2015 13:50:36 +0200
1ff636
Subject: [PATCH] mount: don't claim a device is gone from /proc/self/mountinfo
1ff636
 before it is gone from *all* lines
1ff636
1ff636
Devices might be referenced by multiple mount points in
1ff636
/proc/self/mountinfo, hence we should consider them unmounted only after
1ff636
they disappeared from all lines, not just from one.
1ff636
1ff636
http://lists.freedesktop.org/archives/systemd-devel/2015-May/032026.html
1ff636
(cherry picked from commit fcd8b266edf0df2b85079fcf7b099cd4028740e6)
1ff636
1ff636
Cherry-picked from:
1ff636
Resolves: #1222517
1ff636
---
1ff636
 src/core/mount.c | 30 +++++++++++++++++++++++++++---
1ff636
 1 file changed, 27 insertions(+), 3 deletions(-)
1ff636
1ff636
diff --git a/src/core/mount.c b/src/core/mount.c
c62b8e
index fd4fb6f1b2..fa63f2426f 100644
1ff636
--- a/src/core/mount.c
1ff636
+++ b/src/core/mount.c
1ff636
@@ -1698,7 +1698,10 @@ fail:
1ff636
 }
1ff636
 
1ff636
 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1ff636
+        _cleanup_set_free_ Set *around = NULL, *gone = NULL;
1ff636
         Manager *m = userdata;
1ff636
+        const char *what;
1ff636
+        Iterator i;
1ff636
         Unit *u;
1ff636
         int r;
1ff636
 
1ff636
@@ -1765,6 +1768,8 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
1ff636
 
1ff636
                 if (!mount->is_mounted) {
1ff636
 
1ff636
+                        /* A mount point is gone */
1ff636
+
1ff636
                         mount->from_proc_self_mountinfo = false;
1ff636
 
1ff636
                         switch (mount->state) {
1ff636
@@ -1780,13 +1785,17 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
1ff636
                                 break;
1ff636
                         }
1ff636
 
1ff636
-                        if (mount->parameters_proc_self_mountinfo.what)
1ff636
-                                (void) device_found_node(m, mount->parameters_proc_self_mountinfo.what, false, DEVICE_FOUND_MOUNT, true);
1ff636
+                        /* Remember that this device might just have disappeared */
1ff636
+                        if (mount->parameters_proc_self_mountinfo.what) {
1ff636
 
1ff636
+                                if (set_ensure_allocated(&gone, &string_hash_ops) < 0 ||
1ff636
+                                    set_put(gone, mount->parameters_proc_self_mountinfo.what) < 0)
1ff636
+                                        log_oom(); /* we don't care too much about OOM here... */
1ff636
+                        }
1ff636
 
1ff636
                 } else if (mount->just_mounted || mount->just_changed) {
1ff636
 
1ff636
-                        /* New or changed mount entry */
1ff636
+                        /* A mount point was added or changed */
1ff636
 
1ff636
                         switch (mount->state) {
1ff636
 
1ff636
@@ -1811,12 +1820,27 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
1ff636
                                 mount_set_state(mount, mount->state);
1ff636
                                 break;
1ff636
                         }
1ff636
+
1ff636
+                        if (mount->parameters_proc_self_mountinfo.what) {
1ff636
+
1ff636
+                                if (set_ensure_allocated(&around, &string_hash_ops) < 0 ||
1ff636
+                                    set_put(around, mount->parameters_proc_self_mountinfo.what) < 0)
1ff636
+                                        log_oom();
1ff636
+                        }
1ff636
                 }
1ff636
 
1ff636
                 /* Reset the flags for later calls */
1ff636
                 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1ff636
         }
1ff636
 
1ff636
+        SET_FOREACH(what, gone, i) {
1ff636
+                if (set_contains(around, what))
1ff636
+                        continue;
1ff636
+
1ff636
+                /* Let the device units know that the device is no longer mounted */
1ff636
+                (void) device_found_node(m, what, false, DEVICE_FOUND_MOUNT, true);
1ff636
+        }
1ff636
+
1ff636
         return 0;
1ff636
 }
1ff636