]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util: add generic block device listener helper
authorLennart Poettering <lennart@poettering.net>
Mon, 1 Jul 2024 09:45:12 +0000 (11:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 1 Jul 2024 14:39:40 +0000 (16:39 +0200)
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.

src/shared/blockdev-list.c [new file with mode: 0644]
src/shared/blockdev-list.h [new file with mode: 0644]
src/shared/meson.build

diff --git a/src/shared/blockdev-list.c b/src/shared/blockdev-list.c
new file mode 100644 (file)
index 0000000..2e6ed36
--- /dev/null
@@ -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;
+}
diff --git a/src/shared/blockdev-list.h b/src/shared/blockdev-list.h
new file mode 100644 (file)
index 0000000..7fbf824
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+typedef enum BlockDevListFlags {
+        BLOCKDEV_LIST_SHOW_SYMLINKS              = 1 << 0,
+        BLOCKDEV_LIST_REQUIRE_PARTITION_SCANNING = 1 << 1,
+        BLOCKDEV_LIST_IGNORE_ZRAM                = 1 << 2,
+        BLOCKDEV_LIST_REQUIRE_LUKS               = 1 << 3,
+} BlockDevListFlags;
+
+int blockdev_list(BlockDevListFlags flags);
index b7ae5959e835e0dda966148370ebba8685815b8e..ea1e0092869cb216cff5e1d81297d3c568952865 100644 (file)
@@ -12,6 +12,7 @@ shared_sources = files(
         'battery-util.c',
         'binfmt-util.c',
         'bitmap.c',
+        'blockdev-list.c',
         'blockdev-util.c',
         'bond-util.c',
         'boot-entry.c',