tools/bpftool: Add bpftool support for bpf map element iterator
The optional parameter "map MAP" can be added to "bpftool iter" command to create a bpf iterator for map elements. For example, bpftool iter pin ./prog.o /sys/fs/bpf/p1 map id 333 For map element bpf iterator "map MAP" parameter is required. Otherwise, bpf link creation will return an error. Quentin Monnet kindly provided bash-completion implementation for new "map MAP" option. Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20200723184119.590799-1-yhs@fb.com
This commit is contained in:
Родитель
cd31039a73
Коммит
d8793aca70
|
@ -17,14 +17,15 @@ SYNOPSIS
|
|||
ITER COMMANDS
|
||||
===================
|
||||
|
||||
| **bpftool** **iter pin** *OBJ* *PATH*
|
||||
| **bpftool** **iter pin** *OBJ* *PATH* [**map** *MAP*]
|
||||
| **bpftool** **iter help**
|
||||
|
|
||||
| *OBJ* := /a/file/of/bpf_iter_target.o
|
||||
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
**bpftool iter pin** *OBJ* *PATH*
|
||||
**bpftool iter pin** *OBJ* *PATH* [**map** *MAP*]
|
||||
A bpf iterator combines a kernel iterating of
|
||||
particular kernel data (e.g., tasks, bpf_maps, etc.)
|
||||
and a bpf program called for each kernel data object
|
||||
|
@ -37,6 +38,12 @@ DESCRIPTION
|
|||
character ('.'), which is reserved for future extensions
|
||||
of *bpffs*.
|
||||
|
||||
Map element bpf iterator requires an additional parameter
|
||||
*MAP* so bpf program can iterate over map elements for
|
||||
that map. User can have a bpf program in kernel to run
|
||||
with each map element, do checking, filtering, aggregation,
|
||||
etc. without copying data to user space.
|
||||
|
||||
User can then *cat PATH* to see the bpf iterator output.
|
||||
|
||||
**bpftool iter help**
|
||||
|
@ -64,6 +71,13 @@ EXAMPLES
|
|||
Create a file-based bpf iterator from bpf_iter_netlink.o and pin it
|
||||
to /sys/fs/bpf/my_netlink
|
||||
|
||||
**# bpftool iter pin bpf_iter_hashmap.o /sys/fs/bpf/my_hashmap map id 20**
|
||||
|
||||
::
|
||||
|
||||
Create a file-based bpf iterator from bpf_iter_hashmap.o and map with
|
||||
id 20, and pin it to /sys/fs/bpf/my_hashmap
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
**bpf**\ (2),
|
||||
|
|
|
@ -615,7 +615,23 @@ _bpftool()
|
|||
iter)
|
||||
case $command in
|
||||
pin)
|
||||
_filedir
|
||||
case $prev in
|
||||
$command)
|
||||
_filedir
|
||||
;;
|
||||
id)
|
||||
_bpftool_get_map_ids
|
||||
;;
|
||||
name)
|
||||
_bpftool_get_map_names
|
||||
;;
|
||||
pinned)
|
||||
_filedir
|
||||
;;
|
||||
*)
|
||||
_bpftool_one_of_list $MAP_TYPE
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Copyright (C) 2020 Facebook
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <linux/err.h>
|
||||
#include <bpf/libbpf.h>
|
||||
|
||||
|
@ -9,11 +10,12 @@
|
|||
|
||||
static int do_pin(int argc, char **argv)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
|
||||
const char *objfile, *path;
|
||||
struct bpf_program *prog;
|
||||
struct bpf_object *obj;
|
||||
struct bpf_link *link;
|
||||
int err;
|
||||
int err = -1, map_fd = -1;
|
||||
|
||||
if (!REQ_ARGS(2))
|
||||
usage();
|
||||
|
@ -21,10 +23,26 @@ static int do_pin(int argc, char **argv)
|
|||
objfile = GET_ARG();
|
||||
path = GET_ARG();
|
||||
|
||||
/* optional arguments */
|
||||
if (argc) {
|
||||
if (is_prefix(*argv, "map")) {
|
||||
NEXT_ARG();
|
||||
|
||||
if (!REQ_ARGS(2)) {
|
||||
p_err("incorrect map spec");
|
||||
return -1;
|
||||
}
|
||||
|
||||
map_fd = map_parse_fd(&argc, &argv);
|
||||
if (map_fd < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
obj = bpf_object__open(objfile);
|
||||
if (IS_ERR(obj)) {
|
||||
p_err("can't open objfile %s", objfile);
|
||||
return -1;
|
||||
goto close_map_fd;
|
||||
}
|
||||
|
||||
err = bpf_object__load(obj);
|
||||
|
@ -39,7 +57,10 @@ static int do_pin(int argc, char **argv)
|
|||
goto close_obj;
|
||||
}
|
||||
|
||||
link = bpf_program__attach_iter(prog, NULL);
|
||||
if (map_fd >= 0)
|
||||
iter_opts.map_fd = map_fd;
|
||||
|
||||
link = bpf_program__attach_iter(prog, &iter_opts);
|
||||
if (IS_ERR(link)) {
|
||||
err = PTR_ERR(link);
|
||||
p_err("attach_iter failed for program %s",
|
||||
|
@ -62,14 +83,18 @@ close_link:
|
|||
bpf_link__destroy(link);
|
||||
close_obj:
|
||||
bpf_object__close(obj);
|
||||
close_map_fd:
|
||||
if (map_fd >= 0)
|
||||
close(map_fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_help(int argc, char **argv)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %1$s %2$s pin OBJ PATH\n"
|
||||
"Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
|
||||
" %1$s %2$s help\n"
|
||||
" " HELP_SPEC_MAP "\n"
|
||||
"",
|
||||
bin_name, "iter");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче