From a43129b0a0cb5d0e86a0086aa277e99282855d14 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Mar 2022 04:04:54 +0900 Subject: [PATCH 1/6] sd-device: drop /sys/subsystem support Follow-ups for 37cf83d9bfdd9f6859b6f2654d8ec3bbb17873b2. --- src/libsystemd/sd-device/sd-device.c | 30 +++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index f22088db57d..e7d398dbb0a 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -340,7 +340,7 @@ _public_ int sd_device_new_from_subsystem_sysname( assert_return(path_is_normalized(sysname), -EINVAL); if (streq(subsystem, "subsystem")) { - FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/", "/sys/class/") { + FOREACH_STRING(s, "/sys/bus/", "/sys/class/") { r = device_strjoin_new(s, sysname, NULL, NULL, ret); if (r < 0) return r; @@ -364,13 +364,11 @@ _public_ int sd_device_new_from_subsystem_sysname( const char *subsys = memdupa_suffix0(sysname, sep - sysname); sep++; - FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/") { - r = device_strjoin_new(s, subsys, "/drivers/", sep, ret); - if (r < 0) - return r; - if (r > 0) - return 0; - } + r = device_strjoin_new("/sys/bus/", subsys, "/drivers/", sep, ret); + if (r < 0) + return r; + if (r > 0) + return 0; } } @@ -380,13 +378,11 @@ _public_ int sd_device_new_from_subsystem_sysname( if (name[i] == '/') name[i] = '!'; - FOREACH_STRING(s, "/sys/subsystem/", "/sys/bus/") { - r = device_strjoin_new(s, subsystem, "/devices/", name, ret); - if (r < 0) - return r; - if (r > 0) - return 0; - } + r = device_strjoin_new("/sys/bus/", subsystem, "/devices/", name, ret); + if (r < 0) + return r; + if (r > 0) + return 0; r = device_strjoin_new("/sys/class/", subsystem, "/", name, ret); if (r < 0) @@ -869,9 +865,7 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) { r = device_set_subsystem(device, "module"); else if (strstr(syspath, "/drivers/")) r = device_set_drivers_subsystem(device); - else if (PATH_STARTSWITH_SET(device->devpath, "/subsystem/", - "/class/", - "/bus/")) + else if (PATH_STARTSWITH_SET(device->devpath, "/class/", "/bus/")) r = device_set_subsystem(device, "subsystem"); else { device->subsystem_set = true; From becbcca5b829f5ed56b53c0db62d2b505b30997a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Mar 2022 03:27:17 +0900 Subject: [PATCH 2/6] sd-device: try to get DISKSEQ from uevent file Otherwise, if the sd-device object is created from e.g. syspath, then sd_device_get_diskseq() returns -ENOENT. --- src/libsystemd/sd-device/sd-device.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index e7d398dbb0a..545a0f5a5d7 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1138,8 +1138,14 @@ _public_ int sd_device_get_seqnum(sd_device *device, uint64_t *ret) { } _public_ int sd_device_get_diskseq(sd_device *device, uint64_t *ret) { + int r; + assert_return(device, -EINVAL); + r = device_read_uevent_file(device); + if (r < 0) + return r; + if (device->diskseq == 0) return -ENOENT; From 07c90f02d22eb346a9f315faaf440ba54cdffb1f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Mar 2022 04:11:30 +0900 Subject: [PATCH 3/6] sd-device: use path_extract_directory() at one more place --- src/libsystemd/sd-device/sd-device.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 545a0f5a5d7..d2fd322e2a1 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -735,7 +735,7 @@ _public_ int sd_device_get_syspath(sd_device *device, const char **ret) { static int device_new_from_child(sd_device **ret, sd_device *child) { _cleanup_free_ char *path = NULL; - const char *subdir, *syspath; + const char *syspath; int r; assert(ret); @@ -745,25 +745,21 @@ static int device_new_from_child(sd_device **ret, sd_device *child) { if (r < 0) return r; - path = strdup(syspath); - if (!path) - return -ENOMEM; - subdir = path + STRLEN("/sys"); - for (;;) { - char *pos; + _cleanup_free_ char *p = NULL; - pos = strrchr(subdir, '/'); - if (!pos || pos < subdir + 2) + r = path_extract_directory(path ?: syspath, &p); + if (r < 0) + return r; + + if (path_equal(p, "/sys")) return -ENODEV; - *pos = '\0'; + r = sd_device_new_from_syspath(ret, p); + if (r != -ENODEV) + return r; - r = sd_device_new_from_syspath(ret, path); - if (r < 0) - continue; - - return 0; + free_and_replace(path, p); } } From df88f02bb13c1ef27b3e3752efa552ed6bf88586 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Mar 2022 04:14:49 +0900 Subject: [PATCH 4/6] sd-device: do not ignore critical errors in device_new_from_child() --- src/libsystemd/sd-device/sd-device.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index d2fd322e2a1..19bf01abc71 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -764,12 +764,16 @@ static int device_new_from_child(sd_device **ret, sd_device *child) { } _public_ int sd_device_get_parent(sd_device *child, sd_device **ret) { + int r; + assert_return(child, -EINVAL); if (!child->parent_set) { - child->parent_set = true; + r = device_new_from_child(&child->parent, child); + if (r < 0 && r != -ENODEV) + return r; - (void) device_new_from_child(&child->parent, child); + child->parent_set = true; } if (!child->parent) From 20ba5a3fe7c387eae72ca3e0bd1e6eeee3f50f3b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Mar 2022 04:26:22 +0900 Subject: [PATCH 5/6] udev: ignore one more error in device_get_block_device() --- src/udev/udevd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 1cde6b9c9c0..21e3c3558fb 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -451,6 +451,8 @@ static int device_get_block_device(sd_device *dev, const char **ret) { return log_device_debug_errno(dev, r, "Failed to get devtype: %m"); if (r >= 0 && streq(val, "partition")) { r = sd_device_get_parent(dev, &dev); + if (r == -ENOENT) /* The device may be already removed. */ + goto irrelevant; if (r < 0) return log_device_debug_errno(dev, r, "Failed to get parent device: %m"); } From 03a24ce76b8ccfcb634f1863a18f9d7521237d63 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 31 Mar 2022 04:31:46 +0900 Subject: [PATCH 6/6] udev: rename functions to emphasize whole disk is locked --- src/udev/udevd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 21e3c3558fb..424ecfc2cfb 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -422,7 +422,7 @@ static int worker_send_result(Manager *manager, int result) { return loop_write(manager->worker_watch[WRITE_END], &result, sizeof(result), false); } -static int device_get_block_device(sd_device *dev, const char **ret) { +static int device_get_whole_disk(sd_device *dev, const char **ret) { const char *val; int r; @@ -471,7 +471,7 @@ irrelevant: return 0; } -static int worker_lock_block_device(sd_device *dev, int *ret_fd) { +static int worker_lock_whole_disk(sd_device *dev, int *ret_fd) { _cleanup_close_ int fd = -1; const char *val; int r; @@ -484,7 +484,7 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) { * event handling; in the case udev acquired the lock, the external process can block until udev has * finished its event handling. */ - r = device_get_block_device(dev, &val); + r = device_get_whole_disk(dev, &val); if (r < 0) return r; if (r == 0) @@ -581,7 +581,7 @@ static int worker_process_device(Manager *manager, sd_device *dev) { * Instead of processing the event, we requeue the event and will try again after a delay. * * The user-facing side of this: https://systemd.io/BLOCK_DEVICE_LOCKING */ - r = worker_lock_block_device(dev, &fd_lock); + r = worker_lock_whole_disk(dev, &fd_lock); if (r == -EAGAIN) return EVENT_RESULT_TRY_AGAIN; if (r < 0) @@ -1093,7 +1093,7 @@ static int event_queue_assume_block_device_unlocked(Manager *manager, sd_device * device is not locked anymore. The assumption may not be true, but that should not cause any * issues, as in that case events will be requeued soon. */ - r = device_get_block_device(dev, &devname); + r = device_get_whole_disk(dev, &devname); if (r <= 0) return r; @@ -1106,7 +1106,7 @@ static int event_queue_assume_block_device_unlocked(Manager *manager, sd_device if (event->retry_again_next_usec == 0) continue; - if (device_get_block_device(event->dev, &event_devname) <= 0) + if (device_get_whole_disk(event->dev, &event_devname) <= 0) continue; if (!streq(devname, event_devname))