bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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).