Hi all,
I have tried looking at an issue from the bpftool repository: https://github.com/libbpf/bpftool/issues/121 and this RFC tries to add that enhancement.
Summary: Currently when a map creation is successful there is no message on the terminal, printing IDs on successful creation of maps can help notify the user and can be used in CI/CD.
The first patch adds the logic for printing and the second patch adds a simple selftest for the same.
The github issue is not fully solved with these two patches, as there are other bpf objects that might need similar additions. Would appreciate any inputs on this.
Thank you very much.
V1 --> V2: PATCH 1 updated [Thanks Yonghong for suggesting better way of error handling with a new label for close(fd); instead of calling multiple times]
Regards, Harshit
Harshit Mogalapalli (2): bpftool: Print map ID upon creation and support JSON output selftests/bpf: Add test for bpftool map ID printing
tools/bpf/bpftool/map.c | 21 ++++++++--- .../testing/selftests/bpf/test_bpftool_map.sh | 36 +++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-)
It is useful to print map ID on successful creation.
JSON case: $ ./bpftool -j map create /sys/fs/bpf/test_map4 type hash key 4 value 8 entries 128 name map4 {"id":12}
Generic case: $ ./bpftool map create /sys/fs/bpf/test_map5 type hash key 4 value 8 entries 128 name map5 Map successfully created with ID: 15
Bpftool Issue: https://github.com/libbpf/bpftool/issues/121 Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com --- tools/bpf/bpftool/map.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index c9de44a45778..80c96b33b553 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -1251,6 +1251,8 @@ static int do_create(int argc, char **argv) LIBBPF_OPTS(bpf_map_create_opts, attr); enum bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC; __u32 key_size = 0, value_size = 0, max_entries = 0; + struct bpf_map_info map_info = {}; + __u32 map_info_len = sizeof(map_info); const char *map_name = NULL; const char *pinfile; int err = -1, fd; @@ -1353,13 +1355,24 @@ static int do_create(int argc, char **argv) }
err = do_pin_fd(fd, pinfile); - close(fd); if (err) - goto exit; + goto close_fd;
- if (json_output) - jsonw_null(json_wtr); + err = bpf_obj_get_info_by_fd(fd, &map_info, &map_info_len); + if (err) { + p_err("Failed to fetch map info: %s\n", strerror(errno)); + goto close_fd; + }
+ if (json_output) { + jsonw_start_object(json_wtr); + jsonw_int_field(json_wtr, "id", map_info.id); + jsonw_end_object(json_wtr); + } else { + printf("Map successfully created with ID: %u\n", map_info.id); + } +close_fd: + close(fd); exit: if (attr.inner_map_fd > 0) close(attr.inner_map_fd);
On 10/30/25 2:06 PM, Harshit Mogalapalli wrote:
It is useful to print map ID on successful creation.
JSON case: $ ./bpftool -j map create /sys/fs/bpf/test_map4 type hash key 4 value 8 entries 128 name map4 {"id":12}
Generic case: $ ./bpftool map create /sys/fs/bpf/test_map5 type hash key 4 value 8 entries 128 name map5 Map successfully created with ID: 15
Bpftool Issue: https://github.com/libbpf/bpftool/issues/121 Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Acked-by: Yonghong Song yonghong.song@linux.dev
2025-10-30 14:06 UTC-0700 ~ Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
It is useful to print map ID on successful creation.
JSON case: $ ./bpftool -j map create /sys/fs/bpf/test_map4 type hash key 4 value 8 entries 128 name map4 {"id":12}
Generic case: $ ./bpftool map create /sys/fs/bpf/test_map5 type hash key 4 value 8 entries 128 name map5 Map successfully created with ID: 15
Bpftool Issue: https://github.com/libbpf/bpftool/issues/121 Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
tools/bpf/bpftool/map.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index c9de44a45778..80c96b33b553 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -1251,6 +1251,8 @@ static int do_create(int argc, char **argv) LIBBPF_OPTS(bpf_map_create_opts, attr); enum bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC; __u32 key_size = 0, value_size = 0, max_entries = 0;
- struct bpf_map_info map_info = {};
- __u32 map_info_len = sizeof(map_info); const char *map_name = NULL; const char *pinfile; int err = -1, fd;
@@ -1353,13 +1355,24 @@ static int do_create(int argc, char **argv) } err = do_pin_fd(fd, pinfile);
- close(fd); if (err)
goto exit;
goto close_fd;
- if (json_output)
jsonw_null(json_wtr);
- err = bpf_obj_get_info_by_fd(fd, &map_info, &map_info_len);
- if (err) {
p_err("Failed to fetch map info: %s\n", strerror(errno));
Nit: Please remove the line break ('\n') here, p_err() already adds it.
goto close_fd;- }
- if (json_output) {
jsonw_start_object(json_wtr);jsonw_int_field(json_wtr, "id", map_info.id);jsonw_end_object(json_wtr);
I've been wondering if we should have some parent object like '{"map_created": { "id": 15 }}' in case we later add more output, but I can't really see a good use case at the moment, I'm probably overthinking it... So I'm good with the current output. Thanks for this!
With the line break removed:
Reviewed-by: Quentin Monnet qmo@kernel.org
Hi Quentin,
On 01/11/25 22:29, Quentin Monnet wrote:
2025-10-30 14:06 UTC-0700 ~ Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
It is useful to print map ID on successful creation.
JSON case: $ ./bpftool -j map create /sys/fs/bpf/test_map4 type hash key 4 value 8 entries 128 name map4 {"id":12}
Generic case: $ ./bpftool map create /sys/fs/bpf/test_map5 type hash key 4 value 8 entries 128 name map5 Map successfully created with ID: 15
Bpftool Issue: https://github.com/libbpf/bpftool/issues/121 Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
tools/bpf/bpftool/map.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index c9de44a45778..80c96b33b553 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -1251,6 +1251,8 @@ static int do_create(int argc, char **argv) LIBBPF_OPTS(bpf_map_create_opts, attr); enum bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC; __u32 key_size = 0, value_size = 0, max_entries = 0;
- struct bpf_map_info map_info = {};
- __u32 map_info_len = sizeof(map_info); const char *map_name = NULL; const char *pinfile; int err = -1, fd;
@@ -1353,13 +1355,24 @@ static int do_create(int argc, char **argv) } err = do_pin_fd(fd, pinfile);
- close(fd); if (err)
goto exit;
goto close_fd;
- if (json_output)
jsonw_null(json_wtr);
- err = bpf_obj_get_info_by_fd(fd, &map_info, &map_info_len);
- if (err) {
p_err("Failed to fetch map info: %s\n", strerror(errno));Nit: Please remove the line break ('\n') here, p_err() already adds it.
Ah thanks for spotting that, will do.
goto close_fd;- }
- if (json_output) {
jsonw_start_object(json_wtr);jsonw_int_field(json_wtr, "id", map_info.id);jsonw_end_object(json_wtr);I've been wondering if we should have some parent object like '{"map_created": { "id": 15 }}' in case we later add more output, but I can't really see a good use case at the moment, I'm probably overthinking it... So I'm good with the current output. Thanks for this!
Thanks a lot for the review.
With the line break removed:
Sure will send a next version with updates to p_err and selftest(to not echo messages on success)
Reviewed-by: Quentin Monnet qmo@kernel.org
Regards, Harshit
Add selftest to check if Map ID is printed on successful creation in both plain text and json formats.
Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com --- .../testing/selftests/bpf/test_bpftool_map.sh | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/tools/testing/selftests/bpf/test_bpftool_map.sh b/tools/testing/selftests/bpf/test_bpftool_map.sh index 515b1df0501e..013a64e96cbf 100755 --- a/tools/testing/selftests/bpf/test_bpftool_map.sh +++ b/tools/testing/selftests/bpf/test_bpftool_map.sh @@ -361,6 +361,40 @@ test_map_access_with_btf_list() { fi }
+# Function to test map ID printing +# Parameters: +# $1: bpftool path +# $2: BPF_DIR +test_map_id_printing() { + local bpftool_path="$1" + local bpf_dir="$2" + local test_map_name="test_map_id" + local test_map_path="$bpf_dir/$test_map_name" + + local output + output=$("$bpftool_path" map create "$test_map_path" type hash key 4 \ + value 8 entries 128 name "$test_map_name") + if echo "$output" | grep -q "Map successfully created with ID:"; then + echo "PASS: Map ID printed in plain text output." + else + echo "FAIL: Map ID not printed in plain text output." + exit 1 + fi + + rm -f "$test_map_path" + + output=$("$bpftool_path" map create "$test_map_path" type hash key 4 \ + value 8 entries 128 name "$test_map_name" --json) + if echo "$output" | jq -e 'has("id")' >/dev/null 2>&1; then + echo "PASS: Map ID printed in JSON output." + else + echo "FAIL: Map ID not printed in JSON output." + exit 1 + fi + + rm -f "$test_map_path" +} + set -eu
trap cleanup_skip EXIT @@ -395,4 +429,6 @@ test_map_creation_and_map_of_maps "$BPFTOOL_PATH" "$BPF_DIR"
test_map_access_with_btf_list "$BPFTOOL_PATH"
+test_map_id_printing "$BPFTOOL_PATH" "$BPF_DIR" + exit 0
2025-10-30 14:06 UTC-0700 ~ Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Add selftest to check if Map ID is printed on successful creation in both plain text and json formats.
Signed-off-by: Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
.../testing/selftests/bpf/test_bpftool_map.sh | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/tools/testing/selftests/bpf/test_bpftool_map.sh b/tools/testing/selftests/bpf/test_bpftool_map.sh index 515b1df0501e..013a64e96cbf 100755 --- a/tools/testing/selftests/bpf/test_bpftool_map.sh +++ b/tools/testing/selftests/bpf/test_bpftool_map.sh @@ -361,6 +361,40 @@ test_map_access_with_btf_list() { fi } +# Function to test map ID printing +# Parameters: +# $1: bpftool path +# $2: BPF_DIR +test_map_id_printing() {
- local bpftool_path="$1"
- local bpf_dir="$2"
- local test_map_name="test_map_id"
- local test_map_path="$bpf_dir/$test_map_name"
- local output
- output=$("$bpftool_path" map create "$test_map_path" type hash key 4 \
value 8 entries 128 name "$test_map_name")- if echo "$output" | grep -q "Map successfully created with ID:"; then
echo "PASS: Map ID printed in plain text output."- else
echo "FAIL: Map ID not printed in plain text output."exit 1
Other tests in the file print a message only on failure, without a "FAIL:" prefix. Could you do the same, for consistency and brevity? Same for the JSON test.
Thanks, Quentin
2025-10-30 14:06 UTC-0700 ~ Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Hi all,
I have tried looking at an issue from the bpftool repository: https://github.com/libbpf/bpftool/issues/121 and this RFC tries to add
This is not longer a RFC :)
that enhancement.
Summary: Currently when a map creation is successful there is no message on the terminal, printing IDs on successful creation of maps can help notify the user and can be used in CI/CD.
The first patch adds the logic for printing and the second patch adds a simple selftest for the same.
The github issue is not fully solved with these two patches, as there are other bpf objects that might need similar additions. Would appreciate any inputs on this.
What's your question, exactly?
Thanks, Quentin
Hi Quentin,
On 01/11/25 22:29, Quentin Monnet wrote:
2025-10-30 14:06 UTC-0700 ~ Harshit Mogalapalli harshit.m.mogalapalli@oracle.com
Hi all,
I have tried looking at an issue from the bpftool repository: https://github.com/libbpf/bpftool/issues/121 and this RFC tries to add
This is not longer a RFC :)
Oh, right, I used part of it from my RFC cover letter, sorry about that.
that enhancement.
Summary: Currently when a map creation is successful there is no message on the terminal, printing IDs on successful creation of maps can help notify the user and can be used in CI/CD.
The first patch adds the logic for printing and the second patch adds a simple selftest for the same.
The github issue is not fully solved with these two patches, as there are other bpf objects that might need similar additions. Would appreciate any inputs on this.
What's your question, exactly?
If I understand the issue correctly, the goal is to improve usability and CI support by printing IDs or other relevant information to the terminal upon creation of BPF objects, instead of producing no output as is currently the case. For maps, printing the map ID on creation is particularly helpful.
In addition to maps, I believe it would be beneficial to print the ID when loading a program. I am currently working on implementing this enhancement.
Are there any other BPF objects where displaying additional information (such as IDs or relevant metadata) on the terminal would be useful?
Thank you!
Regards, Harshit
Thanks, Quentin
linux-kselftest-mirror@lists.linaro.org