mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	bpftool: Switch to libbpf's hashmap for pinned paths of BPF objects
In order to show pinned paths for BPF programs, maps, or links when
listing them with the "-f" option, bpftool creates hash maps to store
all relevant paths under the bpffs. So far, it would rely on the
kernel implementation (from tools/include/linux/hashtable.h).
We can make bpftool rely on libbpf's implementation instead. The
motivation is to make bpftool less dependent of kernel headers, to ease
the path to a potential out-of-tree mirror, like libbpf has.
This commit is the first step of the conversion: the hash maps for
pinned paths for programs, maps, and links are converted to libbpf's
hashmap.{c,h}. Other hash maps used for the PIDs of process holding
references to BPF objects are left unchanged for now. On the build side,
this requires adding a dependency to a second header internal to libbpf,
and making it a dependency for the bootstrap bpftool version as well.
The rest of the changes are a rather straightforward conversion.
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20211023205154.6710-4-quentin@isovalent.com
			
			
This commit is contained in:
		
							parent
							
								
									46241271d1
								
							
						
					
					
						commit
						8f184732b6
					
				
					 6 changed files with 111 additions and 84 deletions
				
			
		|  | @ -31,9 +31,9 @@ LIBBPF = $(LIBBPF_OUTPUT)libbpf.a | ||||||
| LIBBPF_BOOTSTRAP_OUTPUT = $(BOOTSTRAP_OUTPUT)libbpf/ | LIBBPF_BOOTSTRAP_OUTPUT = $(BOOTSTRAP_OUTPUT)libbpf/ | ||||||
| LIBBPF_BOOTSTRAP = $(LIBBPF_BOOTSTRAP_OUTPUT)libbpf.a | LIBBPF_BOOTSTRAP = $(LIBBPF_BOOTSTRAP_OUTPUT)libbpf.a | ||||||
| 
 | 
 | ||||||
| # We need to copy nlattr.h which is not otherwise exported by libbpf, but still
 | # We need to copy hashmap.h and nlattr.h which is not otherwise exported by
 | ||||||
| # required by bpftool.
 | # libbpf, but still required by bpftool.
 | ||||||
| LIBBPF_INTERNAL_HDRS := $(addprefix $(LIBBPF_HDRS_DIR)/,nlattr.h) | LIBBPF_INTERNAL_HDRS := $(addprefix $(LIBBPF_HDRS_DIR)/,hashmap.h nlattr.h) | ||||||
| 
 | 
 | ||||||
| ifeq ($(BPFTOOL_VERSION),) | ifeq ($(BPFTOOL_VERSION),) | ||||||
| BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion) | BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion) | ||||||
|  | @ -209,7 +209,7 @@ $(BPFTOOL_BOOTSTRAP): $(BOOTSTRAP_OBJS) $(LIBBPF_BOOTSTRAP) | ||||||
| $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) | $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) | ||||||
| 	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) | 	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) | ||||||
| 
 | 
 | ||||||
| $(BOOTSTRAP_OUTPUT)%.o: %.c | $(BOOTSTRAP_OUTPUT) | $(BOOTSTRAP_OUTPUT)%.o: %.c $(LIBBPF_INTERNAL_HDRS) | $(BOOTSTRAP_OUTPUT) | ||||||
| 	$(QUIET_CC)$(HOSTCC) $(CFLAGS) -c -MMD -o $@ $< | 	$(QUIET_CC)$(HOSTCC) $(CFLAGS) -c -MMD -o $@ $< | ||||||
| 
 | 
 | ||||||
| $(OUTPUT)%.o: %.c | $(OUTPUT)%.o: %.c | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ | ||||||
| #include <sys/vfs.h> | #include <sys/vfs.h> | ||||||
| 
 | 
 | ||||||
| #include <bpf/bpf.h> | #include <bpf/bpf.h> | ||||||
|  | #include <bpf/hashmap.h> | ||||||
| #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */ | #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */ | ||||||
| 
 | 
 | ||||||
| #include "main.h" | #include "main.h" | ||||||
|  | @ -393,7 +394,7 @@ void print_hex_data_json(uint8_t *data, size_t len) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* extra params for nftw cb */ | /* extra params for nftw cb */ | ||||||
| static struct pinned_obj_table *build_fn_table; | static struct hashmap *build_fn_table; | ||||||
| static enum bpf_obj_type build_fn_type; | static enum bpf_obj_type build_fn_type; | ||||||
| 
 | 
 | ||||||
| static int do_build_table_cb(const char *fpath, const struct stat *sb, | static int do_build_table_cb(const char *fpath, const struct stat *sb, | ||||||
|  | @ -401,9 +402,9 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb, | ||||||
| { | { | ||||||
| 	struct bpf_prog_info pinned_info; | 	struct bpf_prog_info pinned_info; | ||||||
| 	__u32 len = sizeof(pinned_info); | 	__u32 len = sizeof(pinned_info); | ||||||
| 	struct pinned_obj *obj_node; |  | ||||||
| 	enum bpf_obj_type objtype; | 	enum bpf_obj_type objtype; | ||||||
| 	int fd, err = 0; | 	int fd, err = 0; | ||||||
|  | 	char *path; | ||||||
| 
 | 
 | ||||||
| 	if (typeflag != FTW_F) | 	if (typeflag != FTW_F) | ||||||
| 		goto out_ret; | 		goto out_ret; | ||||||
|  | @ -420,28 +421,26 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb, | ||||||
| 	if (bpf_obj_get_info_by_fd(fd, &pinned_info, &len)) | 	if (bpf_obj_get_info_by_fd(fd, &pinned_info, &len)) | ||||||
| 		goto out_close; | 		goto out_close; | ||||||
| 
 | 
 | ||||||
| 	obj_node = calloc(1, sizeof(*obj_node)); | 	path = strdup(fpath); | ||||||
| 	if (!obj_node) { | 	if (!path) { | ||||||
| 		err = -1; | 		err = -1; | ||||||
| 		goto out_close; | 		goto out_close; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	obj_node->id = pinned_info.id; | 	err = hashmap__append(build_fn_table, u32_as_hash_field(pinned_info.id), path); | ||||||
| 	obj_node->path = strdup(fpath); | 	if (err) { | ||||||
| 	if (!obj_node->path) { | 		p_err("failed to append entry to hashmap for ID %u, path '%s': %s", | ||||||
| 		err = -1; | 		      pinned_info.id, path, strerror(errno)); | ||||||
| 		free(obj_node); |  | ||||||
| 		goto out_close; | 		goto out_close; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	hash_add(build_fn_table->table, &obj_node->hash, obj_node->id); |  | ||||||
| out_close: | out_close: | ||||||
| 	close(fd); | 	close(fd); | ||||||
| out_ret: | out_ret: | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int build_pinned_obj_table(struct pinned_obj_table *tab, | int build_pinned_obj_table(struct hashmap *tab, | ||||||
| 			   enum bpf_obj_type type) | 			   enum bpf_obj_type type) | ||||||
| { | { | ||||||
| 	struct mntent *mntent = NULL; | 	struct mntent *mntent = NULL; | ||||||
|  | @ -470,17 +469,18 @@ int build_pinned_obj_table(struct pinned_obj_table *tab, | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void delete_pinned_obj_table(struct pinned_obj_table *tab) | void delete_pinned_obj_table(struct hashmap *map) | ||||||
| { | { | ||||||
| 	struct pinned_obj *obj; | 	struct hashmap_entry *entry; | ||||||
| 	struct hlist_node *tmp; | 	size_t bkt; | ||||||
| 	unsigned int bkt; |  | ||||||
| 
 | 
 | ||||||
| 	hash_for_each_safe(tab->table, bkt, tmp, obj, hash) { | 	if (!map) | ||||||
| 		hash_del(&obj->hash); | 		return; | ||||||
| 		free(obj->path); | 
 | ||||||
| 		free(obj); | 	hashmap__for_each_entry(map, entry, bkt) | ||||||
| 	} | 		free(entry->value); | ||||||
|  | 
 | ||||||
|  | 	hashmap__free(map); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned int get_page_size(void) | unsigned int get_page_size(void) | ||||||
|  | @ -962,3 +962,13 @@ int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len) | ||||||
| 
 | 
 | ||||||
| 	return fd; | 	return fd; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | size_t hash_fn_for_key_as_id(const void *key, void *ctx) | ||||||
|  | { | ||||||
|  | 	return (size_t)key; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool equal_fn_for_key_as_id(const void *k1, const void *k2, void *ctx) | ||||||
|  | { | ||||||
|  | 	return k1 == k2; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| 
 | 
 | ||||||
| #include <bpf/bpf.h> | #include <bpf/bpf.h> | ||||||
|  | #include <bpf/hashmap.h> | ||||||
| 
 | 
 | ||||||
| #include "json_writer.h" | #include "json_writer.h" | ||||||
| #include "main.h" | #include "main.h" | ||||||
|  | @ -20,7 +21,7 @@ static const char * const link_type_name[] = { | ||||||
| 	[BPF_LINK_TYPE_NETNS]			= "netns", | 	[BPF_LINK_TYPE_NETNS]			= "netns", | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct pinned_obj_table link_table; | static struct hashmap *link_table; | ||||||
| 
 | 
 | ||||||
| static int link_parse_fd(int *argc, char ***argv) | static int link_parse_fd(int *argc, char ***argv) | ||||||
| { | { | ||||||
|  | @ -158,15 +159,14 @@ static int show_link_close_json(int fd, struct bpf_link_info *info) | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(link_table.table)) { | 	if (!hashmap__empty(link_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		jsonw_name(json_wtr, "pinned"); | 		jsonw_name(json_wtr, "pinned"); | ||||||
| 		jsonw_start_array(json_wtr); | 		jsonw_start_array(json_wtr); | ||||||
| 		hash_for_each_possible(link_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(link_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				jsonw_string(json_wtr, obj->path); | 			jsonw_string(json_wtr, entry->value); | ||||||
| 		} |  | ||||||
| 		jsonw_end_array(json_wtr); | 		jsonw_end_array(json_wtr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -246,13 +246,12 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info) | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(link_table.table)) { | 	if (!hashmap__empty(link_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		hash_for_each_possible(link_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(link_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				printf("\n\tpinned %s", obj->path); | 			printf("\n\tpinned %s", (char *)entry->value); | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	emit_obj_refs_plain(&refs_table, info->id, "\n\tpids "); | 	emit_obj_refs_plain(&refs_table, info->id, "\n\tpids "); | ||||||
| 
 | 
 | ||||||
|  | @ -305,8 +304,13 @@ static int do_show(int argc, char **argv) | ||||||
| 	int err, fd; | 	int err, fd; | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) { | 	if (show_pinned) { | ||||||
| 		hash_init(link_table.table); | 		link_table = hashmap__new(hash_fn_for_key_as_id, | ||||||
| 		build_pinned_obj_table(&link_table, BPF_OBJ_LINK); | 					  equal_fn_for_key_as_id, NULL); | ||||||
|  | 		if (!link_table) { | ||||||
|  | 			p_err("failed to create hashmap for pinned paths"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		build_pinned_obj_table(link_table, BPF_OBJ_LINK); | ||||||
| 	} | 	} | ||||||
| 	build_obj_refs_table(&refs_table, BPF_OBJ_LINK); | 	build_obj_refs_table(&refs_table, BPF_OBJ_LINK); | ||||||
| 
 | 
 | ||||||
|  | @ -351,7 +355,7 @@ static int do_show(int argc, char **argv) | ||||||
| 	delete_obj_refs_table(&refs_table); | 	delete_obj_refs_table(&refs_table); | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) | 	if (show_pinned) | ||||||
| 		delete_pinned_obj_table(&link_table); | 		delete_pinned_obj_table(link_table); | ||||||
| 
 | 
 | ||||||
| 	return errno == ENOENT ? 0 : -1; | 	return errno == ENOENT ? 0 : -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| #include <linux/hashtable.h> | #include <linux/hashtable.h> | ||||||
| #include <tools/libc_compat.h> | #include <tools/libc_compat.h> | ||||||
| 
 | 
 | ||||||
|  | #include <bpf/hashmap.h> | ||||||
| #include <bpf/libbpf.h> | #include <bpf/libbpf.h> | ||||||
| 
 | 
 | ||||||
| #include "json_writer.h" | #include "json_writer.h" | ||||||
|  | @ -105,16 +106,6 @@ void set_max_rlimit(void); | ||||||
| 
 | 
 | ||||||
| int mount_tracefs(const char *target); | int mount_tracefs(const char *target); | ||||||
| 
 | 
 | ||||||
| struct pinned_obj_table { |  | ||||||
| 	DECLARE_HASHTABLE(table, 16); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct pinned_obj { |  | ||||||
| 	__u32 id; |  | ||||||
| 	char *path; |  | ||||||
| 	struct hlist_node hash; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct obj_refs_table { | struct obj_refs_table { | ||||||
| 	DECLARE_HASHTABLE(table, 16); | 	DECLARE_HASHTABLE(table, 16); | ||||||
| }; | }; | ||||||
|  | @ -134,9 +125,9 @@ struct obj_refs { | ||||||
| struct btf; | struct btf; | ||||||
| struct bpf_line_info; | struct bpf_line_info; | ||||||
| 
 | 
 | ||||||
| int build_pinned_obj_table(struct pinned_obj_table *table, | int build_pinned_obj_table(struct hashmap *table, | ||||||
| 			   enum bpf_obj_type type); | 			   enum bpf_obj_type type); | ||||||
| void delete_pinned_obj_table(struct pinned_obj_table *tab); | void delete_pinned_obj_table(struct hashmap *table); | ||||||
| __weak int build_obj_refs_table(struct obj_refs_table *table, | __weak int build_obj_refs_table(struct obj_refs_table *table, | ||||||
| 				enum bpf_obj_type type); | 				enum bpf_obj_type type); | ||||||
| __weak void delete_obj_refs_table(struct obj_refs_table *table); | __weak void delete_obj_refs_table(struct obj_refs_table *table); | ||||||
|  | @ -256,4 +247,18 @@ int do_filter_dump(struct tcmsg *ifinfo, struct nlattr **tb, const char *kind, | ||||||
| 
 | 
 | ||||||
| int print_all_levels(__maybe_unused enum libbpf_print_level level, | int print_all_levels(__maybe_unused enum libbpf_print_level level, | ||||||
| 		     const char *format, va_list args); | 		     const char *format, va_list args); | ||||||
|  | 
 | ||||||
|  | size_t hash_fn_for_key_as_id(const void *key, void *ctx); | ||||||
|  | bool equal_fn_for_key_as_id(const void *k1, const void *k2, void *ctx); | ||||||
|  | 
 | ||||||
|  | static inline void *u32_as_hash_field(__u32 x) | ||||||
|  | { | ||||||
|  | 	return (void *)(uintptr_t)x; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline bool hashmap__empty(struct hashmap *map) | ||||||
|  | { | ||||||
|  | 	return map ? hashmap__size(map) == 0 : true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <bpf/bpf.h> | #include <bpf/bpf.h> | ||||||
| #include <bpf/btf.h> | #include <bpf/btf.h> | ||||||
|  | #include <bpf/hashmap.h> | ||||||
| 
 | 
 | ||||||
| #include "json_writer.h" | #include "json_writer.h" | ||||||
| #include "main.h" | #include "main.h" | ||||||
|  | @ -56,7 +57,7 @@ const char * const map_type_name[] = { | ||||||
| 
 | 
 | ||||||
| const size_t map_type_name_size = ARRAY_SIZE(map_type_name); | const size_t map_type_name_size = ARRAY_SIZE(map_type_name); | ||||||
| 
 | 
 | ||||||
| static struct pinned_obj_table map_table; | static struct hashmap *map_table; | ||||||
| 
 | 
 | ||||||
| static bool map_is_per_cpu(__u32 type) | static bool map_is_per_cpu(__u32 type) | ||||||
| { | { | ||||||
|  | @ -537,15 +538,14 @@ static int show_map_close_json(int fd, struct bpf_map_info *info) | ||||||
| 	if (info->btf_id) | 	if (info->btf_id) | ||||||
| 		jsonw_int_field(json_wtr, "btf_id", info->btf_id); | 		jsonw_int_field(json_wtr, "btf_id", info->btf_id); | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(map_table.table)) { | 	if (!hashmap__empty(map_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		jsonw_name(json_wtr, "pinned"); | 		jsonw_name(json_wtr, "pinned"); | ||||||
| 		jsonw_start_array(json_wtr); | 		jsonw_start_array(json_wtr); | ||||||
| 		hash_for_each_possible(map_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(map_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				jsonw_string(json_wtr, obj->path); | 			jsonw_string(json_wtr, entry->value); | ||||||
| 		} |  | ||||||
| 		jsonw_end_array(json_wtr); | 		jsonw_end_array(json_wtr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -612,13 +612,12 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info) | ||||||
| 	} | 	} | ||||||
| 	close(fd); | 	close(fd); | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(map_table.table)) { | 	if (!hashmap__empty(map_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		hash_for_each_possible(map_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(map_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				printf("\n\tpinned %s", obj->path); | 			printf("\n\tpinned %s", (char *)entry->value); | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	printf("\n"); | 	printf("\n"); | ||||||
| 
 | 
 | ||||||
|  | @ -697,8 +696,13 @@ static int do_show(int argc, char **argv) | ||||||
| 	int fd; | 	int fd; | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) { | 	if (show_pinned) { | ||||||
| 		hash_init(map_table.table); | 		map_table = hashmap__new(hash_fn_for_key_as_id, | ||||||
| 		build_pinned_obj_table(&map_table, BPF_OBJ_MAP); | 					 equal_fn_for_key_as_id, NULL); | ||||||
|  | 		if (!map_table) { | ||||||
|  | 			p_err("failed to create hashmap for pinned paths"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		build_pinned_obj_table(map_table, BPF_OBJ_MAP); | ||||||
| 	} | 	} | ||||||
| 	build_obj_refs_table(&refs_table, BPF_OBJ_MAP); | 	build_obj_refs_table(&refs_table, BPF_OBJ_MAP); | ||||||
| 
 | 
 | ||||||
|  | @ -747,7 +751,7 @@ static int do_show(int argc, char **argv) | ||||||
| 	delete_obj_refs_table(&refs_table); | 	delete_obj_refs_table(&refs_table); | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) | 	if (show_pinned) | ||||||
| 		delete_pinned_obj_table(&map_table); | 		delete_pinned_obj_table(map_table); | ||||||
| 
 | 
 | ||||||
| 	return errno == ENOENT ? 0 : -1; | 	return errno == ENOENT ? 0 : -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -24,6 +24,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <bpf/bpf.h> | #include <bpf/bpf.h> | ||||||
| #include <bpf/btf.h> | #include <bpf/btf.h> | ||||||
|  | #include <bpf/hashmap.h> | ||||||
| #include <bpf/libbpf.h> | #include <bpf/libbpf.h> | ||||||
| #include <bpf/skel_internal.h> | #include <bpf/skel_internal.h> | ||||||
| 
 | 
 | ||||||
|  | @ -84,7 +85,7 @@ static const char * const attach_type_strings[] = { | ||||||
| 	[__MAX_BPF_ATTACH_TYPE] = NULL, | 	[__MAX_BPF_ATTACH_TYPE] = NULL, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct pinned_obj_table prog_table; | static struct hashmap *prog_table; | ||||||
| 
 | 
 | ||||||
| static enum bpf_attach_type parse_attach_type(const char *str) | static enum bpf_attach_type parse_attach_type(const char *str) | ||||||
| { | { | ||||||
|  | @ -418,15 +419,14 @@ static void print_prog_json(struct bpf_prog_info *info, int fd) | ||||||
| 	if (info->btf_id) | 	if (info->btf_id) | ||||||
| 		jsonw_int_field(json_wtr, "btf_id", info->btf_id); | 		jsonw_int_field(json_wtr, "btf_id", info->btf_id); | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(prog_table.table)) { | 	if (!hashmap__empty(prog_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		jsonw_name(json_wtr, "pinned"); | 		jsonw_name(json_wtr, "pinned"); | ||||||
| 		jsonw_start_array(json_wtr); | 		jsonw_start_array(json_wtr); | ||||||
| 		hash_for_each_possible(prog_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(prog_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				jsonw_string(json_wtr, obj->path); | 			jsonw_string(json_wtr, entry->value); | ||||||
| 		} |  | ||||||
| 		jsonw_end_array(json_wtr); | 		jsonw_end_array(json_wtr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -490,13 +490,12 @@ static void print_prog_plain(struct bpf_prog_info *info, int fd) | ||||||
| 	if (info->nr_map_ids) | 	if (info->nr_map_ids) | ||||||
| 		show_prog_maps(fd, info->nr_map_ids); | 		show_prog_maps(fd, info->nr_map_ids); | ||||||
| 
 | 
 | ||||||
| 	if (!hash_empty(prog_table.table)) { | 	if (!hashmap__empty(prog_table)) { | ||||||
| 		struct pinned_obj *obj; | 		struct hashmap_entry *entry; | ||||||
| 
 | 
 | ||||||
| 		hash_for_each_possible(prog_table.table, obj, hash, info->id) { | 		hashmap__for_each_key_entry(prog_table, entry, | ||||||
| 			if (obj->id == info->id) | 					    u32_as_hash_field(info->id)) | ||||||
| 				printf("\n\tpinned %s", obj->path); | 			printf("\n\tpinned %s", (char *)entry->value); | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (info->btf_id) | 	if (info->btf_id) | ||||||
|  | @ -570,8 +569,13 @@ static int do_show(int argc, char **argv) | ||||||
| 	int fd; | 	int fd; | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) { | 	if (show_pinned) { | ||||||
| 		hash_init(prog_table.table); | 		prog_table = hashmap__new(hash_fn_for_key_as_id, | ||||||
| 		build_pinned_obj_table(&prog_table, BPF_OBJ_PROG); | 					  equal_fn_for_key_as_id, NULL); | ||||||
|  | 		if (!prog_table) { | ||||||
|  | 			p_err("failed to create hashmap for pinned paths"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		build_pinned_obj_table(prog_table, BPF_OBJ_PROG); | ||||||
| 	} | 	} | ||||||
| 	build_obj_refs_table(&refs_table, BPF_OBJ_PROG); | 	build_obj_refs_table(&refs_table, BPF_OBJ_PROG); | ||||||
| 
 | 
 | ||||||
|  | @ -618,7 +622,7 @@ static int do_show(int argc, char **argv) | ||||||
| 	delete_obj_refs_table(&refs_table); | 	delete_obj_refs_table(&refs_table); | ||||||
| 
 | 
 | ||||||
| 	if (show_pinned) | 	if (show_pinned) | ||||||
| 		delete_pinned_obj_table(&prog_table); | 		delete_pinned_obj_table(prog_table); | ||||||
| 
 | 
 | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Quentin Monnet
						Quentin Monnet