Merge branch 'libbpf: rename btf__get_from_id() and btf__load() APIs, support split BTF'
Quentin Monnet says: ==================== As part of the effort to move towards a v1.0 for libbpf [0], this set improves some confusing function names related to BTF loading from and to the kernel: - btf__load() becomes btf__load_into_kernel(). - btf__get_from_id becomes btf__load_from_kernel_by_id(). - A new version btf__load_from_kernel_by_id_split() extends the former to add support for split BTF. The last patch is a trivial change to bpftool to add support for dumping split BTF objects by referencing them by their id (and not only by their BTF path). [0] https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0#btfh-apis v3: - Use libbpf_err_ptr() in btf__load_from_kernel_by_id(), ERR_PTR() in bpftool's get_map_kv_btf(). - Move the definition of btf__load_from_kernel_by_id() closer to the btf__parse() group in btf.h (move the legacy function with it). - Fix a bug on the return value in libbpf_find_prog_btf_id(), as a new patch. - Move the btf__free() fixes to their own patch. - Add "Fixes:" tags to relevant patches. v2: - Remove deprecation marking of legacy functions (patch 4/6 from v1). - Make btf__load_from_kernel_by_id{,_split}() return the btf struct, adjust surrounding code and call btf__free() when missing. - Add new functions to v0.5.0 API (and not v0.6.0). ==================== Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
This commit is contained in:
Коммит
f309b4ba98
|
@ -580,16 +580,12 @@ static int do_dump(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (!btf) {
|
||||
err = btf__get_from_id(btf_id, &btf);
|
||||
btf = btf__load_from_kernel_by_id_split(btf_id, base_btf);
|
||||
err = libbpf_get_error(btf);
|
||||
if (err) {
|
||||
p_err("get btf by id (%u): %s", btf_id, strerror(err));
|
||||
goto done;
|
||||
}
|
||||
if (!btf) {
|
||||
err = -ENOENT;
|
||||
p_err("can't find btf with ID (%u)", btf_id);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (dump_c) {
|
||||
|
|
|
@ -64,8 +64,10 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
|
|||
}
|
||||
info = &prog_info->info;
|
||||
|
||||
if (!info->btf_id || !info->nr_func_info ||
|
||||
btf__get_from_id(info->btf_id, &prog_btf))
|
||||
if (!info->btf_id || !info->nr_func_info)
|
||||
goto print;
|
||||
prog_btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
if (libbpf_get_error(prog_btf))
|
||||
goto print;
|
||||
finfo = u64_to_ptr(info->func_info);
|
||||
func_type = btf__type_by_id(prog_btf, finfo->type_id);
|
||||
|
|
|
@ -807,10 +807,11 @@ static struct btf *get_map_kv_btf(const struct bpf_map_info *info)
|
|||
} else if (info->btf_value_type_id) {
|
||||
int err;
|
||||
|
||||
err = btf__get_from_id(info->btf_id, &btf);
|
||||
if (err || !btf) {
|
||||
btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
err = libbpf_get_error(btf);
|
||||
if (err) {
|
||||
p_err("failed to get btf");
|
||||
btf = err ? ERR_PTR(err) : ERR_PTR(-ESRCH);
|
||||
btf = ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1039,11 +1040,10 @@ static void print_key_value(struct bpf_map_info *info, void *key,
|
|||
void *value)
|
||||
{
|
||||
json_writer_t *btf_wtr;
|
||||
struct btf *btf = NULL;
|
||||
int err;
|
||||
struct btf *btf;
|
||||
|
||||
err = btf__get_from_id(info->btf_id, &btf);
|
||||
if (err) {
|
||||
btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
p_err("failed to get btf");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -249,10 +249,10 @@ static void show_prog_metadata(int fd, __u32 num_maps)
|
|||
struct bpf_map_info map_info;
|
||||
struct btf_var_secinfo *vsi;
|
||||
bool printed_header = false;
|
||||
struct btf *btf = NULL;
|
||||
unsigned int i, vlen;
|
||||
void *value = NULL;
|
||||
const char *name;
|
||||
struct btf *btf;
|
||||
int err;
|
||||
|
||||
if (!num_maps)
|
||||
|
@ -263,8 +263,8 @@ static void show_prog_metadata(int fd, __u32 num_maps)
|
|||
if (!value)
|
||||
return;
|
||||
|
||||
err = btf__get_from_id(map_info.btf_id, &btf);
|
||||
if (err || !btf)
|
||||
btf = btf__load_from_kernel_by_id(map_info.btf_id);
|
||||
if (libbpf_get_error(btf))
|
||||
goto out_free;
|
||||
|
||||
t_datasec = btf__type_by_id(btf, map_info.btf_value_type_id);
|
||||
|
@ -646,9 +646,12 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
|
|||
member_len = info->xlated_prog_len;
|
||||
}
|
||||
|
||||
if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
|
||||
p_err("failed to get btf");
|
||||
return -1;
|
||||
if (info->btf_id) {
|
||||
btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
p_err("failed to get btf");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
func_info = u64_to_ptr(info->func_info);
|
||||
|
@ -781,6 +784,8 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
|
|||
kernel_syms_destroy(&dd);
|
||||
}
|
||||
|
||||
btf__free(btf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2002,8 +2007,8 @@ static char *profile_target_name(int tgt_fd)
|
|||
struct bpf_prog_info_linear *info_linear;
|
||||
struct bpf_func_info *func_info;
|
||||
const struct btf_type *t;
|
||||
struct btf *btf = NULL;
|
||||
char *name = NULL;
|
||||
struct btf *btf;
|
||||
|
||||
info_linear = bpf_program__get_prog_info_linear(
|
||||
tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO);
|
||||
|
@ -2012,12 +2017,17 @@ static char *profile_target_name(int tgt_fd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (info_linear->info.btf_id == 0 ||
|
||||
btf__get_from_id(info_linear->info.btf_id, &btf)) {
|
||||
if (info_linear->info.btf_id == 0) {
|
||||
p_err("prog FD %d doesn't have valid btf", tgt_fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
btf = btf__load_from_kernel_by_id(info_linear->info.btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
p_err("failed to load btf for prog FD %d", tgt_fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
func_info = u64_to_ptr(info_linear->info.func_info);
|
||||
t = btf__type_by_id(btf, func_info[0].type_id);
|
||||
if (!t) {
|
||||
|
@ -2027,6 +2037,7 @@ static char *profile_target_name(int tgt_fd)
|
|||
}
|
||||
name = strdup(btf__name_by_offset(btf, t->name_off));
|
||||
out:
|
||||
btf__free(btf);
|
||||
free(info_linear);
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -1180,7 +1180,7 @@ int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
|
|||
|
||||
static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
|
||||
|
||||
int btf__load(struct btf *btf)
|
||||
int btf__load_into_kernel(struct btf *btf)
|
||||
{
|
||||
__u32 log_buf_size = 0, raw_size;
|
||||
char *log_buf = NULL;
|
||||
|
@ -1228,6 +1228,7 @@ done:
|
|||
free(log_buf);
|
||||
return libbpf_err(err);
|
||||
}
|
||||
int btf__load(struct btf *) __attribute__((alias("btf__load_into_kernel")));
|
||||
|
||||
int btf__fd(const struct btf *btf)
|
||||
{
|
||||
|
@ -1382,21 +1383,35 @@ exit_free:
|
|||
return btf;
|
||||
}
|
||||
|
||||
struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf)
|
||||
{
|
||||
struct btf *btf;
|
||||
int btf_fd;
|
||||
|
||||
btf_fd = bpf_btf_get_fd_by_id(id);
|
||||
if (btf_fd < 0)
|
||||
return libbpf_err_ptr(-errno);
|
||||
|
||||
btf = btf_get_from_fd(btf_fd, base_btf);
|
||||
close(btf_fd);
|
||||
|
||||
return libbpf_ptr(btf);
|
||||
}
|
||||
|
||||
struct btf *btf__load_from_kernel_by_id(__u32 id)
|
||||
{
|
||||
return btf__load_from_kernel_by_id_split(id, NULL);
|
||||
}
|
||||
|
||||
int btf__get_from_id(__u32 id, struct btf **btf)
|
||||
{
|
||||
struct btf *res;
|
||||
int err, btf_fd;
|
||||
int err;
|
||||
|
||||
*btf = NULL;
|
||||
btf_fd = bpf_btf_get_fd_by_id(id);
|
||||
if (btf_fd < 0)
|
||||
return libbpf_err(-errno);
|
||||
|
||||
res = btf_get_from_fd(btf_fd, NULL);
|
||||
res = btf__load_from_kernel_by_id(id);
|
||||
err = libbpf_get_error(res);
|
||||
|
||||
close(btf_fd);
|
||||
|
||||
if (err)
|
||||
return libbpf_err(err);
|
||||
|
||||
|
|
|
@ -44,8 +44,13 @@ LIBBPF_API struct btf *btf__parse_elf_split(const char *path, struct btf *base_b
|
|||
LIBBPF_API struct btf *btf__parse_raw(const char *path);
|
||||
LIBBPF_API struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf);
|
||||
|
||||
LIBBPF_API struct btf *btf__load_from_kernel_by_id(__u32 id);
|
||||
LIBBPF_API struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf);
|
||||
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
|
||||
|
||||
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
|
||||
LIBBPF_API int btf__load(struct btf *btf);
|
||||
LIBBPF_API int btf__load_into_kernel(struct btf *btf);
|
||||
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
||||
const char *type_name);
|
||||
LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
|
||||
|
@ -66,7 +71,6 @@ LIBBPF_API void btf__set_fd(struct btf *btf, int fd);
|
|||
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
||||
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||
LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset);
|
||||
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
|
||||
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
|
||||
__u32 expected_key_size,
|
||||
__u32 expected_value_size,
|
||||
|
|
|
@ -2769,7 +2769,7 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
|
|||
*/
|
||||
btf__set_fd(kern_btf, 0);
|
||||
} else {
|
||||
err = btf__load(kern_btf);
|
||||
err = btf__load_into_kernel(kern_btf);
|
||||
}
|
||||
if (sanitize) {
|
||||
if (!err) {
|
||||
|
@ -8316,8 +8316,8 @@ static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
|
|||
{
|
||||
struct bpf_prog_info_linear *info_linear;
|
||||
struct bpf_prog_info *info;
|
||||
struct btf *btf = NULL;
|
||||
int err = -EINVAL;
|
||||
struct btf *btf;
|
||||
int err;
|
||||
|
||||
info_linear = bpf_program__get_prog_info_linear(attach_prog_fd, 0);
|
||||
err = libbpf_get_error(info_linear);
|
||||
|
@ -8326,12 +8326,15 @@ static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd)
|
|||
attach_prog_fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = -EINVAL;
|
||||
info = &info_linear->info;
|
||||
if (!info->btf_id) {
|
||||
pr_warn("The target program doesn't have BTF\n");
|
||||
goto out;
|
||||
}
|
||||
if (btf__get_from_id(info->btf_id, &btf)) {
|
||||
btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
pr_warn("Failed to get BTF of the program\n");
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -375,6 +375,9 @@ LIBBPF_0.5.0 {
|
|||
bpf_map_lookup_and_delete_elem_flags;
|
||||
bpf_program__attach_kprobe_opts;
|
||||
bpf_object__gen_loader;
|
||||
btf__load_from_kernel_by_id;
|
||||
btf__load_from_kernel_by_id_split;
|
||||
btf__load_into_kernel;
|
||||
btf_dump__dump_type_data;
|
||||
libbpf_set_strict_mode;
|
||||
} LIBBPF_0.4.0;
|
||||
|
|
|
@ -223,10 +223,10 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,
|
|||
free(info_linear);
|
||||
return -1;
|
||||
}
|
||||
if (btf__get_from_id(info->btf_id, &btf)) {
|
||||
btf = btf__load_from_kernel_by_id(info->btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
pr_debug("%s: failed to get BTF of id %u, aborting\n", __func__, info->btf_id);
|
||||
err = -1;
|
||||
btf = NULL;
|
||||
goto out;
|
||||
}
|
||||
perf_env__fetch_btf(env, info->btf_id, btf);
|
||||
|
@ -296,7 +296,7 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,
|
|||
|
||||
out:
|
||||
free(info_linear);
|
||||
free(btf);
|
||||
btf__free(btf);
|
||||
return err ? -1 : 0;
|
||||
}
|
||||
|
||||
|
@ -478,7 +478,8 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id)
|
|||
if (btf_id == 0)
|
||||
goto out;
|
||||
|
||||
if (btf__get_from_id(btf_id, &btf)) {
|
||||
btf = btf__load_from_kernel_by_id(btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
pr_debug("%s: failed to get BTF of id %u, aborting\n",
|
||||
__func__, btf_id);
|
||||
goto out;
|
||||
|
@ -486,7 +487,7 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id)
|
|||
perf_env__fetch_btf(env, btf_id, btf);
|
||||
|
||||
out:
|
||||
free(btf);
|
||||
btf__free(btf);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ static char *bpf_target_prog_name(int tgt_fd)
|
|||
struct bpf_prog_info_linear *info_linear;
|
||||
struct bpf_func_info *func_info;
|
||||
const struct btf_type *t;
|
||||
struct btf *btf = NULL;
|
||||
char *name = NULL;
|
||||
struct btf *btf;
|
||||
|
||||
info_linear = bpf_program__get_prog_info_linear(
|
||||
tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO);
|
||||
|
@ -74,12 +74,17 @@ static char *bpf_target_prog_name(int tgt_fd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (info_linear->info.btf_id == 0 ||
|
||||
btf__get_from_id(info_linear->info.btf_id, &btf)) {
|
||||
if (info_linear->info.btf_id == 0) {
|
||||
pr_debug("prog FD %d doesn't have valid btf\n", tgt_fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
btf = btf__load_from_kernel_by_id(info_linear->info.btf_id);
|
||||
if (libbpf_get_error(btf)) {
|
||||
pr_debug("failed to load btf for prog FD %d\n", tgt_fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
func_info = u64_to_ptr(info_linear->info.func_info);
|
||||
t = btf__type_by_id(btf, func_info[0].type_id);
|
||||
if (!t) {
|
||||
|
@ -89,6 +94,7 @@ static char *bpf_target_prog_name(int tgt_fd)
|
|||
}
|
||||
name = strdup(btf__name_by_offset(btf, t->name_off));
|
||||
out:
|
||||
btf__free(btf);
|
||||
free(info_linear);
|
||||
return name;
|
||||
}
|
||||
|
|
|
@ -4350,7 +4350,8 @@ static void do_test_file(unsigned int test_num)
|
|||
goto done;
|
||||
}
|
||||
|
||||
err = btf__get_from_id(info.btf_id, &btf);
|
||||
btf = btf__load_from_kernel_by_id(info.btf_id);
|
||||
err = libbpf_get_error(btf);
|
||||
if (CHECK(err, "cannot get btf from kernel, err: %d", err))
|
||||
goto done;
|
||||
|
||||
|
@ -4386,6 +4387,7 @@ skip:
|
|||
fprintf(stderr, "OK");
|
||||
|
||||
done:
|
||||
btf__free(btf);
|
||||
free(func_info);
|
||||
bpf_object__close(obj);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче