Commit e9fc3ce9 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

libbpf: Streamline error reporting for high-level APIs

Implement changes to error reporting for high-level libbpf APIs to make them
less surprising and less error-prone to users:
  - in all the cases when error happens, errno is set to an appropriate error
    value;
  - in libbpf 1.0 mode, all pointer-returning APIs return NULL on error and
    error code is communicated through errno; this applies both to APIs that
    already returned NULL before (so now they communicate more detailed error
    codes), as well as for many APIs that used ERR_PTR() macro and encoded
    error numbers as fake pointers.
  - in legacy (default) mode, those APIs that were returning ERR_PTR(err),
    continue doing so, but still set errno.

With these changes, errno can be always used to extract actual error,
regardless of legacy or libbpf 1.0 modes. This is utilized internally in
libbpf in places where libbpf uses it's own high-level APIs.
libbpf_get_error() is adapted to handle both cases completely transparently to
end-users (and is used by libbpf consistently as well).

More context, justification, and discussion can be found in "Libbpf: the road
to v1.0" document ([0]).

  [0] https://docs.google.com/document/d/1UyjTZuPFWiPFyKk1tV5an11_iaRuec6U-ZESZ54nNTY



Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Acked-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/20210525035935.1461796-5-andrii@kernel.org
parent f12b6543
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
	nr_linfo = info->nr_line_info;

	if (!nr_linfo)
		return NULL;
		return errno = EINVAL, NULL;

	/*
	 * The min size that bpf_prog_linfo has to access for
@@ -114,11 +114,11 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
	 */
	if (info->line_info_rec_size <
	    offsetof(struct bpf_line_info, file_name_off))
		return NULL;
		return errno = EINVAL, NULL;

	prog_linfo = calloc(1, sizeof(*prog_linfo));
	if (!prog_linfo)
		return NULL;
		return errno = ENOMEM, NULL;

	/* Copy xlated line_info */
	prog_linfo->nr_linfo = nr_linfo;
@@ -174,7 +174,7 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)

err_free:
	bpf_prog_linfo__free(prog_linfo);
	return NULL;
	return errno = EINVAL, NULL;
}

const struct bpf_line_info *
@@ -186,11 +186,11 @@ bpf_prog_linfo__lfind_addr_func(const struct bpf_prog_linfo *prog_linfo,
	const __u64 *jited_linfo;

	if (func_idx >= prog_linfo->nr_jited_func)
		return NULL;
		return errno = ENOENT, NULL;

	nr_linfo = prog_linfo->nr_jited_linfo_per_func[func_idx];
	if (nr_skip >= nr_linfo)
		return NULL;
		return errno = ENOENT, NULL;

	start = prog_linfo->jited_linfo_func_idx[func_idx] + nr_skip;
	jited_rec_size = prog_linfo->jited_rec_size;
@@ -198,7 +198,7 @@ bpf_prog_linfo__lfind_addr_func(const struct bpf_prog_linfo *prog_linfo,
		(start * jited_rec_size);
	jited_linfo = raw_jited_linfo;
	if (addr < *jited_linfo)
		return NULL;
		return errno = ENOENT, NULL;

	nr_linfo -= nr_skip;
	rec_size = prog_linfo->rec_size;
@@ -225,13 +225,13 @@ bpf_prog_linfo__lfind(const struct bpf_prog_linfo *prog_linfo,

	nr_linfo = prog_linfo->nr_linfo;
	if (nr_skip >= nr_linfo)
		return NULL;
		return errno = ENOENT, NULL;

	rec_size = prog_linfo->rec_size;
	raw_linfo = prog_linfo->raw_linfo + (nr_skip * rec_size);
	linfo = raw_linfo;
	if (insn_off < linfo->insn_off)
		return NULL;
		return errno = ENOENT, NULL;

	nr_linfo -= nr_skip;
	for (i = 0; i < nr_linfo; i++) {
+152 −150

File changed.

Preview size limit exceeded, changes collapsed.

+7 −7
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf,

	d = calloc(1, sizeof(struct btf_dump));
	if (!d)
		return ERR_PTR(-ENOMEM);
		return libbpf_err_ptr(-ENOMEM);

	d->btf = btf;
	d->btf_ext = btf_ext;
@@ -156,7 +156,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
	return d;
err:
	btf_dump__free(d);
	return ERR_PTR(err);
	return libbpf_err_ptr(err);
}

static int btf_dump_resize(struct btf_dump *d)
@@ -236,16 +236,16 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
	int err, i;

	if (id > btf__get_nr_types(d->btf))
		return -EINVAL;
		return libbpf_err(-EINVAL);

	err = btf_dump_resize(d);
	if (err)
		return err;
		return libbpf_err(err);

	d->emit_queue_cnt = 0;
	err = btf_dump_order_type(d, id, false);
	if (err < 0)
		return err;
		return libbpf_err(err);

	for (i = 0; i < d->emit_queue_cnt; i++)
		btf_dump_emit_type(d, d->emit_queue[i], 0 /*top-level*/);
@@ -1075,11 +1075,11 @@ int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
	int lvl, err;

	if (!OPTS_VALID(opts, btf_dump_emit_type_decl_opts))
		return -EINVAL;
		return libbpf_err(-EINVAL);

	err = btf_dump_resize(d);
	if (err)
		return -EINVAL;
		return libbpf_err(err);

	fname = OPTS_GET(opts, field_name, "");
	lvl = OPTS_GET(opts, indent_level, 0);
+261 −241

File changed.

Preview size limit exceeded, changes collapsed.

+4 −3
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <string.h>

#include "libbpf.h"
#include "libbpf_internal.h"

/* make sure libbpf doesn't use kernel-only integer typedefs */
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
@@ -39,7 +40,7 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
int libbpf_strerror(int err, char *buf, size_t size)
{
	if (!buf || !size)
		return -1;
		return libbpf_err(-EINVAL);

	err = err > 0 ? err : -err;

@@ -48,7 +49,7 @@ int libbpf_strerror(int err, char *buf, size_t size)

		ret = strerror_r(err, buf, size);
		buf[size - 1] = '\0';
		return ret;
		return libbpf_err_errno(ret);
	}

	if (err < __LIBBPF_ERRNO__END) {
@@ -62,5 +63,5 @@ int libbpf_strerror(int err, char *buf, size_t size)

	snprintf(buf, size, "Unknown libbpf error %d", err);
	buf[size - 1] = '\0';
	return -1;
	return libbpf_err(-ENOENT);
}
Loading