diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-18 22:25:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-18 22:25:09 +0200 |
commit | 3afe230d4aa97a89712d160ce7f8900fc644661c (patch) | |
tree | d1e7997d1f8eec7f2bb671b2fb9613c6f03bcd1e | |
parent | Merge pull request #24730 from yuwata/dissect-image-drop-reference-to-decrypt... (diff) | |
parent | udev: do not ignore -ENOENT from sd_device_get_devname() for block device (diff) | |
download | systemd-3afe230d4aa97a89712d160ce7f8900fc644661c.tar.xz systemd-3afe230d4aa97a89712d160ce7f8900fc644661c.zip |
Merge pull request #24725 from yuwata/blockdev-util-introduce-block_device_get_whole_disk
blockdev-util: introduce block_device_get_whole_disk()
-rw-r--r-- | src/shared/blockdev-util.c | 64 | ||||
-rw-r--r-- | src/shared/blockdev-util.h | 2 | ||||
-rw-r--r-- | src/udev/udevd.c | 26 |
3 files changed, 62 insertions, 30 deletions
diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index e5abb524d5..ab3b5ce263 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -20,6 +20,55 @@ #include "missing_magic.h" #include "parse-util.h" +static int block_device_is_whole_disk(sd_device *dev) { + const char *s; + int r; + + assert(dev); + + r = sd_device_get_subsystem(dev, &s); + if (r < 0) + return r; + + if (!streq(s, "block")) + return -ENOTBLK; + + r = sd_device_get_devtype(dev, &s); + if (r < 0) + return r; + + return streq(s, "disk"); +} + +int block_device_get_whole_disk(sd_device *dev, sd_device **ret) { + int r; + + assert(dev); + assert(ret); + + /* Do not unref returned sd_device object. */ + + r = block_device_is_whole_disk(dev); + if (r < 0) + return r; + if (r == 0) { + r = sd_device_get_parent(dev, &dev); + if (r == -ENOENT) /* Already removed? Let's return a recognizable error. */ + return -ENODEV; + if (r < 0) + return r; + + r = block_device_is_whole_disk(dev); + if (r < 0) + return r; + if (r == 0) + return -ENXIO; + } + + *ret = dev; + return 0; +} + int block_get_whole_disk(dev_t d, dev_t *ret) { char p[SYS_BLOCK_PATH_MAX("/partition")]; _cleanup_free_ char *s = NULL; @@ -518,19 +567,12 @@ int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret) { assert(dev); assert(ret); - r = sd_device_get_subsystem(dev, &s); + /* Refuse invocation on partition block device, insist on "whole" device */ + r = block_device_is_whole_disk(dev); if (r < 0) return r; - - if (!streq(s, "block")) - return -ENOTBLK; - - r = sd_device_get_devtype(dev, &s); - if (r < 0) - return r; - - if (!streq(s, "disk")) /* Refuse invocation on partition block device, insist on "whole" device */ - return -EINVAL; + if (r == 0) + return -ENXIO; /* return a recognizable error */ r = sd_device_enumerator_new(&e); if (r < 0) diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index 550b2786d2..802d79394f 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -14,6 +14,8 @@ #define xsprintf_sys_block_path(buf, suffix, devno) \ xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix)) +int block_device_get_whole_disk(sd_device *dev, sd_device **ret); + int block_get_whole_disk(dev_t d, dev_t *ret); int block_get_originating(dev_t d, dev_t *ret); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 20a9a8cdbe..5ea197c1c4 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -473,13 +473,6 @@ static int device_get_whole_disk(sd_device *dev, sd_device **ret_device, const c if (device_for_action(dev, SD_DEVICE_REMOVE)) goto irrelevant; - r = sd_device_get_subsystem(dev, &val); - if (r < 0) - return log_device_debug_errno(dev, r, "Failed to get subsystem: %m"); - - if (!streq(val, "block")) - goto irrelevant; - r = sd_device_get_sysname(dev, &val); if (r < 0) return log_device_debug_errno(dev, r, "Failed to get sysname: %m"); @@ -493,20 +486,15 @@ static int device_get_whole_disk(sd_device *dev, sd_device **ret_device, const c if (STARTSWITH_SET(val, "dm-", "md", "drbd")) goto irrelevant; - r = sd_device_get_devtype(dev, &val); - if (r < 0 && r != -ENOENT) - 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"); - } + r = block_device_get_whole_disk(dev, &dev); + if (IN_SET(r, + -ENOTBLK, /* The device is not a block device. */ + -ENODEV /* The whole disk device was not found, it may already be removed. */)) + goto irrelevant; + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to get whole disk device: %m"); r = sd_device_get_devname(dev, &val); - if (r == -ENOENT) - goto irrelevant; if (r < 0) return log_device_debug_errno(dev, r, "Failed to get devname: %m"); |