On 12/16/19 4:40 AM, Toke Høiland-Jørgensen wrote: > Probably the single most common error newcomers to XDP are stumped by is > the 'permission denied' error they get when trying to load their program > and 'ulimit -r' is set too low. For examples, see [0], [1]. > > Since the error code is UAPI, we can't change that. Instead, this patch > adds a few heuristics in libbpf and outputs an additional hint if they are > met: If an EPERM is returned on map create or program load, and geteuid() > shows we are root, and the current RLIMIT_MEMLOCK is not infinity, we > output a hint about raising 'ulimit -r' as an additional log line. > > [0] https://marc.info/?l=xdp-newbies&m=157043612505624&w=2 > [1] https://github.com/xdp-project/xdp-tutorial/issues/86 > > Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> LGTM with one minor no-essential suggestion below. Acked-by: Yonghong Song <yhs@xxxxxx> > --- > tools/lib/bpf/libbpf.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index a2cc7313763a..aec7995674d2 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -41,6 +41,7 @@ > #include <sys/types.h> > #include <sys/vfs.h> > #include <sys/utsname.h> > +#include <sys/resource.h> > #include <tools/libc_compat.h> > #include <libelf.h> > #include <gelf.h> > @@ -100,6 +101,24 @@ void libbpf_print(enum libbpf_print_level level, const char *format, ...) > va_end(args); > } > > +static void pr_perm_msg(int err) > +{ > + struct rlimit limit; > + > + if (err != -EPERM || geteuid() != 0) > + return; > + > + err = getrlimit(RLIMIT_MEMLOCK, &limit); > + if (err) > + return; > + > + if (limit.rlim_cur == RLIM_INFINITY) > + return; > + > + pr_warn("permission error while running as root; try raising 'ulimit -r'? current value: %lu\n", > + limit.rlim_cur); Here we print out in terms of bytes. Maybe in terms of kilo bytes or mega bytes is more user friendly, esp. we want them to set a different value? > +} > + > #define STRERR_BUFSIZE 128 > > /* Copied from tools/perf/util/util.h */ > @@ -2983,6 +3002,7 @@ bpf_object__create_maps(struct bpf_object *obj) > cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg)); > pr_warn("failed to create map (name: '%s'): %s(%d)\n", > map->name, cp, err); > + pr_perm_msg(err); > for (j = 0; j < i; j++) > zclose(obj->maps[j].fd); > return err; > @@ -4381,6 +4401,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, > ret = -errno; > cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); > pr_warn("load bpf program failed: %s\n", cp); > + pr_perm_msg(ret); > > if (log_buf && log_buf[0] != '\0') { > ret = -LIBBPF_ERRNO__VERIFY; >