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