bpftool: Use libbpf_bpf_map_type_str
This change switches bpftool over to using the recently introduced libbpf_bpf_map_type_str function instead of maintaining its own string representation for the bpf_map_type enum. Signed-off-by: Daniel Müller <deso@posteo.net> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Quentin Monnet <quentin@isovalent.com> Link: https://lore.kernel.org/bpf/20220523230428.3077108-7-deso@posteo.net
This commit is contained in:
Родитель
c3a2574011
Коммит
2e98964bd6
|
@ -615,8 +615,8 @@ static bool probe_map_type_ifindex(enum bpf_map_type map_type, __u32 ifindex)
|
|||
}
|
||||
|
||||
static void
|
||||
probe_map_type(enum bpf_map_type map_type, const char *define_prefix,
|
||||
__u32 ifindex)
|
||||
probe_map_type(enum bpf_map_type map_type, char const *map_type_str,
|
||||
const char *define_prefix, __u32 ifindex)
|
||||
{
|
||||
char feat_name[128], plain_desc[128], define_name[128];
|
||||
const char *plain_comment = "eBPF map_type ";
|
||||
|
@ -641,20 +641,16 @@ probe_map_type(enum bpf_map_type map_type, const char *define_prefix,
|
|||
* check required for unprivileged users
|
||||
*/
|
||||
|
||||
if (!map_type_name[map_type]) {
|
||||
p_info("map type name not found (type %d)", map_type);
|
||||
return;
|
||||
}
|
||||
maxlen = sizeof(plain_desc) - strlen(plain_comment) - 1;
|
||||
if (strlen(map_type_name[map_type]) > maxlen) {
|
||||
if (strlen(map_type_str) > maxlen) {
|
||||
p_info("map type name too long");
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(feat_name, "have_%s_map_type", map_type_name[map_type]);
|
||||
sprintf(define_name, "%s_map_type", map_type_name[map_type]);
|
||||
sprintf(feat_name, "have_%s_map_type", map_type_str);
|
||||
sprintf(define_name, "%s_map_type", map_type_str);
|
||||
uppercase(define_name, sizeof(define_name));
|
||||
sprintf(plain_desc, "%s%s", plain_comment, map_type_name[map_type]);
|
||||
sprintf(plain_desc, "%s%s", plain_comment, map_type_str);
|
||||
print_bool_feature(feat_name, plain_desc, define_name, res,
|
||||
define_prefix);
|
||||
}
|
||||
|
@ -963,15 +959,23 @@ section_program_types(bool *supported_types, const char *define_prefix,
|
|||
|
||||
static void section_map_types(const char *define_prefix, __u32 ifindex)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int map_type = BPF_MAP_TYPE_UNSPEC;
|
||||
const char *map_type_str;
|
||||
|
||||
print_start_section("map_types",
|
||||
"Scanning eBPF map types...",
|
||||
"/*** eBPF map types ***/",
|
||||
define_prefix);
|
||||
|
||||
for (i = BPF_MAP_TYPE_UNSPEC + 1; i < map_type_name_size; i++)
|
||||
probe_map_type(i, define_prefix, ifindex);
|
||||
while (true) {
|
||||
map_type++;
|
||||
map_type_str = libbpf_bpf_map_type_str(map_type);
|
||||
/* libbpf will return NULL for variants unknown to it. */
|
||||
if (!map_type_str)
|
||||
break;
|
||||
|
||||
probe_map_type(map_type, map_type_str, define_prefix, ifindex);
|
||||
}
|
||||
|
||||
print_end_section();
|
||||
}
|
||||
|
|
|
@ -65,9 +65,6 @@ static inline void *u64_to_ptr(__u64 ptr)
|
|||
|
||||
extern const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE];
|
||||
|
||||
extern const char * const map_type_name[];
|
||||
extern const size_t map_type_name_size;
|
||||
|
||||
/* keep in sync with the definition in skeleton/pid_iter.bpf.c */
|
||||
enum bpf_obj_type {
|
||||
BPF_OBJ_UNKNOWN,
|
||||
|
|
|
@ -22,42 +22,6 @@
|
|||
#include "json_writer.h"
|
||||
#include "main.h"
|
||||
|
||||
const char * const map_type_name[] = {
|
||||
[BPF_MAP_TYPE_UNSPEC] = "unspec",
|
||||
[BPF_MAP_TYPE_HASH] = "hash",
|
||||
[BPF_MAP_TYPE_ARRAY] = "array",
|
||||
[BPF_MAP_TYPE_PROG_ARRAY] = "prog_array",
|
||||
[BPF_MAP_TYPE_PERF_EVENT_ARRAY] = "perf_event_array",
|
||||
[BPF_MAP_TYPE_PERCPU_HASH] = "percpu_hash",
|
||||
[BPF_MAP_TYPE_PERCPU_ARRAY] = "percpu_array",
|
||||
[BPF_MAP_TYPE_STACK_TRACE] = "stack_trace",
|
||||
[BPF_MAP_TYPE_CGROUP_ARRAY] = "cgroup_array",
|
||||
[BPF_MAP_TYPE_LRU_HASH] = "lru_hash",
|
||||
[BPF_MAP_TYPE_LRU_PERCPU_HASH] = "lru_percpu_hash",
|
||||
[BPF_MAP_TYPE_LPM_TRIE] = "lpm_trie",
|
||||
[BPF_MAP_TYPE_ARRAY_OF_MAPS] = "array_of_maps",
|
||||
[BPF_MAP_TYPE_HASH_OF_MAPS] = "hash_of_maps",
|
||||
[BPF_MAP_TYPE_DEVMAP] = "devmap",
|
||||
[BPF_MAP_TYPE_DEVMAP_HASH] = "devmap_hash",
|
||||
[BPF_MAP_TYPE_SOCKMAP] = "sockmap",
|
||||
[BPF_MAP_TYPE_CPUMAP] = "cpumap",
|
||||
[BPF_MAP_TYPE_XSKMAP] = "xskmap",
|
||||
[BPF_MAP_TYPE_SOCKHASH] = "sockhash",
|
||||
[BPF_MAP_TYPE_CGROUP_STORAGE] = "cgroup_storage",
|
||||
[BPF_MAP_TYPE_REUSEPORT_SOCKARRAY] = "reuseport_sockarray",
|
||||
[BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE] = "percpu_cgroup_storage",
|
||||
[BPF_MAP_TYPE_QUEUE] = "queue",
|
||||
[BPF_MAP_TYPE_STACK] = "stack",
|
||||
[BPF_MAP_TYPE_SK_STORAGE] = "sk_storage",
|
||||
[BPF_MAP_TYPE_STRUCT_OPS] = "struct_ops",
|
||||
[BPF_MAP_TYPE_RINGBUF] = "ringbuf",
|
||||
[BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage",
|
||||
[BPF_MAP_TYPE_TASK_STORAGE] = "task_storage",
|
||||
[BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter",
|
||||
};
|
||||
|
||||
const size_t map_type_name_size = ARRAY_SIZE(map_type_name);
|
||||
|
||||
static struct hashmap *map_table;
|
||||
|
||||
static bool map_is_per_cpu(__u32 type)
|
||||
|
@ -81,12 +45,18 @@ static bool map_is_map_of_progs(__u32 type)
|
|||
|
||||
static int map_type_from_str(const char *type)
|
||||
{
|
||||
const char *map_type_str;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(map_type_name); i++)
|
||||
for (i = 0; ; i++) {
|
||||
map_type_str = libbpf_bpf_map_type_str(i);
|
||||
if (!map_type_str)
|
||||
break;
|
||||
|
||||
/* Don't allow prefixing in case of possible future shadowing */
|
||||
if (map_type_name[i] && !strcmp(map_type_name[i], type))
|
||||
if (!strcmp(map_type_str, type))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -472,9 +442,12 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
|
|||
|
||||
static void show_map_header_json(struct bpf_map_info *info, json_writer_t *wtr)
|
||||
{
|
||||
const char *map_type_str;
|
||||
|
||||
jsonw_uint_field(wtr, "id", info->id);
|
||||
if (info->type < ARRAY_SIZE(map_type_name))
|
||||
jsonw_string_field(wtr, "type", map_type_name[info->type]);
|
||||
map_type_str = libbpf_bpf_map_type_str(info->type);
|
||||
if (map_type_str)
|
||||
jsonw_string_field(wtr, "type", map_type_str);
|
||||
else
|
||||
jsonw_uint_field(wtr, "type", info->type);
|
||||
|
||||
|
@ -561,9 +534,13 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
|
|||
|
||||
static void show_map_header_plain(struct bpf_map_info *info)
|
||||
{
|
||||
const char *map_type_str;
|
||||
|
||||
printf("%u: ", info->id);
|
||||
if (info->type < ARRAY_SIZE(map_type_name))
|
||||
printf("%s ", map_type_name[info->type]);
|
||||
|
||||
map_type_str = libbpf_bpf_map_type_str(info->type);
|
||||
if (map_type_str)
|
||||
printf("%s ", map_type_str);
|
||||
else
|
||||
printf("type %u ", info->type);
|
||||
|
||||
|
@ -879,9 +856,13 @@ map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
|
|||
}
|
||||
|
||||
if (info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY &&
|
||||
info->value_size != 8)
|
||||
info->value_size != 8) {
|
||||
const char *map_type_str;
|
||||
|
||||
map_type_str = libbpf_bpf_map_type_str(info->type);
|
||||
p_info("Warning: cannot read values from %s map with value_size != 8",
|
||||
map_type_name[info->type]);
|
||||
map_type_str);
|
||||
}
|
||||
while (true) {
|
||||
err = bpf_map_get_next_key(fd, prev_key, key);
|
||||
if (err) {
|
||||
|
|
|
@ -186,6 +186,27 @@ class FileExtractor(object):
|
|||
parser.search_block(start_marker)
|
||||
return parser.parse(pattern, end_marker)
|
||||
|
||||
def make_enum_map(self, names, enum_prefix):
|
||||
"""
|
||||
Search for and parse an enum containing BPF_* members, just as get_enum
|
||||
does. However, instead of just returning a set of the variant names,
|
||||
also generate a textual representation from them by (assuming and)
|
||||
removing a provided prefix and lowercasing the remainder. Then return a
|
||||
dict mapping from name to textual representation.
|
||||
|
||||
@enum_values: a set of enum values; e.g., as retrieved by get_enum
|
||||
@enum_prefix: the prefix to remove from each of the variants to infer
|
||||
textual representation
|
||||
"""
|
||||
mapping = {}
|
||||
for name in names:
|
||||
if not name.startswith(enum_prefix):
|
||||
raise Exception(f"enum variant {name} does not start with {enum_prefix}")
|
||||
text = name[len(enum_prefix):].lower()
|
||||
mapping[name] = text
|
||||
|
||||
return mapping
|
||||
|
||||
def __get_description_list(self, start_marker, pattern, end_marker):
|
||||
parser = InlineListParser(self.reader)
|
||||
parser.search_block(start_marker)
|
||||
|
@ -345,9 +366,6 @@ class MapFileExtractor(SourceFileExtractor):
|
|||
"""
|
||||
filename = os.path.join(BPFTOOL_DIR, 'map.c')
|
||||
|
||||
def get_map_types(self):
|
||||
return self.get_types_from_array('map_type_name')
|
||||
|
||||
def get_map_help(self):
|
||||
return self.get_help_list('TYPE')
|
||||
|
||||
|
@ -403,8 +421,9 @@ class BpfHeaderExtractor(FileExtractor):
|
|||
def get_prog_types(self):
|
||||
return self.get_enum('bpf_prog_type')
|
||||
|
||||
def get_map_types(self):
|
||||
return self.get_enum('bpf_map_type')
|
||||
def get_map_type_map(self):
|
||||
names = self.get_enum('bpf_map_type')
|
||||
return self.make_enum_map(names, 'BPF_MAP_TYPE_')
|
||||
|
||||
def get_attach_types(self):
|
||||
return self.get_enum('bpf_attach_type')
|
||||
|
@ -492,21 +511,12 @@ def main():
|
|||
""")
|
||||
args = argParser.parse_args()
|
||||
|
||||
# Map types (enum)
|
||||
|
||||
bpf_info = BpfHeaderExtractor()
|
||||
ref = bpf_info.get_map_types()
|
||||
|
||||
map_info = MapFileExtractor()
|
||||
source_map_items = map_info.get_map_types()
|
||||
map_types_enum = set(source_map_items.keys())
|
||||
|
||||
verify(ref, map_types_enum,
|
||||
f'Comparing BPF header (enum bpf_map_type) and {MapFileExtractor.filename} (map_type_name):')
|
||||
|
||||
# Map types (names)
|
||||
|
||||
source_map_types = set(source_map_items.values())
|
||||
map_info = MapFileExtractor()
|
||||
source_map_types = set(bpf_info.get_map_type_map().values())
|
||||
source_map_types.discard('unspec')
|
||||
|
||||
help_map_types = map_info.get_map_help()
|
||||
|
@ -522,13 +532,13 @@ def main():
|
|||
bashcomp_map_types = bashcomp_info.get_map_types()
|
||||
|
||||
verify(source_map_types, help_map_types,
|
||||
f'Comparing {MapFileExtractor.filename} (map_type_name) and {MapFileExtractor.filename} (do_help() TYPE):')
|
||||
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {MapFileExtractor.filename} (do_help() TYPE):')
|
||||
verify(source_map_types, man_map_types,
|
||||
f'Comparing {MapFileExtractor.filename} (map_type_name) and {ManMapExtractor.filename} (TYPE):')
|
||||
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {ManMapExtractor.filename} (TYPE):')
|
||||
verify(help_map_options, man_map_options,
|
||||
f'Comparing {MapFileExtractor.filename} (do_help() OPTIONS) and {ManMapExtractor.filename} (OPTIONS):')
|
||||
verify(source_map_types, bashcomp_map_types,
|
||||
f'Comparing {MapFileExtractor.filename} (map_type_name) and {BashcompExtractor.filename} (BPFTOOL_MAP_CREATE_TYPES):')
|
||||
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {BashcompExtractor.filename} (BPFTOOL_MAP_CREATE_TYPES):')
|
||||
|
||||
# Attach types (enum)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче