blockdev-list: optionally return finds as list instead of writing it to stdout

This commit is contained in:
Lennart Poettering
2025-09-23 09:13:13 +02:00
parent cb06a80482
commit 9f6b2745ea
5 changed files with 79 additions and 12 deletions
+1 -1
View File
@@ -630,7 +630,7 @@ static int parse_argv(int argc, char *argv[]) {
}
case ARG_LIST_DEVICES:
r = blockdev_list(BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_REQUIRE_LUKS);
r = blockdev_list(BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_REQUIRE_LUKS, /* ret_devices= */ NULL, /* ret_n_devices= */ NULL);
if (r < 0)
return r;
+1 -1
View File
@@ -9163,7 +9163,7 @@ static int parse_argv(
break;
case ARG_LIST_DEVICES:
r = blockdev_list(BLOCKDEV_LIST_REQUIRE_PARTITION_SCANNING|BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_IGNORE_ZRAM);
r = blockdev_list(BLOCKDEV_LIST_REQUIRE_PARTITION_SCANNING|BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_IGNORE_ZRAM, /* ret_devices= */ NULL, /* ret_n_devices= */ NULL);
if (r < 0)
return r;
+61 -8
View File
@@ -2,6 +2,7 @@
#include "sd-device.h"
#include "alloc-util.h"
#include "ansi-color.h"
#include "blockdev-list.h"
#include "blockdev-util.h"
@@ -9,10 +10,34 @@
#include "strv.h"
#include "terminal-util.h"
int blockdev_list(BlockDevListFlags flags) {
void block_device_done(BlockDevice *d) {
assert(d);
d->node = mfree(d->node);
d->symlinks = strv_free(d->symlinks);
}
void block_device_array_free(BlockDevice *d, size_t n_devices) {
FOREACH_ARRAY(i, d, n_devices)
block_device_done(d);
free(d);
}
int blockdev_list(BlockDevListFlags flags, BlockDevice **ret_devices, size_t *ret_n_devices) {
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
int r;
assert(!!ret_devices == !!ret_n_devices);
/* If ret_devices/ret_n_devices are passed, returns a list of matching block devices, otherwise
* prints the list to stdout */
BlockDevice *l = NULL;
size_t n = 0;
CLEANUP_ARRAY(l, n, block_device_array_free);
if (sd_device_enumerator_new(&e) < 0)
return log_oom();
@@ -57,21 +82,49 @@ int blockdev_list(BlockDevListFlags flags) {
}
}
printf("%s\n", node);
_cleanup_strv_free_ char **list = NULL;
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)
FOREACH_DEVICE_DEVLINK(dev, sl)
if (strv_extend(&list, sl) < 0)
return log_oom();
strv_sort(list);
}
STRV_FOREACH(i, list)
printf("%s%s%s%s\n", on_tty() ? " " : "", ansi_grey(), *i, ansi_normal());
if (ret_devices) {
uint64_t diskseq = UINT64_MAX;
r = sd_device_get_diskseq(dev, &diskseq);
if (r < 0)
log_debug_errno(r, "Failed to acquire diskseq of device '%s', ignoring: %m", node);
if (!GREEDY_REALLOC(l, n+1))
return log_oom();
_cleanup_free_ char *m = strdup(node);
if (!m)
return log_oom();
l[n++] = (BlockDevice) {
.node = TAKE_PTR(m),
.symlinks = TAKE_PTR(list),
.diskseq = diskseq,
};
} else {
printf("%s\n", node);
if (FLAGS_SET(flags, BLOCKDEV_LIST_SHOW_SYMLINKS))
STRV_FOREACH(i, list)
printf("%s%s%s%s\n", on_tty() ? " " : "", ansi_grey(), *i, ansi_normal());
}
}
if (ret_devices)
*ret_devices = TAKE_PTR(l);
if (ret_n_devices)
*ret_n_devices = n;
return 0;
}
+15 -1
View File
@@ -10,4 +10,18 @@ typedef enum BlockDevListFlags {
BLOCKDEV_LIST_REQUIRE_LUKS = 1 << 3,
} BlockDevListFlags;
int blockdev_list(BlockDevListFlags flags);
typedef struct BlockDevice {
char *node;
char **symlinks;
uint64_t diskseq;
} BlockDevice;
#define BLOCK_DEVICE_NULL (BlockDevice) { \
.diskseq = UINT64_MAX, \
.size = UINT64_MAX, \
}
void block_device_done(BlockDevice *d);
void block_device_array_free(BlockDevice *d, size_t n_devices);
int blockdev_list(BlockDevListFlags flags, BlockDevice **ret_devices, size_t *ret_n_devices);
+1 -1
View File
@@ -115,7 +115,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_LIST_DEVICES:
r = blockdev_list(BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_IGNORE_ZRAM);
r = blockdev_list(BLOCKDEV_LIST_SHOW_SYMLINKS|BLOCKDEV_LIST_IGNORE_ZRAM, /* ret_devices= */ NULL, /* ret_n_devices= */ NULL);
if (r < 0)
return r;