[systemd-commits] src/udev

Kay Sievers kay at kemper.freedesktop.org
Wed Jun 4 04:39:08 PDT 2014


 src/udev/udevd.c |   39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

New commits:
commit ede344452a54e1c53f541cad12a06269a4fe96a9
Author: Kay Sievers <kay at vrfy.org>
Date:   Wed Jun 4 13:30:24 2014 +0200

    udev: try first re-reading the partition table
    
    mounted partitions:
      # dd if=/dev/zero of=/dev/sda bs=1 count=1
      UDEV  [4157.369250] change   .../0:0:0:0/block/sda (block)
      UDEV  [4157.375059] change   .../0:0:0:0/block/sda/sda1 (block)
      UDEV  [4157.397088] change   .../0:0:0:0/block/sda/sda2 (block)
      UDEV  [4157.404842] change   .../0:0:0:0/block/sda/sda4 (block)
    
    unmounted partitions:
      # dd if=/dev/zero of=/dev/sdb bs=1 count=1
      UDEV  [4163.450217] remove   .../target6:0:0/6:0:0:0/block/sdb/sdb1 (block)
      UDEV  [4163.593167] change   .../target6:0:0/6:0:0:0/block/sdb (block)
      UDEV  [4163.713982] add      .../target6:0:0/6:0:0:0/block/sdb/sdb1 (block)

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 6100d7d..763062f 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -38,6 +38,7 @@
 #include <sys/un.h>
 #include <sys/signalfd.h>
 #include <sys/epoll.h>
+#include <sys/mount.h>
 #include <sys/poll.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
@@ -738,17 +739,37 @@ static int synthesize_change(struct udev_device *dev) {
         char filename[UTIL_PATH_SIZE];
         int r;
 
-        log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
-        strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
-        write_string_file(filename, "change");
-
-        /* for disks devices, re-trigger all partitions too */
         if (streq_ptr("block", udev_device_get_subsystem(dev)) &&
-            streq_ptr("disk", udev_device_get_devtype(dev))) {
+            streq_ptr("disk", udev_device_get_devtype(dev)) &&
+            !startswith("dm-", udev_device_get_sysname(dev))) {
+                int fd;
                 struct udev *udev = udev_device_get_udev(dev);
                 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
                 struct udev_list_entry *item;
 
+                /*
+                 * Try to re-read the partition table, this only succeeds if
+                 * none of the devices is busy.
+                 *
+                 * The kernel will send out a change event for the disk, and
+                 * "remove/add" for all partitions.
+                 */
+                fd = open(udev_device_get_devnode(dev), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
+                if (fd >= 0) {
+                        r = ioctl(fd, BLKRRPART, 0);
+                        close(fd);
+                        if (r >= 0)
+                                return 0;
+                }
+
+                /*
+                 * Re-reading the partition table did not work, synthesize "change"
+                 * events for the disk and all partitions.
+                 */
+                log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
+                strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
+                write_string_file(filename, "change");
+
                 e = udev_enumerate_new(udev);
                 if (!e)
                         return -ENOMEM;
@@ -777,8 +798,14 @@ static int synthesize_change(struct udev_device *dev) {
                         strscpyl(filename, sizeof(filename), udev_device_get_syspath(d), "/uevent", NULL);
                         write_string_file(filename, "change");
                 }
+
+                return 0;
         }
 
+        log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev));
+        strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL);
+        write_string_file(filename, "change");
+
         return 0;
 }
 



More information about the systemd-commits mailing list