valeriyvdovin / rpms / systemd

Forked from rpms/systemd 4 years ago
Clone

Blame SOURCES/0310-device-make-sure-to-not-ignore-re-plugged-device.patch

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