From 9409174ee7280447a6f8c395740bda4fa8114b1d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 10 Sep 2022 00:17:46 +0900 Subject: [PATCH 1/2] udevd: use partition enumerator at one more place No functional changes, just refactoring. --- src/shared/blockdev-util.c | 2 +- src/shared/blockdev-util.h | 1 + src/udev/udevd.c | 39 +++++--------------------------------- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index 7ffb619ac6..87c19d7086 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -509,7 +509,7 @@ int block_device_resize_partition( return RET_NERRNO(ioctl(fd, BLKPG, &ba)); } -static int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret) { +int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; const char *s; int r; diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index fb041bf619..8df76ff30e 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -36,5 +36,6 @@ int path_get_whole_disk(const char *path, bool backing, dev_t *ret); int block_device_add_partition(int fd, const char *name, int nr, uint64_t start, uint64_t size); int block_device_remove_partition(int fd, const char *name, int nr); int block_device_resize_partition(int fd, int nr, uint64_t start, uint64_t size); +int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret); int block_device_remove_all_partitions(sd_device *dev, int fd); int block_device_has_partitions(sd_device *dev); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index b179dfac37..c034e6a3cf 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -28,6 +28,7 @@ #include "sd-event.h" #include "alloc-util.h" +#include "blockdev-util.h" #include "cgroup-setup.h" #include "cgroup-util.h" #include "cpu-set-util.h" @@ -1399,7 +1400,7 @@ static int synthesize_change(sd_device *dev) { streq_ptr(devtype, "disk") && !startswith(sysname, "dm-")) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - bool part_table_read = false, has_partitions = false; + bool part_table_read = false; sd_device *d; int fd; @@ -1418,50 +1419,20 @@ static int synthesize_change(sd_device *dev) { } /* search for partitions */ - r = sd_device_enumerator_new(&e); + r = partition_enumerator_new(dev, &e); if (r < 0) return r; - r = sd_device_enumerator_allow_uninitialized(e); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_parent(e, dev); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_subsystem(e, "block", true); - if (r < 0) - return r; - - FOREACH_DEVICE(e, d) { - const char *t; - - if (sd_device_get_devtype(d, &t) < 0 || !streq(t, "partition")) - continue; - - has_partitions = true; - break; - } - /* We have partitions and re-read the table, the kernel already sent out a "change" * event for the disk, and "remove/add" for all partitions. */ - if (part_table_read && has_partitions) + if (part_table_read && sd_device_enumerator_get_device_first(e)) return 0; /* We have partitions but re-reading the partition table did not work, synthesize * "change" for the disk and all partitions. */ (void) synthesize_change_one(dev, dev); - - FOREACH_DEVICE(e, d) { - const char *t; - - if (sd_device_get_devtype(d, &t) < 0 || !streq(t, "partition")) - continue; - + FOREACH_DEVICE(e, d) (void) synthesize_change_one(dev, d); - } - } else (void) synthesize_change_one(dev, dev); From 86f9b69a6a394bd752be01d997d47849de67006f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 10 Sep 2022 00:33:43 +0900 Subject: [PATCH 2/2] blockdev-util: split out blockdev_reread_partition_table() No functional changes, just refactoring. --- src/shared/blockdev-util.c | 21 +++++++++++++++++++++ src/shared/blockdev-util.h | 1 + src/udev/udevd.c | 20 +++++--------------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index 87c19d7086..e5abb524d5 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "sd-device.h" @@ -649,3 +650,23 @@ int block_device_has_partitions(sd_device *dev) { return !!sd_device_enumerator_get_device_first(e); } + +int blockdev_reread_partition_table(sd_device *dev) { + _cleanup_close_ int fd = -1; + + assert(dev); + + /* Try to re-read the partition table. This only succeeds if none of the devices is busy. */ + + fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (fd < 0) + return fd; + + if (flock(fd, LOCK_EX|LOCK_NB) < 0) + return -errno; + + if (ioctl(fd, BLKRRPART, 0) < 0) + return -errno; + + return 0; +} diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index 8df76ff30e..550b2786d2 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -39,3 +39,4 @@ int block_device_resize_partition(int fd, int nr, uint64_t start, uint64_t size) int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret); int block_device_remove_all_partitions(sd_device *dev, int fd); int block_device_has_partitions(sd_device *dev); +int blockdev_reread_partition_table(sd_device *dev); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c034e6a3cf..c2a4a8a7bd 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1400,23 +1400,13 @@ static int synthesize_change(sd_device *dev) { streq_ptr(devtype, "disk") && !startswith(sysname, "dm-")) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - bool part_table_read = false; + bool part_table_read; sd_device *d; - int fd; - /* Try to re-read the partition table. This only succeeds if none of the devices is - * busy. The kernel returns 0 if no partition table is found, and we will not get an - * event for the disk. */ - fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK); - if (fd >= 0) { - r = flock(fd, LOCK_EX|LOCK_NB); - if (r >= 0) - r = ioctl(fd, BLKRRPART, 0); - - close(fd); - if (r >= 0) - part_table_read = true; - } + r = blockdev_reread_partition_table(dev); + if (r < 0) + log_device_debug_errno(dev, r, "Failed to re-read partition table, ignoring: %m"); + part_table_read = r >= 0; /* search for partitions */ r = partition_enumerator_new(dev, &e);