Commit d6699f8e authored by Quentin Monnet's avatar Quentin Monnet Committed by Andrii Nakryiko
Browse files

bpftool: Switch to libbpf's hashmap for PIDs/names references



In order to show PIDs and names for processes holding references to BPF
programs, maps, links, or BTF objects, bpftool creates hash maps to
store all relevant information. This commit is part of a set that
transitions from the kernel's hash map implementation to the one coming
with libbpf.

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 is the third and final step of the transition, in which we convert
the hash maps used for storing the information about the processes
holding references to BPF objects (programs, maps, links, BTF), and at
last we drop the inclusion of tools/include/linux/hashtable.h.

Note: Checkpatch complains about the use of __weak declarations, and the
missing empty lines after the bunch of empty function declarations when
compiling without the BPF skeletons (none of these were introduced in
this patch). We want to keep things as they are, and the reports should
be safe to ignore.

Signed-off-by: default avatarQuentin Monnet <quentin@isovalent.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20211023205154.6710-6-quentin@isovalent.com
parent 2828d0d7
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
#include <string.h>
#include <unistd.h>
#include <linux/btf.h>
#include <linux/hashtable.h>
#include <sys/types.h>
#include <sys/stat.h>

@@ -797,7 +796,7 @@ show_btf_plain(struct bpf_btf_info *info, int fd,
		       hash_field_as_u32(entry->value));
	}

	emit_obj_refs_plain(&refs_table, info->id, "\n\tpids ");
	emit_obj_refs_plain(refs_table, info->id, "\n\tpids ");

	printf("\n");
}
@@ -830,7 +829,7 @@ show_btf_json(struct bpf_btf_info *info, int fd,
	}
	jsonw_end_array(json_wtr);	/* map_ids */

	emit_obj_refs_json(&refs_table, info->id, json_wtr); /* pids */
	emit_obj_refs_json(refs_table, info->id, json_wtr); /* pids */

	jsonw_bool_field(json_wtr, "kernel", info->kernel_btf);

@@ -961,7 +960,7 @@ static int do_show(int argc, char **argv)
exit_free:
	hashmap__free(btf_prog_table);
	hashmap__free(btf_map_table);
	delete_obj_refs_table(&refs_table);
	delete_obj_refs_table(refs_table);

	return err;
}
+3 −3
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
		jsonw_end_array(json_wtr);
	}

	emit_obj_refs_json(&refs_table, info->id, json_wtr);
	emit_obj_refs_json(refs_table, info->id, json_wtr);

	jsonw_end_object(json_wtr);

@@ -253,7 +253,7 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
					    u32_as_hash_field(info->id))
			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 ");

	printf("\n");

@@ -352,7 +352,7 @@ static int do_show(int argc, char **argv)
	if (json_output)
		jsonw_end_array(json_wtr);

	delete_obj_refs_table(&refs_table);
	delete_obj_refs_table(refs_table);

	if (show_pinned)
		delete_pinned_obj_table(link_table);
+3 −2
Original line number Diff line number Diff line
@@ -10,8 +10,9 @@
#include <string.h>

#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <bpf/btf.h>
#include <bpf/hashmap.h>
#include <bpf/libbpf.h>

#include "main.h"

@@ -31,7 +32,7 @@ bool verifier_logs;
bool relaxed_maps;
bool use_loader;
struct btf *base_btf;
struct obj_refs_table refs_table;
struct hashmap *refs_table;

static void __noreturn clean_and_exit(int i)
{
+5 −12
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
#include <linux/bpf.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/hashtable.h>
#include <tools/libc_compat.h>

#include <bpf/hashmap.h>
@@ -92,7 +91,7 @@ extern bool verifier_logs;
extern bool relaxed_maps;
extern bool use_loader;
extern struct btf *base_btf;
extern struct obj_refs_table refs_table;
extern struct hashmap *refs_table;

void __printf(1, 2) p_err(const char *fmt, ...);
void __printf(1, 2) p_info(const char *fmt, ...);
@@ -106,18 +105,12 @@ void set_max_rlimit(void);

int mount_tracefs(const char *target);

struct obj_refs_table {
	DECLARE_HASHTABLE(table, 16);
};

struct obj_ref {
	int pid;
	char comm[16];
};

struct obj_refs {
	struct hlist_node node;
	__u32 id;
	int ref_cnt;
	struct obj_ref *refs;
};
@@ -128,12 +121,12 @@ struct bpf_line_info;
int build_pinned_obj_table(struct hashmap *table,
			   enum bpf_obj_type type);
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 hashmap **table,
				enum bpf_obj_type type);
__weak void delete_obj_refs_table(struct obj_refs_table *table);
__weak void emit_obj_refs_json(struct obj_refs_table *table, __u32 id,
__weak void delete_obj_refs_table(struct hashmap *table);
__weak void emit_obj_refs_json(struct hashmap *table, __u32 id,
			       json_writer_t *json_wtr);
__weak void emit_obj_refs_plain(struct obj_refs_table *table, __u32 id,
__weak void emit_obj_refs_plain(struct hashmap *table, __u32 id,
				const char *prefix);
void print_dev_plain(__u32 ifindex, __u64 ns_dev, __u64 ns_inode);
void print_dev_json(__u32 ifindex, __u64 ns_dev, __u64 ns_inode);
+3 −3
Original line number Diff line number Diff line
@@ -549,7 +549,7 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
		jsonw_end_array(json_wtr);
	}

	emit_obj_refs_json(&refs_table, info->id, json_wtr);
	emit_obj_refs_json(refs_table, info->id, json_wtr);

	jsonw_end_object(json_wtr);

@@ -637,7 +637,7 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info)
	if (frozen)
		printf("%sfrozen", info->btf_id ? "  " : "");

	emit_obj_refs_plain(&refs_table, info->id, "\n\tpids ");
	emit_obj_refs_plain(refs_table, info->id, "\n\tpids ");

	printf("\n");
	return 0;
@@ -748,7 +748,7 @@ static int do_show(int argc, char **argv)
	if (json_output)
		jsonw_end_array(json_wtr);

	delete_obj_refs_table(&refs_table);
	delete_obj_refs_table(refs_table);

	if (show_pinned)
		delete_pinned_obj_table(map_table);
Loading