mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
bpftool: Fail map dump for maps that can't be iterated
"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.
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Quentin Monnet <qmo@kernel.org>
Link: https://patch.msgid.link/20261016194825.230433-3-skokovmaksimevg@gmail.com
This commit is contained in:
parent
b32b4956d4
commit
70ac4de43a
|
|
@ -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" : "");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user