dcavalca / rpms / systemd

Forked from rpms/systemd 3 months ago
Clone
1abbee
From 45ff3d79f079c73c73209940cf6eaa0ea0a95708 Mon Sep 17 00:00:00 2001
1abbee
From: Franck Bui <fbui@suse.com>
1abbee
Date: Fri, 22 Jan 2016 07:18:19 +0100
1abbee
Subject: [PATCH] device: make sure to not ignore re-plugged device
1abbee
1abbee
systemd automatically mounts device unless 'noauto' is part of the
1abbee
mount options. This can happen during boot if the device is plugged at
1abbee
that time or later when the system is already running (the latter case
1abbee
is not documented AFAICS).
1abbee
1abbee
After the systemd booted, I plugged my USB device which had an entry
1abbee
in /etc/fstab with the default options and systemd automatically
1abbee
mounted it.
1abbee
1abbee
However I noticed that if I unplugged and re-plugged the device the
1abbee
automatic mounting of the device didn't work anymore: systemd didn't
1abbee
notice that the device was re-plugged.
1abbee
1abbee
This was due to the device unit which was not recycled by the GC
1abbee
during the unplug event because in the case of automounting, the mount
1abbee
unit still referenced it. When the device was re-plugged, the old
1abbee
device unit was reused but it still had the old sysfs path (amongst
1abbee
other useful information).
1abbee
1abbee
Systemd was confused by the stalled sysfs path and decided to ignore
1abbee
the plug event.
1abbee
1abbee
This patch fixes this issue by simply not doing the sanity checking on
1abbee
the sysfs path if the device is in unplugged state.
1abbee
1abbee
Cherry-picked from: ac9d396b2abbae4e7ab84f7b556f70681b66236b
1abbee
Resolves: #1332606
1abbee
---
1abbee
 src/core/device.c | 18 +++++++++++++-----
1abbee
 1 file changed, 13 insertions(+), 5 deletions(-)
1abbee
1abbee
diff --git a/src/core/device.c b/src/core/device.c
1abbee
index 1995e3c..fc73e26 100644
1abbee
--- a/src/core/device.c
1abbee
+++ b/src/core/device.c
1abbee
@@ -314,11 +314,19 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa
1abbee
 
1abbee
         u = manager_get_unit(m, e);
1abbee
 
1abbee
-        if (u &&
1abbee
-            DEVICE(u)->sysfs &&
1abbee
-            !path_equal(DEVICE(u)->sysfs, sysfs)) {
1abbee
-                log_unit_debug(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
1abbee
-                return -EEXIST;
1abbee
+        /* The device unit can still be present even if the device was
1abbee
+         * unplugged: a mount unit can reference it hence preventing
1abbee
+         * the GC to have garbaged it. That's desired since the device
1abbee
+         * unit may have a dependency on the mount unit which was
1abbee
+         * added during the loading of the later. */
1abbee
+        if (u && DEVICE(u)->state == DEVICE_PLUGGED) {
1abbee
+                /* This unit is in plugged state: we're sure it's
1abbee
+                 * attached to a device. */
1abbee
+                if (!path_equal(DEVICE(u)->sysfs, sysfs)) {
1abbee
+                        log_unit_debug(u->id, "Dev %s appeared twice with different sysfs paths %s and %s",
1abbee
+                                       e, DEVICE(u)->sysfs, sysfs);
1abbee
+                        return -EEXIST;
1abbee
+                }
1abbee
         }
1abbee
 
1abbee
         if (!u) {