[systemd-commits] src/udev

David Herrmann dvdhrm at kemper.freedesktop.org
Sat Apr 11 04:13:57 PDT 2015


 src/udev/udevd.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

New commits:
commit 07ba8037bf2a2d6a683fa107ee6f2b9545fca23e
Author: Daniel Drake <drake at endlessm.com>
Date:   Mon Apr 6 16:03:43 2015 -0600

    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.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a3f17c4..2d0ac6d 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1505,9 +1505,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
                  */



More information about the systemd-commits mailing list