From: Lennart Poettering Date: Mon, 1 Jul 2024 09:45:12 +0000 (+0200) Subject: util: add generic block device listener helper X-Git-Tag: v257-rc1~1007^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=68ff31fa0aa23060c60a51cebbe593e1e4c769ff;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/shared/blockdev-list.c b/src/shared/blockdev-list.c new file mode 100644 index 00000000000..2e6ed362f28 --- /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; +} diff --git a/src/shared/blockdev-list.h b/src/shared/blockdev-list.h new file mode 100644 index 00000000000..7fbf824ab2c --- /dev/null +++ b/src/shared/blockdev-list.h @@ -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); diff --git a/src/shared/meson.build b/src/shared/meson.build index b7ae5959e83..ea1e0092869 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -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',