summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-09-18 22:25:09 +0200
committerGitHub <noreply@github.com>2022-09-18 22:25:09 +0200
commit3afe230d4aa97a89712d160ce7f8900fc644661c (patch)
treed1e7997d1f8eec7f2bb671b2fb9613c6f03bcd1e
parentMerge pull request #24730 from yuwata/dissect-image-drop-reference-to-decrypt... (diff)
parentudev: do not ignore -ENOENT from sd_device_get_devname() for block device (diff)
downloadsystemd-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.c64
-rw-r--r--src/shared/blockdev-util.h2
-rw-r--r--src/udev/udevd.c26
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");