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