Commit 99f9863a authored by Paul Chaignon's avatar Paul Chaignon Committed by Alexei Starovoitov

bpftool: Match maps by name

This patch implements lookup by name for maps and changes the behavior of
lookups by tag to be consistent with prog subcommands.  Similarly to
program subcommands, the show and dump commands will return all maps with
the given name (or tag), whereas other commands will error out if several
maps have the same name (resp. tag).

When a map has BTF info, it is dumped in JSON with available BTF info.
This patch requires that all matched maps have BTF info before switching
the output format to JSON.
Signed-off-by: default avatarPaul Chaignon <paul.chaignon@orange.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/8de1c9f273860b3ea1680502928f4da2336b853e.1576263640.git.paul.chaignon@gmail.com
parent a7d22ca2
...@@ -39,7 +39,7 @@ MAP COMMANDS ...@@ -39,7 +39,7 @@ MAP COMMANDS
| **bpftool** **map freeze** *MAP* | **bpftool** **map freeze** *MAP*
| **bpftool** **map help** | **bpftool** **map help**
| |
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* | **name** *MAP_NAME* }
| *DATA* := { [**hex**] *BYTES* } | *DATA* := { [**hex**] *BYTES* }
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* } | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
| *VALUE* := { *DATA* | *MAP* | *PROG* } | *VALUE* := { *DATA* | *MAP* | *PROG* }
...@@ -55,8 +55,9 @@ DESCRIPTION ...@@ -55,8 +55,9 @@ DESCRIPTION
=========== ===========
**bpftool map { show | list }** [*MAP*] **bpftool map { show | list }** [*MAP*]
Show information about loaded maps. If *MAP* is specified Show information about loaded maps. If *MAP* is specified
show information only about given map, otherwise list all show information only about given maps, otherwise list all
maps currently loaded on the system. maps currently loaded on the system. In case of **name**,
*MAP* may match several maps which will all be shown.
Output will start with map ID followed by map type and Output will start with map ID followed by map type and
zero or more named attributes (depending on kernel version). zero or more named attributes (depending on kernel version).
...@@ -66,7 +67,8 @@ DESCRIPTION ...@@ -66,7 +67,8 @@ DESCRIPTION
as *FILE*. as *FILE*.
**bpftool map dump** *MAP* **bpftool map dump** *MAP*
Dump all entries in a given *MAP*. Dump all entries in a given *MAP*. In case of **name**,
*MAP* may match several maps which will all be dumped.
**bpftool map update** *MAP* [**key** *DATA*] [**value** *VALUE*] [*UPDATE_FLAGS*] **bpftool map update** *MAP* [**key** *DATA*] [**value** *VALUE*] [*UPDATE_FLAGS*]
Update map entry for a given *KEY*. Update map entry for a given *KEY*.
......
...@@ -59,6 +59,21 @@ _bpftool_get_map_ids_for_type() ...@@ -59,6 +59,21 @@ _bpftool_get_map_ids_for_type()
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
} }
_bpftool_get_map_names()
{
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
}
# Takes map type and adds matching map names to the list of suggestions.
_bpftool_get_map_names_for_type()
{
local type="$1"
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
command grep -C2 "$type" | \
command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
}
_bpftool_get_prog_ids() _bpftool_get_prog_ids()
{ {
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \ COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
...@@ -186,6 +201,52 @@ _bpftool_map_update_get_id() ...@@ -186,6 +201,52 @@ _bpftool_map_update_get_id()
esac esac
} }
_bpftool_map_update_get_name()
{
local command="$1"
# Is it the map to update, or a map to insert into the map to update?
# Search for "value" keyword.
local idx value
for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
if [[ ${words[idx]} == "value" ]]; then
value=1
break
fi
done
if [[ $value -eq 0 ]]; then
case "$command" in
push)
_bpftool_get_map_names_for_type stack
;;
enqueue)
_bpftool_get_map_names_for_type queue
;;
*)
_bpftool_get_map_names
;;
esac
return 0
fi
# Name to complete is for a value. It can be either prog name or map name. This
# depends on the type of the map to update.
local type=$(_bpftool_map_guess_map_type)
case $type in
array_of_maps|hash_of_maps)
_bpftool_get_map_names
return 0
;;
prog_array)
_bpftool_get_prog_names
return 0
;;
*)
return 0
;;
esac
}
_bpftool() _bpftool()
{ {
local cur prev words objword local cur prev words objword
...@@ -207,10 +268,6 @@ _bpftool() ...@@ -207,10 +268,6 @@ _bpftool()
_bpftool_get_prog_tags _bpftool_get_prog_tags
return 0 return 0
;; ;;
name)
_bpftool_get_prog_names
return 0
;;
dev) dev)
_sysfs_get_netdevs _sysfs_get_netdevs
return 0 return 0
...@@ -261,7 +318,8 @@ _bpftool() ...@@ -261,7 +318,8 @@ _bpftool()
# Completion depends on object and command in use # Completion depends on object and command in use
case $object in case $object in
prog) prog)
# Complete id, only for subcommands that use prog (but no map) ids # Complete id and name, only for subcommands that use prog (but no
# map) ids/names.
case $command in case $command in
show|list|dump|pin) show|list|dump|pin)
case $prev in case $prev in
...@@ -269,12 +327,16 @@ _bpftool() ...@@ -269,12 +327,16 @@ _bpftool()
_bpftool_get_prog_ids _bpftool_get_prog_ids
return 0 return 0
;; ;;
name)
_bpftool_get_prog_names
return 0
;;
esac esac
;; ;;
esac esac
local PROG_TYPE='id pinned tag name' local PROG_TYPE='id pinned tag name'
local MAP_TYPE='id pinned' local MAP_TYPE='id pinned name'
case $command in case $command in
show|list) show|list)
[[ $prev != "$command" ]] && return 0 [[ $prev != "$command" ]] && return 0
...@@ -325,6 +387,9 @@ _bpftool() ...@@ -325,6 +387,9 @@ _bpftool()
id) id)
_bpftool_get_prog_ids _bpftool_get_prog_ids
;; ;;
name)
_bpftool_get_map_names
;;
pinned) pinned)
_filedir _filedir
;; ;;
...@@ -345,6 +410,9 @@ _bpftool() ...@@ -345,6 +410,9 @@ _bpftool()
id) id)
_bpftool_get_map_ids _bpftool_get_map_ids
;; ;;
name)
_bpftool_get_map_names
;;
pinned) pinned)
_filedir _filedir
;; ;;
...@@ -409,6 +477,10 @@ _bpftool() ...@@ -409,6 +477,10 @@ _bpftool()
_bpftool_get_map_ids _bpftool_get_map_ids
return 0 return 0
;; ;;
name)
_bpftool_get_map_names
return 0
;;
pinned|pinmaps) pinned|pinmaps)
_filedir _filedir
return 0 return 0
...@@ -457,7 +529,7 @@ _bpftool() ...@@ -457,7 +529,7 @@ _bpftool()
esac esac
;; ;;
map) map)
local MAP_TYPE='id pinned' local MAP_TYPE='id pinned name'
case $command in case $command in
show|list|dump|peek|pop|dequeue|freeze) show|list|dump|peek|pop|dequeue|freeze)
case $prev in case $prev in
...@@ -483,6 +555,24 @@ _bpftool() ...@@ -483,6 +555,24 @@ _bpftool()
esac esac
return 0 return 0
;; ;;
name)
case "$command" in
peek)
_bpftool_get_map_names_for_type stack
_bpftool_get_map_names_for_type queue
;;
pop)
_bpftool_get_map_names_for_type stack
;;
dequeue)
_bpftool_get_map_names_for_type queue
;;
*)
_bpftool_get_map_names
;;
esac
return 0
;;
*) *)
return 0 return 0
;; ;;
...@@ -530,6 +620,10 @@ _bpftool() ...@@ -530,6 +620,10 @@ _bpftool()
_bpftool_get_map_ids _bpftool_get_map_ids
return 0 return 0
;; ;;
name)
_bpftool_get_map_names
return 0
;;
key) key)
COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) ) COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
;; ;;
...@@ -555,6 +649,10 @@ _bpftool() ...@@ -555,6 +649,10 @@ _bpftool()
_bpftool_map_update_get_id $command _bpftool_map_update_get_id $command
return 0 return 0
;; ;;
name)
_bpftool_map_update_get_name $command
return 0
;;
key) key)
COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) ) COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
;; ;;
...@@ -563,7 +661,7 @@ _bpftool() ...@@ -563,7 +661,7 @@ _bpftool()
# map, depending on the type of the map to update. # map, depending on the type of the map to update.
case "$(_bpftool_map_guess_map_type)" in case "$(_bpftool_map_guess_map_type)" in
array_of_maps|hash_of_maps) array_of_maps|hash_of_maps)
local MAP_TYPE='id pinned' local MAP_TYPE='id pinned name'
COMPREPLY+=( $( compgen -W "$MAP_TYPE" \ COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
-- "$cur" ) ) -- "$cur" ) )
return 0 return 0
...@@ -631,6 +729,10 @@ _bpftool() ...@@ -631,6 +729,10 @@ _bpftool()
_bpftool_get_map_ids_for_type perf_event_array _bpftool_get_map_ids_for_type perf_event_array
return 0 return 0
;; ;;
name)
_bpftool_get_map_names_for_type perf_event_array
return 0
;;
cpu) cpu)
return 0 return 0
;; ;;
...@@ -655,7 +757,7 @@ _bpftool() ...@@ -655,7 +757,7 @@ _bpftool()
;; ;;
btf) btf)
local PROG_TYPE='id pinned tag name' local PROG_TYPE='id pinned tag name'
local MAP_TYPE='id pinned' local MAP_TYPE='id pinned name'
case $command in case $command in
dump) dump)
case $prev in case $prev in
...@@ -686,6 +788,17 @@ _bpftool() ...@@ -686,6 +788,17 @@ _bpftool()
esac esac
return 0 return 0
;; ;;
name)
case $pprev in
prog)
_bpftool_get_prog_names
;;
map)
_bpftool_get_map_names
;;
esac
return 0
;;
format) format)
COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) ) COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
;; ;;
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \ "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \
"\t {-m|--mapcompat} | {-n|--nomount} }" "\t {-m|--mapcompat} | {-n|--nomount} }"
#define HELP_SPEC_MAP \ #define HELP_SPEC_MAP \
"MAP := { id MAP_ID | pinned FILE }" "MAP := { id MAP_ID | pinned FILE | name MAP_NAME }"
static const char * const prog_type_name[] = { static const char * const prog_type_name[] = {
[BPF_PROG_TYPE_UNSPEC] = "unspec", [BPF_PROG_TYPE_UNSPEC] = "unspec",
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment