summaryrefslogtreecommitdiffstats
path: root/src/shared/blockdev-list.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-07-01 11:45:12 +0200
committerLennart Poettering <lennart@poettering.net>2024-07-01 16:39:40 +0200
commit68ff31fa0aa23060c60a51cebbe593e1e4c769ff (patch)
tree217ac31a58984fadc6360a927e994ab07b87ecdd /src/shared/blockdev-list.c
parentblockdev-util: add partscan check function that takes an sd_device* (diff)
downloadsystemd-68ff31fa0aa23060c60a51cebbe593e1e4c769ff.tar.xz
systemd-68ff31fa0aa23060c60a51cebbe593e1e4c769ff.zip
util: add generic block device listener helper
Various of our tools operate on block devices, and it's not always obvious to know which block devices are actually appropriate for use. Hence, let's add a helper that allows to list block devices, and supports some limited filtering.
Diffstat (limited to 'src/shared/blockdev-list.c')
-rw-r--r--src/shared/blockdev-list.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/shared/blockdev-list.c b/src/shared/blockdev-list.c
new file mode 100644
index 0000000000..2e6ed362f2
--- /dev/null
+++ b/src/shared/blockdev-list.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-device.h"
+
+#include "blockdev-list.h"
+#include "blockdev-util.h"
+#include "device-util.h"
+#include "macro.h"
+#include "terminal-util.h"
+
+int blockdev_list(BlockDevListFlags flags) {
+ _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
+ int r;
+
+ if (sd_device_enumerator_new(&e) < 0)
+ return log_oom();
+
+ r = sd_device_enumerator_add_match_subsystem(e, "block", /* match = */ true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add subsystem match: %m");
+
+ if (FLAGS_SET(flags, BLOCKDEV_LIST_REQUIRE_LUKS)) {
+ r = sd_device_enumerator_add_match_property(e, "ID_FS_TYPE", "crypto_LUKS");
+ if (r < 0)
+ return log_error_errno(r, "Failed to add match for LUKS block devices: %m");
+ }
+
+ FOREACH_DEVICE(e, dev) {
+ const char *node;
+
+ r = sd_device_get_devname(dev, &node);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get device node of discovered block device, ignoring: %m");
+ continue;
+ }
+
+ if (FLAGS_SET(flags, BLOCKDEV_LIST_IGNORE_ZRAM)) {
+ const char *dn;
+
+ r = sd_device_get_sysname(dev, &dn);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get device name of discovered block device '%s', ignoring: %m", node);
+ continue;
+ }
+
+ if (startswith(dn, "zram"))
+ continue;
+ }
+
+ if (FLAGS_SET(flags, BLOCKDEV_LIST_REQUIRE_PARTITION_SCANNING)) {
+ r = blockdev_partscan_enabled(dev);
+ if (r < 0) {
+ log_warning_errno(r, "Unable to determine whether '%s' supports partition scanning, skipping device: %m", node);
+ continue;
+ }
+ if (r == 0) {
+ log_debug("Device '%s' does not support partition scanning, skipping.", node);
+ continue;
+ }
+ }
+
+ printf("%s\n", node);
+
+ if (FLAGS_SET(flags, BLOCKDEV_LIST_SHOW_SYMLINKS)) {
+ _cleanup_strv_free_ char **list = NULL;
+
+ FOREACH_DEVICE_DEVLINK(dev, l)
+ if (strv_extend(&list, l) < 0)
+ return log_oom();
+
+ strv_sort(list);
+
+ STRV_FOREACH(i, list)
+ printf("%s%s%s%s\n", on_tty() ? " " : "", ansi_grey(), *i, ansi_normal());
+ }
+ }
+
+ return 0;
+}