diff options
author | Kay Sievers <kay@vrfy.org> | 2014-06-07 08:38:45 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-06-07 08:38:45 -0400 |
commit | 50decc8ac8f7c9d91ec46a5a52ef0f161f752be0 (patch) | |
tree | 8ed8a519b35cdb4628cd182eada617c039f9409e | |
parent | 7c09c01851c4fc2cc97d59aaed11d315ecb02d29 (diff) |
udev: synthesize "change' events for partitions when tools change the disk
This should make sure that fdisk-like programs will automatically
cause an update of all partitions, just like mkfs-like programs cause
an update of the partition.
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
-rw-r--r-- | src/udev/udevd.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c index df4bb4b9b4..b21c962272 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -46,6 +46,7 @@ #include <sys/utsname.h> #include "udev.h" +#include "udev-util.h" #include "def.h" #include "cgroup-util.h" #include "dev-setup.h" @@ -733,15 +734,54 @@ out: return udev_ctrl_connection_unref(ctrl_conn); } -static void synthesize_change(struct udev_device *dev) { +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))) { + struct udev *udev = udev_device_get_udev(dev); + _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; + struct udev_list_entry *item; + + e = udev_enumerate_new(udev); + if (!e) + return -ENOMEM; + + r = udev_enumerate_add_match_parent(e, dev); + if (r < 0) + return r; + + r = udev_enumerate_add_match_subsystem(e, "block"); + if (r < 0) + return r; + + r = udev_enumerate_scan_devices(e); + udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) { + _cleanup_udev_device_unref_ struct udev_device *d = NULL; + + d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + if (!d) + continue; + + if (!streq_ptr("partition", udev_device_get_devtype(d))) + continue; + + log_debug("device %s closed, synthesising partition '%s' 'change'", + udev_device_get_devnode(dev), udev_device_get_devnode(d)); + strscpyl(filename, sizeof(filename), udev_device_get_syspath(d), "/uevent", NULL); + write_string_file(filename, "change"); + } + } + + return 0; } -/* read inotify messages */ static int handle_inotify(struct udev *udev) { int nbytes, pos; |