* [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated
@ 2026-10-16 19:47 Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported" Maxim Skokov
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Maxim Skokov @ 2026-10-16 19:47 UTC (permalink / raw)
To: bpf
Cc: qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
"bpftool map dump" treats only ENOENT from bpf_map_get_next_key() as the
end of the map. Map types that can't be iterated (local storage, ringbuf,
bloom filter, arena, queue, stack) fail on the first key, and bpftool
prints an empty dump, "[]" or "Found 0 elements", with only a non-zero
exit status.
Patch 1 adds a helper that prints ENOTSUPP (524), which the kernel
returns from some BPF commands, as "Operation not supported" instead of
"Unknown error 524", and uses it for map create, map element
operations, map freeze and prog run. Patch 2 asks for the first key
before printing anything and fails with the map type and the error.
Patch 3 adds a test_progs case on a socket storage map, and on a queue
map without BTF for the plain output path.
The new test fails without patches 1-2 and passes with them; the other
bpftool_* selftests pass. v5 was tested on x86_64 under a bpf-next
kernel (d2141481a764e). The ENOTSUPP message was also checked by hand
for map getnext, lookup and dump on ringbuf and socket storage maps,
map create of an LRU hash without preallocation, and prog run on a
kprobe program; map delete, pop and freeze use the same helper but
were not checked by hand.
Changes in v5 (patches 1-2 of v4 are now patches 2-3):
- new patch 1: helper for ENOTSUPP, used in map dump and the other
places where bpftool prints the result of a command that can return
it (Daniel)
- patch 2 (map dump) uses the helper; kept Quentin's Acked-by as the
change is only the error string
- selftests: check the full error text for socket storage
- rebase on current bpf-next
Changes in v4:
- selftests: socket storage always has BTF, so the "Found" check could
never fail there; check the count on a queue map without BTF instead,
and fix the comment on create_sk_storage_map() (bpf-ci)
- selftests: split into sk_storage and queue subtests, new subject
- rebase on current bpf-next, patch 1 unchanged
Changes in v3:
- shorter comment on the probe (Quentin)
- selftests: unlink the pin on every exit path, so a killed run doesn't
leave a stale pin that fails every later run with EEXIST (Sashiko)
- collect Acked-by on patch 1
Changes in v2:
- probe the first key before any output instead of printing a hint for
ENOTSUPP only, so every non-iterable type gets an error and stdout gets
no "[]" (Alexei)
- drop the Fixes tag and use a neutral example map (Alexei)
- selftests: check that JSON output is only the error object and plain
stdout has no elements or count; clear the output buffer before each
run (Sashiko)
- multi-line comment style (bpf-ci)
v4: https://lore.kernel.org/bpf/20260928001513.7072-1-skokovmaksimevg@gmail.com/
v3: https://lore.kernel.org/bpf/20260926170149.541352-1-skokovmaksimevg@gmail.com/
v2: https://lore.kernel.org/bpf/20260925162031.27259-1-skokovmaksimevg@gmail.com/
v1: https://lore.kernel.org/bpf/20260924160732.485650-1-skokovmaksimevg@gmail.com/
Maxim Skokov (3):
bpftool: Print ENOTSUPP as "Operation not supported"
bpftool: Fail map dump for maps that can't be iterated
selftests/bpf: Test bpftool map dump on maps that can't be iterated
tools/bpf/bpftool/common.c | 11 ++
tools/bpf/bpftool/main.h | 1 +
tools/bpf/bpftool/map.c | 40 ++++--
tools/bpf/bpftool/prog.c | 2 +-
.../bpf/prog_tests/bpftool_map_dump.c | 133 ++++++++++++++++++
5 files changed, 175 insertions(+), 12 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
base-commit: d2141481a764efdfaac70965ea28e8925f6a6b80
--
2.47.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported"
2026-10-16 19:47 [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
@ 2026-10-16 19:47 ` Maxim Skokov
2026-10-16 20:08 ` Quentin Monnet
2026-10-16 19:47 ` [PATCH bpf-next v5 2/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Maxim Skokov @ 2026-10-16 19:47 UTC (permalink / raw)
To: bpf
Cc: qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
Some BPF commands return ENOTSUPP (524) to user space: iterating local
storage maps, element operations on ringbuf maps, creating an LRU hash
map without preallocation, freezing a struct_ops map, or running a
program type that has no test_run. ENOTSUPP is kernel internal, so
strerror() only gives "Unknown error 524":
# bpftool map getnext pinned /sys/fs/bpf/sk_storage
Error: can't get next key: Unknown error 524
Add a small helper that knows ENOTSUPP and use it where bpftool prints
the error of map create, map element operations, map freeze and prog
run.
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Assisted-by: LLM
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
---
tools/bpf/bpftool/common.c | 11 +++++++++++
tools/bpf/bpftool/main.h | 1 +
tools/bpf/bpftool/map.c | 18 +++++++++---------
tools/bpf/bpftool/prog.c | 2 +-
4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index f9b87efa7c9a7..ca5fa2f0bf9b1 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -72,6 +72,17 @@ void p_info(const char *fmt, ...)
va_end(ap);
}
+/*
+ * Like strerror(), but also knows ENOTSUPP (524), which the kernel returns
+ * to user space from some BPF commands although it is not a userspace errno.
+ */
+const char *bpf_strerror(int err)
+{
+ if (err == 524 /* ENOTSUPP */)
+ return "Operation not supported";
+ return strerror(err);
+}
+
static bool is_bpffs(const char *path)
{
struct statfs st_fs;
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 6851346a60305..b1eb4b5d991b8 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -98,6 +98,7 @@ extern const char *cert_path;
void __printf(1, 2) p_err(const char *fmt, ...);
void __printf(1, 2) p_info(const char *fmt, ...);
+const char *bpf_strerror(int err);
bool is_prefix(const char *pfx, const char *str);
int detect_common_prefix(const char *arg, ...);
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 20d59eab09a12..d809b075e734f 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -228,7 +228,7 @@ print_entry_error(struct bpf_map_info *map_info, void *key, int lookup_errno)
print_hex_data_json(key, map_info->key_size);
jsonw_name(json_wtr, "value");
jsonw_start_object(json_wtr); /* error */
- jsonw_string_field(json_wtr, "error", strerror(lookup_errno));
+ jsonw_string_field(json_wtr, "error", bpf_strerror(lookup_errno));
jsonw_end_object(json_wtr); /* error */
jsonw_end_object(json_wtr); /* entry */
} else {
@@ -241,7 +241,7 @@ print_entry_error(struct bpf_map_info *map_info, void *key, int lookup_errno)
msg = "<cannot read>";
print_entry_error_msg(map_info, key,
- msg ? : strerror(lookup_errno));
+ msg ? : bpf_strerror(lookup_errno));
}
}
@@ -1032,7 +1032,7 @@ static int do_update(int argc, char **argv)
err = bpf_map_update_elem(fd, key, value, flags);
if (err) {
- p_err("update failed: %s", strerror(errno));
+ p_err("update failed: %s", bpf_strerror(errno));
goto exit_free;
}
@@ -1136,7 +1136,7 @@ static int do_lookup(int argc, char **argv)
printf("\n\nNot found\n");
}
} else {
- p_err("lookup failed: %s", strerror(errno));
+ p_err("lookup failed: %s", bpf_strerror(errno));
}
goto exit_free;
@@ -1188,7 +1188,7 @@ static int do_getnext(int argc, char **argv)
err = bpf_map_get_next_key(fd, key, nextkey);
if (err) {
- p_err("can't get next key: %s", strerror(errno));
+ p_err("can't get next key: %s", bpf_strerror(errno));
goto exit_free;
}
@@ -1253,7 +1253,7 @@ static int do_delete(int argc, char **argv)
err = bpf_map_delete_elem(fd, key);
if (err)
- p_err("delete failed: %s", strerror(errno));
+ p_err("delete failed: %s", bpf_strerror(errno));
exit_free:
free(key);
@@ -1381,7 +1381,7 @@ static int do_create(int argc, char **argv)
fd = bpf_map_create(map_type, map_name, key_size, value_size, max_entries, &attr);
if (fd < 0) {
- p_err("map create failed: %s", strerror(errno));
+ p_err("map create failed: %s", bpf_strerror(errno));
goto exit;
}
@@ -1427,7 +1427,7 @@ static int do_pop_dequeue(int argc, char **argv)
else
printf("Error: empty map\n");
} else {
- p_err("pop failed: %s", strerror(errno));
+ p_err("pop failed: %s", bpf_strerror(errno));
}
goto exit_free;
@@ -1462,7 +1462,7 @@ static int do_freeze(int argc, char **argv)
err = bpf_map_freeze(fd);
close(fd);
if (err) {
- p_err("failed to freeze map: %s", strerror(errno));
+ p_err("failed to freeze map: %s", bpf_strerror(errno));
return err;
}
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index eb077236d2eaa..43599c79c93ac 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -1499,7 +1499,7 @@ static int do_run(int argc, char **argv)
err = bpf_prog_test_run_opts(fd, &test_attr);
if (err) {
- p_err("failed to run program: %s", strerror(errno));
+ p_err("failed to run program: %s", bpf_strerror(errno));
goto free_ctx_out;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH bpf-next v5 2/3] bpftool: Fail map dump for maps that can't be iterated
2026-10-16 19:47 [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported" Maxim Skokov
@ 2026-10-16 19:47 ` Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on " Maxim Skokov
2026-10-17 14:50 ` [PATCH bpf-next v5 0/3] bpftool: Fail map dump for " patchwork-bot+netdevbpf
3 siblings, 0 replies; 7+ messages in thread
From: Maxim Skokov @ 2026-10-16 19:47 UTC (permalink / raw)
To: bpf
Cc: qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
"bpftool map dump" walks the map with bpf_map_get_next_key() and treats
ENOENT as the end of the map. Map types that can't be iterated fail that
call on the very first key: local storage and ringbuf with ENOTSUPP,
bloom filter and arena with EOPNOTSUPP, queue and stack with EINVAL.
bpftool then ends the walk without a word and prints what it prints for
an empty map, "[]" with BTF or "Found 0 elements" without, and only the
exit status tells that the map was not read. On a socket storage map
that holds storage for a socket:
# bpftool map dump pinned /sys/fs/bpf/sk_storage
[]
Ask for the first key before printing anything, and when that fails with
anything but ENOENT, fail with the map type and the error instead of a
dump:
# bpftool map dump pinned /sys/fs/bpf/sk_storage
Error: can't dump sk_storage map: Operation not supported
# bpftool -j map dump pinned /sys/fs/bpf/sk_storage
{"error":"can't dump sk_storage map: Operation not supported"}
An error later in the walk is now reported too, as "bpftool map getnext"
reports it, and the element count is printed only after a complete walk.
Assisted-by: LLM
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Acked-by: Quentin Monnet <qmo@kernel.org>
---
tools/bpf/bpftool/map.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index d809b075e734f..4b65edf74859b 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -856,6 +856,21 @@ map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
}
}
+ /* Fail early to avoid an empty dump if map type cannot be iterated */
+ if (bpf_map_get_next_key(fd, NULL, key) && errno != ENOENT) {
+ const char *map_type_str, *err_str;
+
+ err_str = bpf_strerror(errno);
+ map_type_str = libbpf_bpf_map_type_str(info->type);
+ if (map_type_str)
+ p_err("can't dump %s map: %s", map_type_str, err_str);
+ else
+ p_err("can't dump map of type %u: %s", info->type,
+ err_str);
+ err = -1;
+ goto exit_free;
+ }
+
if (wtr) {
err = get_map_kv_btf(info, &btf);
if (err) {
@@ -883,8 +898,11 @@ map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
while (true) {
err = bpf_map_get_next_key(fd, prev_key, key);
if (err) {
- if (errno == ENOENT)
+ if (errno == ENOENT) {
err = 0;
+ break;
+ }
+ p_err("can't get next key: %s", bpf_strerror(errno));
break;
}
if (!dump_map_elem(fd, key, value, info, btf, wtr,
@@ -897,7 +915,7 @@ map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
jsonw_end_array(wtr); /* elements */
if (show_header)
jsonw_end_object(wtr); /* map object */
- } else {
+ } else if (!err) {
printf("Found %u element%s\n", num_elems,
num_elems != 1 ? "s" : "");
}
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on maps that can't be iterated
2026-10-16 19:47 [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported" Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 2/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
@ 2026-10-16 19:47 ` Maxim Skokov
2026-10-16 20:08 ` qmo
2026-10-17 14:50 ` [PATCH bpf-next v5 0/3] bpftool: Fail map dump for " patchwork-bot+netdevbpf
3 siblings, 1 reply; 7+ messages in thread
From: Maxim Skokov @ 2026-10-16 19:47 UTC (permalink / raw)
To: bpf
Cc: qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
Socket storage can't be iterated from user space. Create a
BPF_MAP_TYPE_SK_STORAGE map, attach storage to a socket, pin it, and
check that "bpftool map dump" fails with nothing but an error: a JSON
error object with -j, no elements on stdout in plain mode, and the
reason on stderr.
Socket storage always has BTF, so its plain dump goes through the BTF
writer and never prints an element count. Check that path with a queue
map created without BTF that holds one element: its plain dump must
fail without a "Found" line, which bpftool printed as "Found 0
elements" before, and give the reason on stderr.
Assisted-by: LLM
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
---
.../bpf/prog_tests/bpftool_map_dump.c | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c b/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
new file mode 100644
index 0000000000000..187b3f7843079
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <sys/socket.h>
+#include <unistd.h>
+#include <bpf/btf.h>
+#include <test_progs.h>
+#include "bpftool_helpers.h"
+
+#define PIN_PATH "/sys/fs/bpf/test_bpftool_map_dump_sk_storage"
+#define QUEUE_PIN_PATH "/sys/fs/bpf/test_bpftool_map_dump_queue"
+#define JSON_ERROR "{\"error\":\"can't dump sk_storage map"
+
+/* An empty socket storage map with an int value. */
+static int create_sk_storage_map(void)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, opts,
+ .map_flags = BPF_F_NO_PREALLOC);
+ struct btf *btf;
+ int int_id, fd = -1;
+
+ btf = btf__new_empty();
+ if (!ASSERT_OK_PTR(btf, "btf__new_empty"))
+ return -1;
+
+ int_id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED);
+ if (!ASSERT_GT(int_id, 0, "btf__add_int"))
+ goto out;
+ if (!ASSERT_OK(btf__load_into_kernel(btf), "btf__load_into_kernel"))
+ goto out;
+
+ opts.btf_fd = btf__fd(btf);
+ opts.btf_key_type_id = int_id;
+ opts.btf_value_type_id = int_id;
+ fd = bpf_map_create(BPF_MAP_TYPE_SK_STORAGE, "sk_storage", sizeof(int),
+ sizeof(int), 0, &opts);
+ ASSERT_OK_FD(fd, "bpf_map_create");
+out:
+ btf__free(btf);
+ return fd;
+}
+
+static void test_sk_storage(void)
+{
+ int map_fd, sk_fd = -1, value = 42, ret;
+ char output[1024] = {};
+
+ map_fd = create_sk_storage_map();
+ if (map_fd < 0)
+ return;
+
+ sk_fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (!ASSERT_OK_FD(sk_fd, "socket"))
+ goto out;
+ if (!ASSERT_OK(bpf_map_update_elem(map_fd, &sk_fd, &value, BPF_NOEXIST),
+ "add socket storage"))
+ goto out;
+ if (!ASSERT_OK(bpf_obj_pin(map_fd, PIN_PATH), "pin map"))
+ goto out;
+
+ /*
+ * Socket storage can't be iterated, so the dump must fail with an
+ * error and nothing else, rather than print an empty map that holds
+ * an element. The buffer is cleared before each run so that a run
+ * that fails to start can't match stale or uninitialised output.
+ */
+ ret = get_bpftool_command_output("-j map dump pinned " PIN_PATH,
+ output, sizeof(output));
+ ASSERT_NEQ(ret, 0, "json dump fails");
+ ASSERT_STRNEQ(output, JSON_ERROR, strlen(JSON_ERROR),
+ "json dump is only the error");
+
+ memset(output, 0, sizeof(output));
+ ret = get_bpftool_command_output("map dump pinned " PIN_PATH,
+ output, sizeof(output));
+ ASSERT_NEQ(ret, 0, "plain dump fails");
+ ASSERT_NULL(strchr(output, '['), "plain dump prints no elements");
+
+ memset(output, 0, sizeof(output));
+ get_bpftool_command_output("map dump pinned " PIN_PATH " 2>&1 >/dev/null",
+ output, sizeof(output));
+ ASSERT_HAS_SUBSTR(output,
+ "can't dump sk_storage map: Operation not supported",
+ "plain dump explains why on stderr");
+
+out:
+ unlink(PIN_PATH);
+ if (sk_fd >= 0)
+ close(sk_fd);
+ close(map_fd);
+}
+
+/*
+ * A queue map has no BTF, so its plain dump prints an element count
+ * rather than JSON. A dump that ignored the error would print "Found 0
+ * elements" for a queue that holds one.
+ */
+static void test_queue(void)
+{
+ char output[1024] = {};
+ int map_fd, value = 42, ret;
+
+ map_fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, "queue", 0, sizeof(int), 1,
+ NULL);
+ if (!ASSERT_OK_FD(map_fd, "bpf_map_create"))
+ return;
+ if (!ASSERT_OK(bpf_map_update_elem(map_fd, NULL, &value, BPF_ANY),
+ "push to queue"))
+ goto out;
+ if (!ASSERT_OK(bpf_obj_pin(map_fd, QUEUE_PIN_PATH), "pin map"))
+ goto out;
+
+ ret = get_bpftool_command_output("map dump pinned " QUEUE_PIN_PATH,
+ output, sizeof(output));
+ ASSERT_NEQ(ret, 0, "plain dump fails");
+ ASSERT_NULL(strstr(output, "Found"), "plain dump prints no count");
+
+ memset(output, 0, sizeof(output));
+ get_bpftool_command_output("map dump pinned " QUEUE_PIN_PATH " 2>&1 >/dev/null",
+ output, sizeof(output));
+ ASSERT_HAS_SUBSTR(output, "can't dump queue map",
+ "plain dump explains why on stderr");
+
+out:
+ unlink(QUEUE_PIN_PATH);
+ close(map_fd);
+}
+
+void test_bpftool_map_dump(void)
+{
+ if (test__start_subtest("sk_storage"))
+ test_sk_storage();
+ if (test__start_subtest("queue"))
+ test_queue();
+}
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported"
2026-10-16 19:47 ` [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported" Maxim Skokov
@ 2026-10-16 20:08 ` Quentin Monnet
0 siblings, 0 replies; 7+ messages in thread
From: Quentin Monnet @ 2026-10-16 20:08 UTC (permalink / raw)
To: Maxim Skokov, bpf
Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
2026-10-16 22:47 UTC+0300 ~ Maxim Skokov <skokovmaksimevg@gmail.com>
> Some BPF commands return ENOTSUPP (524) to user space: iterating local
> storage maps, element operations on ringbuf maps, creating an LRU hash
> map without preallocation, freezing a struct_ops map, or running a
> program type that has no test_run. ENOTSUPP is kernel internal, so
> strerror() only gives "Unknown error 524":
>
> # bpftool map getnext pinned /sys/fs/bpf/sk_storage
> Error: can't get next key: Unknown error 524
>
> Add a small helper that knows ENOTSUPP and use it where bpftool prints
> the error of map create, map element operations, map freeze and prog
> run.
>
> Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
> Assisted-by: LLM
> Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Acked-by: Quentin Monnet <qmo@kernel.org>
Thank you
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on maps that can't be iterated
2026-10-16 19:47 ` [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on " Maxim Skokov
@ 2026-10-16 20:08 ` qmo
0 siblings, 0 replies; 7+ messages in thread
From: qmo @ 2026-10-16 20:08 UTC (permalink / raw)
To: Maxim Skokov, bpf
Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
2026-10-16 22:47 UTC+0300 ~ Maxim Skokov <skokovmaksimevg@gmail.com>
> Socket storage can't be iterated from user space. Create a
> BPF_MAP_TYPE_SK_STORAGE map, attach storage to a socket, pin it, and
> check that "bpftool map dump" fails with nothing but an error: a JSON
> error object with -j, no elements on stdout in plain mode, and the
> reason on stderr.
>
> Socket storage always has BTF, so its plain dump goes through the BTF
> writer and never prints an element count. Check that path with a queue
> map created without BTF that holds one element: its plain dump must
> fail without a "Found" line, which bpftool printed as "Found 0
> elements" before, and give the reason on stderr.
>
> Assisted-by: LLM
> Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Acked-by: Quentin Monnet <qmo@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated
2026-10-16 19:47 [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
` (2 preceding siblings ...)
2026-10-16 19:47 ` [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on " Maxim Skokov
@ 2026-10-17 14:50 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-10-17 14:50 UTC (permalink / raw)
To: Maxim Skokov
Cc: bpf, qmo, ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
yonghong.song, jolsa, emil, ihor.solodrai, kuba, shuah,
linux-kselftest, hi
Hello:
This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:
On Fri, 16 Oct 2026 22:47:55 +0300 you wrote:
> "bpftool map dump" treats only ENOENT from bpf_map_get_next_key() as the
> end of the map. Map types that can't be iterated (local storage, ringbuf,
> bloom filter, arena, queue, stack) fail on the first key, and bpftool
> prints an empty dump, "[]" or "Found 0 elements", with only a non-zero
> exit status.
>
> Patch 1 adds a helper that prints ENOTSUPP (524), which the kernel
> returns from some BPF commands, as "Operation not supported" instead of
> "Unknown error 524", and uses it for map create, map element
> operations, map freeze and prog run. Patch 2 asks for the first key
> before printing anything and fails with the map type and the error.
> Patch 3 adds a test_progs case on a socket storage map, and on a queue
> map without BTF for the plain output path.
>
> [...]
Here is the summary with links:
- [bpf-next,v5,1/3] bpftool: Print ENOTSUPP as "Operation not supported"
https://git.kernel.org/bpf/bpf-next/c/b32b4956d451
- [bpf-next,v5,2/3] bpftool: Fail map dump for maps that can't be iterated
https://git.kernel.org/bpf/bpf-next/c/70ac4de43ad1
- [bpf-next,v5,3/3] selftests/bpf: Test bpftool map dump on maps that can't be iterated
https://git.kernel.org/bpf/bpf-next/c/631fee3f5a18
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-10-17 14:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16 19:47 [PATCH bpf-next v5 0/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 1/3] bpftool: Print ENOTSUPP as "Operation not supported" Maxim Skokov
2026-10-16 20:08 ` Quentin Monnet
2026-10-16 19:47 ` [PATCH bpf-next v5 2/3] bpftool: Fail map dump for maps that can't be iterated Maxim Skokov
2026-10-16 19:47 ` [PATCH bpf-next v5 3/3] selftests/bpf: Test bpftool map dump on " Maxim Skokov
2026-10-16 20:08 ` qmo
2026-10-17 14:50 ` [PATCH bpf-next v5 0/3] bpftool: Fail map dump for " patchwork-bot+netdevbpf
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.