923a60
From e55efa99fd829a4699aae6505e02fae7b50a40bc Mon Sep 17 00:00:00 2001
923a60
From: Daniel Drake <drake@endlessm.com>
923a60
Date: Mon, 6 Apr 2015 16:03:43 -0600
923a60
Subject: [PATCH] udevd: fix synchronization with settle when handling inotify
923a60
 events
923a60
923a60
udev uses inotify to implement a scheme where when the user closes
923a60
a writable device node, a change uevent is forcefully generated.
923a60
In the case of block devices, it actually requests a partition rescan.
923a60
923a60
This currently can't be synchronized with "udevadm settle", i.e. this
923a60
is not reliable in a script:
923a60
923a60
 sfdisk --change-id /dev/sda 1 81
923a60
 udevadm settle
923a60
 mount /dev/sda1 /foo
923a60
923a60
The settle call doesn't synchronize there, so at the same time we try
923a60
to mount the device, udevd is busy removing the partition device nodes and
923a60
readding them again. The mount call often happens in that moment where the
923a60
partition node has been removed but not readded yet.
923a60
923a60
This exact issue was fixed long ago:
923a60
http://git.kernel.org/cgit/linux/hotplug/udev.git/commit/?id=bb38678e3ccc02bcd970ccde3d8166a40edf92d3
923a60
923a60
but that fix is no longer valid now that sequence numbers are no longer
923a60
used.
923a60
923a60
Fix this by forcing another mainloop iteration after handling inotify events
923a60
before unblocking settle. If the inotify event caused us to generate a
923a60
"change" event, we'll pick that up in the following loop iteration, before
923a60
we reach the end of the loop where we respond to settle's control message,
923a60
unblocking it.
923a60
923a60
(cherry picked from commit 07ba8037bf2a2d6a683fa107ee6f2b9545fca23e)
923a60
923a60
Cherry-picked from: 7a2e024
923a60
Resolves: #1222517
923a60
---
923a60
 src/udev/udevd.c | 15 ++++++++++++++-
923a60
 1 file changed, 14 insertions(+), 1 deletion(-)
923a60
923a60
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
923a60
index e98c1fd6da..87a3f69e90 100644
923a60
--- a/src/udev/udevd.c
923a60
+++ b/src/udev/udevd.c
923a60
@@ -1502,9 +1502,22 @@ int main(int argc, char *argv[]) {
923a60
                         continue;
923a60
 
923a60
                 /* device node watch */
923a60
-                if (is_inotify)
923a60
+                if (is_inotify) {
923a60
                         handle_inotify(udev);
923a60
 
923a60
+                        /*
923a60
+                         * settle might be waiting on us to determine the queue
923a60
+                         * state. If we just handled an inotify event, we might have
923a60
+                         * generated a "change" event, but we won't have queued up
923a60
+                         * the resultant uevent yet.
923a60
+                         *
923a60
+                         * Before we go ahead and potentially tell settle that the
923a60
+                         * queue is empty, lets loop one more time to update the
923a60
+                         * queue state again before deciding.
923a60
+                         */
923a60
+                        continue;
923a60
+                }
923a60
+
923a60
                 /* tell settle that we are busy or idle, this needs to be before the
923a60
                  * PING handling
923a60
                  */