From: "Toke Høiland-Jørgensen" <toke@redhat.com>
To: Yonghong Song <yhs@fb.com>, YiFei Zhu <zhuyifei1999@gmail.com>,
bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Stanislav Fomichev <sdf@google.com>,
Mahesh Bandewar <maheshb@google.com>,
YiFei Zhu <zhuyifei@google.com>
Subject: Re: [PATCH bpf-next 4/5] bpftool: support dumping metadata
Date: Fri, 21 Aug 2020 10:58:14 +0200 [thread overview]
Message-ID: <877dts5qah.fsf@toke.dk> (raw)
In-Reply-To: <e02ae4a7-938f-222e-3139-5ba84e95df15@fb.com>
Yonghong Song <yhs@fb.com> writes:
> On 8/20/20 2:42 AM, YiFei Zhu wrote:
>> From: YiFei Zhu <zhuyifei@google.com>
>>
>> Added a flag "--metadata" to `bpftool prog list` to dump the metadata
>> contents. For some formatting some BTF code is put directly in the
>> metadata dumping. Sanity checks on the map and the kind of the btf_type
>> to make sure we are actually dumping what we are expecting.
>>
>> A helper jsonw_reset is added to json writer so we can reuse the same
>> json writer without having extraneous commas.
>>
>> Sample output:
>>
>> $ bpftool prog --metadata
>> 6: cgroup_skb name prog tag bcf7977d3b93787c gpl
>> [...]
>> btf_id 4
>> metadata:
>> metadata_a = "foo"
>> metadata_b = 1
>>
>> $ bpftool prog --metadata --json --pretty
>> [{
>> "id": 6,
>> [...]
>> "btf_id": 4,
>> "metadata": {
>> "metadata_a": "foo",
>> "metadata_b": 1
>> }
>> }
>> ]
>>
>> Signed-off-by: YiFei Zhu <zhuyifei@google.com>
>> ---
>> tools/bpf/bpftool/json_writer.c | 6 ++
>> tools/bpf/bpftool/json_writer.h | 3 +
>> tools/bpf/bpftool/main.c | 10 +++
>> tools/bpf/bpftool/main.h | 1 +
>> tools/bpf/bpftool/prog.c | 135 ++++++++++++++++++++++++++++++++
>> 5 files changed, 155 insertions(+)
>>
>> diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c
>> index 86501cd3c763..7fea83bedf48 100644
>> --- a/tools/bpf/bpftool/json_writer.c
>> +++ b/tools/bpf/bpftool/json_writer.c
>> @@ -119,6 +119,12 @@ void jsonw_pretty(json_writer_t *self, bool on)
>> self->pretty = on;
>> }
>>
>> +void jsonw_reset(json_writer_t *self)
>> +{
>> + assert(self->depth == 0);
>> + self->sep = '\0';
>> +}
>> +
>> /* Basic blocks */
>> static void jsonw_begin(json_writer_t *self, int c)
>> {
>> diff --git a/tools/bpf/bpftool/json_writer.h b/tools/bpf/bpftool/json_writer.h
>> index 35cf1f00f96c..8ace65cdb92f 100644
>> --- a/tools/bpf/bpftool/json_writer.h
>> +++ b/tools/bpf/bpftool/json_writer.h
>> @@ -27,6 +27,9 @@ void jsonw_destroy(json_writer_t **self_p);
>> /* Cause output to have pretty whitespace */
>> void jsonw_pretty(json_writer_t *self, bool on);
>>
>> +/* Reset separator to create new JSON */
>> +void jsonw_reset(json_writer_t *self);
>> +
>> /* Add property name */
>> void jsonw_name(json_writer_t *self, const char *name);
>>
>> diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
>> index 4a191fcbeb82..a681d568cfa7 100644
>> --- a/tools/bpf/bpftool/main.c
>> +++ b/tools/bpf/bpftool/main.c
>> @@ -28,6 +28,7 @@ bool show_pinned;
>> bool block_mount;
>> bool verifier_logs;
>> bool relaxed_maps;
>> +bool dump_metadata;
>> struct pinned_obj_table prog_table;
>> struct pinned_obj_table map_table;
>> struct pinned_obj_table link_table;
>> @@ -351,6 +352,10 @@ static int do_batch(int argc, char **argv)
>> return err;
>> }
>>
>> +enum bpftool_longonly_opts {
>> + OPT_METADATA = 256,
>> +};
>> +
>> int main(int argc, char **argv)
>> {
>> static const struct option options[] = {
>> @@ -362,6 +367,7 @@ int main(int argc, char **argv)
>> { "mapcompat", no_argument, NULL, 'm' },
>> { "nomount", no_argument, NULL, 'n' },
>> { "debug", no_argument, NULL, 'd' },
>> + { "metadata", no_argument, NULL, OPT_METADATA },
>> { 0 }
>> };
>> int opt, ret;
>> @@ -371,6 +377,7 @@ int main(int argc, char **argv)
>> json_output = false;
>> show_pinned = false;
>> block_mount = false;
>> + dump_metadata = false;
>> bin_name = argv[0];
>>
>> hash_init(prog_table.table);
>> @@ -412,6 +419,9 @@ int main(int argc, char **argv)
>> libbpf_set_print(print_all_levels);
>> verifier_logs = true;
>> break;
>> + case OPT_METADATA:
>> + dump_metadata = true;
>> + break;
>> default:
>> p_err("unrecognized option '%s'", argv[optind - 1]);
>> if (json_output)
>> diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
>> index c46e52137b87..8750758e9150 100644
>> --- a/tools/bpf/bpftool/main.h
>> +++ b/tools/bpf/bpftool/main.h
>> @@ -90,6 +90,7 @@ extern bool show_pids;
>> extern bool block_mount;
>> extern bool verifier_logs;
>> extern bool relaxed_maps;
>> +extern bool dump_metadata;
>> extern struct pinned_obj_table prog_table;
>> extern struct pinned_obj_table map_table;
>> extern struct pinned_obj_table link_table;
>> diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
>> index d393eb8263a6..ee767b8d90fb 100644
>> --- a/tools/bpf/bpftool/prog.c
>> +++ b/tools/bpf/bpftool/prog.c
>> @@ -151,6 +151,135 @@ static void show_prog_maps(int fd, __u32 num_maps)
>> }
>> }
>>
>> +static void show_prog_metadata(int fd, __u32 num_maps)
>> +{
>> + struct bpf_prog_info prog_info = {};
>> + struct bpf_map_info map_info = {};
>> + __u32 prog_info_len = sizeof(prog_info);
>> + __u32 map_info_len = sizeof(map_info);
>> + __u32 map_ids[num_maps];
>> + void *value = NULL;
>> + struct btf *btf = NULL;
>> + const struct btf_type *t_datasec, *t_var;
>> + struct btf_var_secinfo *vsi;
>> + int key = 0;
>> + unsigned int i, vlen;
>> + int map_fd;
>> + int err;
>
> try to follow reverse christmas tree coding styple?
>
>> +
>> + prog_info.nr_map_ids = num_maps;
>> + prog_info.map_ids = ptr_to_u64(map_ids);
>> +
>> + err = bpf_obj_get_info_by_fd(fd, &prog_info, &prog_info_len);
>> + if (err || !prog_info.nr_map_ids)
>> + return;
>
> print out something for "err" case and "!prog_info.nr_map_ids" case?
> The same for some other below returns.
>
>> +
>> + for (i = 0; i < prog_info.nr_map_ids; i++) {
>> + map_fd = bpf_map_get_fd_by_id(map_ids[i]);
>> + if (map_fd < 0)
>> + return;
>> +
>> + err = bpf_obj_get_info_by_fd(map_fd, &map_info, &map_info_len);
>> + if (err)
>> + goto out_close;
>> +
>> + if (map_info.type != BPF_MAP_TYPE_ARRAY)
>> + goto next_map;
>> + if (map_info.key_size != sizeof(int))
>> + goto next_map;
>> + if (map_info.max_entries != 1)
>> + goto next_map;
>> + if (!map_info.btf_value_type_id)
>> + goto next_map;
>> + if (!strstr(map_info.name, ".metadata"))
>> + goto next_map;
>> +
>> + goto found;
>> +
>> +next_map:
>> + close(map_fd);
>> + }
>> +
>> + return;
>> +
>> +found:
>> + value = malloc(map_info.value_size);
>> + if (!value)
>> + goto out_close;
>> +
>> + if (bpf_map_lookup_elem(map_fd, &key, value))
>> + goto out_free;
>
> Not sure whether we need formal libbpf API to access metadata or not.
> This may help other applications too. But we can delay until it is
> necessary.
Yeah, please put in a libbpf accessor as well; I would like to use this
from libxdp - without a skeleton :)
-Toke
next prev parent reply other threads:[~2020-08-21 8:58 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-20 9:42 [PATCH bpf-next 0/5] Allow storage of flexible metadata information for eBPF programs YiFei Zhu
2020-08-20 9:42 ` [PATCH bpf-next 1/5] bpf: Mutex protect used_maps array and count YiFei Zhu
2020-08-20 21:18 ` Yonghong Song
2020-08-20 9:42 ` [PATCH bpf-next 2/5] bpf: Add BPF_PROG_BIND_MAP syscall YiFei Zhu
2020-08-20 21:23 ` Yonghong Song
2020-08-20 9:42 ` [PATCH bpf-next 3/5] libbpf: Add BPF_PROG_BIND_MAP syscall and use it on .metadata section YiFei Zhu
2020-08-20 20:38 ` Yonghong Song
2020-08-21 7:52 ` YiFei Zhu
2020-08-21 15:14 ` Yonghong Song
2020-08-25 20:45 ` Andrey Ignatov
2020-08-26 4:02 ` Andrii Nakryiko
2020-08-20 9:42 ` [PATCH bpf-next 4/5] bpftool: support dumping metadata YiFei Zhu
2020-08-20 21:11 ` Yonghong Song
2020-08-21 8:58 ` Toke Høiland-Jørgensen [this message]
2020-08-21 20:10 ` YiFei Zhu
2020-08-23 18:36 ` Toke Høiland-Jørgensen
2020-08-28 17:00 ` sdf
2020-08-28 20:55 ` Toke Høiland-Jørgensen
2020-08-26 5:36 ` Andrii Nakryiko
2020-08-28 16:59 ` sdf
2020-09-03 5:18 ` Andrii Nakryiko
2020-08-20 9:42 ` [PATCH bpf-next 5/5] selftests/bpf: Test bpftool loading and " YiFei Zhu
2020-08-20 21:15 ` Yonghong Song
2020-08-26 4:00 ` Andrii Nakryiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=877dts5qah.fsf@toke.dk \
--to=toke@redhat.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=maheshb@google.com \
--cc=sdf@google.com \
--cc=yhs@fb.com \
--cc=zhuyifei1999@gmail.com \
--cc=zhuyifei@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).