2018-12-13 11:59:25 +08:00
|
|
|
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
|
|
|
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
|
2017-10-05 11:10:04 +08:00
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
#define _GNU_SOURCE
|
2018-05-04 09:37:15 +08:00
|
|
|
#include <ctype.h>
|
2017-10-05 11:10:04 +08:00
|
|
|
#include <errno.h>
|
2018-01-17 08:05:21 +08:00
|
|
|
#include <fcntl.h>
|
2020-07-21 10:48:16 +08:00
|
|
|
#include <ftw.h>
|
2017-10-05 11:10:04 +08:00
|
|
|
#include <libgen.h>
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
#include <mntent.h>
|
2017-10-05 11:10:04 +08:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <linux/limits.h>
|
|
|
|
#include <linux/magic.h>
|
2017-12-28 10:39:10 +08:00
|
|
|
#include <net/if.h>
|
2017-10-25 11:11:28 +08:00
|
|
|
#include <sys/mount.h>
|
tools: bpftool: adjust rlimit RLIMIT_MEMLOCK when loading programs, maps
The limit for memory locked in the kernel by a process is usually set to
64 kbytes by default. This can be an issue when creating large BPF maps
and/or loading many programs. A workaround is to raise this limit for
the current process before trying to create a new BPF map. Changing the
hard limit requires the CAP_SYS_RESOURCE and can usually only be done by
root user (for non-root users, a call to setrlimit fails (and sets
errno) and the program simply goes on with its rlimit unchanged).
There is no API to get the current amount of memory locked for a user,
therefore we cannot raise the limit only when required. One solution,
used by bcc, is to try to create the map, and on getting a EPERM error,
raising the limit to infinity before giving another try. Another
approach, used in iproute2, is to raise the limit in all cases, before
trying to create the map.
Here we do the same as in iproute2: the rlimit is raised to infinity
before trying to load programs or to create maps with bpftool.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-11-07 20:29:30 +08:00
|
|
|
#include <sys/resource.h>
|
2017-12-28 10:39:10 +08:00
|
|
|
#include <sys/stat.h>
|
2017-10-05 11:10:04 +08:00
|
|
|
#include <sys/vfs.h>
|
|
|
|
|
2020-01-20 21:06:46 +08:00
|
|
|
#include <bpf/bpf.h>
|
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
2021-10-24 04:51:52 +08:00
|
|
|
#include <bpf/hashmap.h>
|
2020-01-20 21:06:46 +08:00
|
|
|
#include <bpf/libbpf.h> /* libbpf_num_possible_cpus */
|
2022-01-19 18:02:55 +08:00
|
|
|
#include <bpf/btf.h>
|
2017-10-05 11:10:04 +08:00
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
2018-03-06 21:50:10 +08:00
|
|
|
#ifndef BPF_FS_MAGIC
|
|
|
|
#define BPF_FS_MAGIC 0xcafe4a11
|
|
|
|
#endif
|
|
|
|
|
2020-06-24 22:31:54 +08:00
|
|
|
const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = {
|
|
|
|
[BPF_CGROUP_INET_INGRESS] = "ingress",
|
|
|
|
[BPF_CGROUP_INET_EGRESS] = "egress",
|
|
|
|
[BPF_CGROUP_INET_SOCK_CREATE] = "sock_create",
|
2020-07-07 07:01:27 +08:00
|
|
|
[BPF_CGROUP_INET_SOCK_RELEASE] = "sock_release",
|
2020-06-24 22:31:54 +08:00
|
|
|
[BPF_CGROUP_SOCK_OPS] = "sock_ops",
|
|
|
|
[BPF_CGROUP_DEVICE] = "device",
|
|
|
|
[BPF_CGROUP_INET4_BIND] = "bind4",
|
|
|
|
[BPF_CGROUP_INET6_BIND] = "bind6",
|
|
|
|
[BPF_CGROUP_INET4_CONNECT] = "connect4",
|
|
|
|
[BPF_CGROUP_INET6_CONNECT] = "connect6",
|
|
|
|
[BPF_CGROUP_INET4_POST_BIND] = "post_bind4",
|
|
|
|
[BPF_CGROUP_INET6_POST_BIND] = "post_bind6",
|
|
|
|
[BPF_CGROUP_INET4_GETPEERNAME] = "getpeername4",
|
|
|
|
[BPF_CGROUP_INET6_GETPEERNAME] = "getpeername6",
|
|
|
|
[BPF_CGROUP_INET4_GETSOCKNAME] = "getsockname4",
|
|
|
|
[BPF_CGROUP_INET6_GETSOCKNAME] = "getsockname6",
|
|
|
|
[BPF_CGROUP_UDP4_SENDMSG] = "sendmsg4",
|
|
|
|
[BPF_CGROUP_UDP6_SENDMSG] = "sendmsg6",
|
|
|
|
[BPF_CGROUP_SYSCTL] = "sysctl",
|
|
|
|
[BPF_CGROUP_UDP4_RECVMSG] = "recvmsg4",
|
|
|
|
[BPF_CGROUP_UDP6_RECVMSG] = "recvmsg6",
|
|
|
|
[BPF_CGROUP_GETSOCKOPT] = "getsockopt",
|
|
|
|
[BPF_CGROUP_SETSOCKOPT] = "setsockopt",
|
|
|
|
[BPF_SK_SKB_STREAM_PARSER] = "sk_skb_stream_parser",
|
|
|
|
[BPF_SK_SKB_STREAM_VERDICT] = "sk_skb_stream_verdict",
|
2021-03-31 10:32:30 +08:00
|
|
|
[BPF_SK_SKB_VERDICT] = "sk_skb_verdict",
|
2020-06-24 22:31:54 +08:00
|
|
|
[BPF_SK_MSG_VERDICT] = "sk_msg_verdict",
|
|
|
|
[BPF_LIRC_MODE2] = "lirc_mode2",
|
|
|
|
[BPF_FLOW_DISSECTOR] = "flow_dissector",
|
|
|
|
[BPF_TRACE_RAW_TP] = "raw_tp",
|
|
|
|
[BPF_TRACE_FENTRY] = "fentry",
|
|
|
|
[BPF_TRACE_FEXIT] = "fexit",
|
|
|
|
[BPF_MODIFY_RETURN] = "mod_ret",
|
|
|
|
[BPF_LSM_MAC] = "lsm_mac",
|
2020-07-17 18:35:34 +08:00
|
|
|
[BPF_SK_LOOKUP] = "sk_lookup",
|
2021-07-31 05:54:31 +08:00
|
|
|
[BPF_TRACE_ITER] = "trace_iter",
|
|
|
|
[BPF_XDP_DEVMAP] = "xdp_devmap",
|
|
|
|
[BPF_XDP_CPUMAP] = "xdp_cpumap",
|
|
|
|
[BPF_XDP] = "xdp",
|
|
|
|
[BPF_SK_REUSEPORT_SELECT] = "sk_skb_reuseport_select",
|
|
|
|
[BPF_SK_REUSEPORT_SELECT_OR_MIGRATE] = "sk_skb_reuseport_select_or_migrate",
|
2021-11-10 19:46:31 +08:00
|
|
|
[BPF_PERF_EVENT] = "perf_event",
|
2022-03-18 23:01:06 +08:00
|
|
|
[BPF_TRACE_KPROBE_MULTI] = "trace_kprobe_multi",
|
2020-06-24 22:31:54 +08:00
|
|
|
};
|
|
|
|
|
2019-08-15 22:32:20 +08:00
|
|
|
void p_err(const char *fmt, ...)
|
2017-11-04 04:59:07 +08:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
if (json_output) {
|
|
|
|
jsonw_start_object(json_wtr);
|
|
|
|
jsonw_name(json_wtr, "error");
|
|
|
|
jsonw_vprintf_enquote(json_wtr, fmt, ap);
|
|
|
|
jsonw_end_object(json_wtr);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Error: ");
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
2019-08-15 22:32:20 +08:00
|
|
|
void p_info(const char *fmt, ...)
|
2017-11-04 04:59:07 +08:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
if (json_output)
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(stderr, fmt, ap);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
|
2017-10-05 11:10:04 +08:00
|
|
|
static bool is_bpffs(char *path)
|
|
|
|
{
|
|
|
|
struct statfs st_fs;
|
|
|
|
|
|
|
|
if (statfs(path, &st_fs) < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return (unsigned long)st_fs.f_type == BPF_FS_MAGIC;
|
|
|
|
}
|
|
|
|
|
tools: bpftool: adjust rlimit RLIMIT_MEMLOCK when loading programs, maps
The limit for memory locked in the kernel by a process is usually set to
64 kbytes by default. This can be an issue when creating large BPF maps
and/or loading many programs. A workaround is to raise this limit for
the current process before trying to create a new BPF map. Changing the
hard limit requires the CAP_SYS_RESOURCE and can usually only be done by
root user (for non-root users, a call to setrlimit fails (and sets
errno) and the program simply goes on with its rlimit unchanged).
There is no API to get the current amount of memory locked for a user,
therefore we cannot raise the limit only when required. One solution,
used by bcc, is to try to create the map, and on getting a EPERM error,
raising the limit to infinity before giving another try. Another
approach, used in iproute2, is to raise the limit in all cases, before
trying to create the map.
Here we do the same as in iproute2: the rlimit is raised to infinity
before trying to load programs or to create maps with bpftool.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-11-07 20:29:30 +08:00
|
|
|
void set_max_rlimit(void)
|
|
|
|
{
|
|
|
|
struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
|
|
|
|
|
|
|
|
setrlimit(RLIMIT_MEMLOCK, &rinf);
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:13:18 +08:00
|
|
|
static int
|
|
|
|
mnt_fs(const char *target, const char *type, char *buff, size_t bufflen)
|
2017-10-25 11:11:28 +08:00
|
|
|
{
|
|
|
|
bool bind_done = false;
|
|
|
|
|
|
|
|
while (mount("", target, "none", MS_PRIVATE | MS_REC, NULL)) {
|
|
|
|
if (errno != EINVAL || bind_done) {
|
|
|
|
snprintf(buff, bufflen,
|
|
|
|
"mount --make-private %s failed: %s",
|
|
|
|
target, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mount(target, target, "none", MS_BIND, NULL)) {
|
|
|
|
snprintf(buff, bufflen,
|
|
|
|
"mount --bind %s %s failed: %s",
|
|
|
|
target, target, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bind_done = true;
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:13:18 +08:00
|
|
|
if (mount(type, target, type, 0, "mode=0700")) {
|
|
|
|
snprintf(buff, bufflen, "mount -t %s %s %s failed: %s",
|
|
|
|
type, type, target, strerror(errno));
|
2017-10-25 11:11:28 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:13:18 +08:00
|
|
|
int mount_tracefs(const char *target)
|
|
|
|
{
|
|
|
|
char err_str[ERR_MAX_LEN];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN);
|
|
|
|
if (err) {
|
|
|
|
err_str[ERR_MAX_LEN - 1] = '\0';
|
|
|
|
p_err("can't mount tracefs: %s", err_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
int open_obj_pinned(const char *path, bool quiet)
|
2017-10-05 11:10:04 +08:00
|
|
|
{
|
2020-07-21 10:48:16 +08:00
|
|
|
char *pname;
|
|
|
|
int fd = -1;
|
2017-10-05 11:10:04 +08:00
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
pname = strdup(path);
|
|
|
|
if (!pname) {
|
|
|
|
if (!quiet)
|
|
|
|
p_err("mem alloc failed");
|
|
|
|
goto out_ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = bpf_obj_get(pname);
|
2017-10-05 11:10:04 +08:00
|
|
|
if (fd < 0) {
|
tools: bpftool: pass an argument to silence open_obj_pinned()
Function open_obj_pinned() prints error messages when it fails to open a
link in the BPF virtual file system. However, in some occasions it is
not desirable to print an error, for example when we parse all links
under the bpffs root, and the error is due to some paths actually being
symbolic links.
Example output:
# ls -l /sys/fs/bpf/
lrwxrwxrwx 1 root root 0 Oct 18 19:00 ip -> /sys/fs/bpf/tc/
drwx------ 3 root root 0 Oct 18 19:00 tc
lrwxrwxrwx 1 root root 0 Oct 18 19:00 xdp -> /sys/fs/bpf/tc/
# bpftool --bpffs prog show
Error: bpf obj get (/sys/fs/bpf): Permission denied
Error: bpf obj get (/sys/fs/bpf): Permission denied
# strace -e bpf bpftool --bpffs prog show
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/ip", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/xdp", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
...
To fix it, pass a bool as a second argument to the function, and prevent
it from printing an error when the argument is set to true.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-11-08 19:52:27 +08:00
|
|
|
if (!quiet)
|
2020-07-21 10:48:16 +08:00
|
|
|
p_err("bpf obj get (%s): %s", pname,
|
|
|
|
errno == EACCES && !is_bpffs(dirname(pname)) ?
|
tools: bpftool: pass an argument to silence open_obj_pinned()
Function open_obj_pinned() prints error messages when it fails to open a
link in the BPF virtual file system. However, in some occasions it is
not desirable to print an error, for example when we parse all links
under the bpffs root, and the error is due to some paths actually being
symbolic links.
Example output:
# ls -l /sys/fs/bpf/
lrwxrwxrwx 1 root root 0 Oct 18 19:00 ip -> /sys/fs/bpf/tc/
drwx------ 3 root root 0 Oct 18 19:00 tc
lrwxrwxrwx 1 root root 0 Oct 18 19:00 xdp -> /sys/fs/bpf/tc/
# bpftool --bpffs prog show
Error: bpf obj get (/sys/fs/bpf): Permission denied
Error: bpf obj get (/sys/fs/bpf): Permission denied
# strace -e bpf bpftool --bpffs prog show
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/ip", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/xdp", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
...
To fix it, pass a bool as a second argument to the function, and prevent
it from printing an error when the argument is set to true.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-11-08 19:52:27 +08:00
|
|
|
"directory not in bpf file system (bpffs)" :
|
|
|
|
strerror(errno));
|
2020-07-21 10:48:16 +08:00
|
|
|
goto out_free;
|
2017-10-05 11:10:04 +08:00
|
|
|
}
|
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
out_free:
|
|
|
|
free(pname);
|
|
|
|
out_ret:
|
2017-11-08 12:55:47 +08:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
int open_obj_pinned_any(const char *path, enum bpf_obj_type exp_type)
|
2017-11-08 12:55:47 +08:00
|
|
|
{
|
|
|
|
enum bpf_obj_type type;
|
|
|
|
int fd;
|
|
|
|
|
tools: bpftool: pass an argument to silence open_obj_pinned()
Function open_obj_pinned() prints error messages when it fails to open a
link in the BPF virtual file system. However, in some occasions it is
not desirable to print an error, for example when we parse all links
under the bpffs root, and the error is due to some paths actually being
symbolic links.
Example output:
# ls -l /sys/fs/bpf/
lrwxrwxrwx 1 root root 0 Oct 18 19:00 ip -> /sys/fs/bpf/tc/
drwx------ 3 root root 0 Oct 18 19:00 tc
lrwxrwxrwx 1 root root 0 Oct 18 19:00 xdp -> /sys/fs/bpf/tc/
# bpftool --bpffs prog show
Error: bpf obj get (/sys/fs/bpf): Permission denied
Error: bpf obj get (/sys/fs/bpf): Permission denied
# strace -e bpf bpftool --bpffs prog show
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/ip", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
bpf(BPF_OBJ_GET, {pathname="/sys/fs/bpf/xdp", bpf_fd=0}, 72) = -1 EACCES (Permission denied)
Error: bpf obj get (/sys/fs/bpf): Permission denied
...
To fix it, pass a bool as a second argument to the function, and prevent
it from printing an error when the argument is set to true.
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-11-08 19:52:27 +08:00
|
|
|
fd = open_obj_pinned(path, false);
|
2017-11-08 12:55:47 +08:00
|
|
|
if (fd < 0)
|
|
|
|
return -1;
|
|
|
|
|
2017-10-05 11:10:04 +08:00
|
|
|
type = get_fd_type(fd);
|
|
|
|
if (type < 0) {
|
|
|
|
close(fd);
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
if (type != exp_type) {
|
2017-10-24 00:24:13 +08:00
|
|
|
p_err("incorrect object type: %s", get_fd_type_name(type));
|
2017-10-05 11:10:04 +08:00
|
|
|
close(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2018-11-10 00:21:44 +08:00
|
|
|
int mount_bpffs_for_pin(const char *name)
|
2017-10-05 11:10:04 +08:00
|
|
|
{
|
2017-10-25 11:11:28 +08:00
|
|
|
char err_str[ERR_MAX_LEN];
|
|
|
|
char *file;
|
|
|
|
char *dir;
|
2017-12-13 23:18:53 +08:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
file = malloc(strlen(name) + 1);
|
2021-07-15 19:06:09 +08:00
|
|
|
if (!file) {
|
|
|
|
p_err("mem alloc failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-12-13 23:18:53 +08:00
|
|
|
strcpy(file, name);
|
|
|
|
dir = dirname(file);
|
|
|
|
|
2018-11-10 00:21:44 +08:00
|
|
|
if (is_bpffs(dir))
|
|
|
|
/* nothing to do if already mounted */
|
2017-12-13 23:18:53 +08:00
|
|
|
goto out_free;
|
|
|
|
|
2018-12-18 18:13:19 +08:00
|
|
|
if (block_mount) {
|
|
|
|
p_err("no BPF file system found, not mounting it due to --nomount option");
|
|
|
|
err = -1;
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
2018-12-18 18:13:18 +08:00
|
|
|
err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
|
2018-11-10 00:21:44 +08:00
|
|
|
if (err) {
|
2017-12-13 23:18:53 +08:00
|
|
|
err_str[ERR_MAX_LEN - 1] = '\0';
|
|
|
|
p_err("can't mount BPF file system to pin the object (%s): %s",
|
|
|
|
name, err_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
out_free:
|
|
|
|
free(file);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2018-11-10 00:21:44 +08:00
|
|
|
int do_pin_fd(int fd, const char *name)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = mount_bpffs_for_pin(name);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
2019-08-07 08:19:23 +08:00
|
|
|
err = bpf_obj_pin(fd, name);
|
|
|
|
if (err)
|
|
|
|
p_err("can't pin the object (%s): %s", name, strerror(errno));
|
|
|
|
|
|
|
|
return err;
|
2018-11-10 00:21:44 +08:00
|
|
|
}
|
|
|
|
|
2020-03-13 02:46:07 +08:00
|
|
|
int do_pin_any(int argc, char **argv, int (*get_fd)(int *, char ***))
|
2017-12-13 23:18:53 +08:00
|
|
|
{
|
2017-10-05 11:10:04 +08:00
|
|
|
int err;
|
|
|
|
int fd;
|
|
|
|
|
2020-03-13 02:46:07 +08:00
|
|
|
fd = get_fd(&argc, &argv);
|
|
|
|
if (fd < 0)
|
|
|
|
return fd;
|
2017-10-05 11:10:04 +08:00
|
|
|
|
2017-12-13 23:18:53 +08:00
|
|
|
err = do_pin_fd(fd, *argv);
|
2017-10-05 11:10:04 +08:00
|
|
|
|
2017-10-25 11:11:28 +08:00
|
|
|
close(fd);
|
|
|
|
return err;
|
2017-10-05 11:10:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *get_fd_type_name(enum bpf_obj_type type)
|
|
|
|
{
|
|
|
|
static const char * const names[] = {
|
|
|
|
[BPF_OBJ_UNKNOWN] = "unknown",
|
|
|
|
[BPF_OBJ_PROG] = "prog",
|
|
|
|
[BPF_OBJ_MAP] = "map",
|
|
|
|
};
|
|
|
|
|
|
|
|
if (type < 0 || type >= ARRAY_SIZE(names) || !names[type])
|
|
|
|
return names[BPF_OBJ_UNKNOWN];
|
|
|
|
|
|
|
|
return names[type];
|
|
|
|
}
|
|
|
|
|
2022-01-19 18:02:55 +08:00
|
|
|
void get_prog_full_name(const struct bpf_prog_info *prog_info, int prog_fd,
|
|
|
|
char *name_buff, size_t buff_len)
|
|
|
|
{
|
|
|
|
const char *prog_name = prog_info->name;
|
|
|
|
const struct btf_type *func_type;
|
2022-02-03 06:59:13 +08:00
|
|
|
const struct bpf_func_info finfo = {};
|
2022-01-19 18:02:55 +08:00
|
|
|
struct bpf_prog_info info = {};
|
|
|
|
__u32 info_len = sizeof(info);
|
|
|
|
struct btf *prog_btf = NULL;
|
|
|
|
|
|
|
|
if (buff_len <= BPF_OBJ_NAME_LEN ||
|
|
|
|
strlen(prog_info->name) < BPF_OBJ_NAME_LEN - 1)
|
|
|
|
goto copy_name;
|
|
|
|
|
|
|
|
if (!prog_info->btf_id || prog_info->nr_func_info == 0)
|
|
|
|
goto copy_name;
|
|
|
|
|
|
|
|
info.nr_func_info = 1;
|
|
|
|
info.func_info_rec_size = prog_info->func_info_rec_size;
|
|
|
|
if (info.func_info_rec_size > sizeof(finfo))
|
|
|
|
info.func_info_rec_size = sizeof(finfo);
|
|
|
|
info.func_info = ptr_to_u64(&finfo);
|
|
|
|
|
|
|
|
if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len))
|
|
|
|
goto copy_name;
|
|
|
|
|
|
|
|
prog_btf = btf__load_from_kernel_by_id(info.btf_id);
|
|
|
|
if (!prog_btf)
|
|
|
|
goto copy_name;
|
|
|
|
|
|
|
|
func_type = btf__type_by_id(prog_btf, finfo.type_id);
|
|
|
|
if (!func_type || !btf_is_func(func_type))
|
|
|
|
goto copy_name;
|
|
|
|
|
|
|
|
prog_name = btf__name_by_offset(prog_btf, func_type->name_off);
|
|
|
|
|
|
|
|
copy_name:
|
|
|
|
snprintf(name_buff, buff_len, "%s", prog_name);
|
|
|
|
|
|
|
|
if (prog_btf)
|
|
|
|
btf__free(prog_btf);
|
|
|
|
}
|
|
|
|
|
2017-10-05 11:10:04 +08:00
|
|
|
int get_fd_type(int fd)
|
|
|
|
{
|
|
|
|
char path[PATH_MAX];
|
|
|
|
char buf[512];
|
|
|
|
ssize_t n;
|
|
|
|
|
2018-12-01 00:25:44 +08:00
|
|
|
snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
|
2017-10-05 11:10:04 +08:00
|
|
|
|
|
|
|
n = readlink(path, buf, sizeof(buf));
|
|
|
|
if (n < 0) {
|
2017-10-24 00:24:13 +08:00
|
|
|
p_err("can't read link type: %s", strerror(errno));
|
2017-10-05 11:10:04 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (n == sizeof(path)) {
|
2017-10-24 00:24:13 +08:00
|
|
|
p_err("can't read link type: path too long!");
|
2017-10-05 11:10:04 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strstr(buf, "bpf-map"))
|
|
|
|
return BPF_OBJ_MAP;
|
|
|
|
else if (strstr(buf, "bpf-prog"))
|
|
|
|
return BPF_OBJ_PROG;
|
2020-04-29 08:16:12 +08:00
|
|
|
else if (strstr(buf, "bpf-link"))
|
|
|
|
return BPF_OBJ_LINK;
|
2017-10-05 11:10:04 +08:00
|
|
|
|
|
|
|
return BPF_OBJ_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *get_fdinfo(int fd, const char *key)
|
|
|
|
{
|
|
|
|
char path[PATH_MAX];
|
|
|
|
char *line = NULL;
|
|
|
|
size_t line_n = 0;
|
|
|
|
ssize_t n;
|
|
|
|
FILE *fdi;
|
|
|
|
|
2018-12-01 00:25:44 +08:00
|
|
|
snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd);
|
2017-10-05 11:10:04 +08:00
|
|
|
|
|
|
|
fdi = fopen(path, "r");
|
2019-01-29 02:01:21 +08:00
|
|
|
if (!fdi)
|
2017-10-05 11:10:04 +08:00
|
|
|
return NULL;
|
|
|
|
|
2018-11-08 19:52:25 +08:00
|
|
|
while ((n = getline(&line, &line_n, fdi)) > 0) {
|
2017-10-05 11:10:04 +08:00
|
|
|
char *value;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!strstr(line, key))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fclose(fdi);
|
|
|
|
|
|
|
|
value = strchr(line, '\t');
|
|
|
|
if (!value || !value[1]) {
|
|
|
|
free(line);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
value++;
|
|
|
|
|
|
|
|
len = strlen(value);
|
|
|
|
memmove(line, value, len);
|
|
|
|
line[len - 1] = '\0';
|
|
|
|
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(line);
|
|
|
|
fclose(fdi);
|
|
|
|
return NULL;
|
|
|
|
}
|
tools: bpftool: add JSON output for `bpftool prog dump xlated *` command
Add a new printing function to dump translated eBPF instructions as
JSON. As for plain output, opcodes are printed only on request (when
`opcodes` is provided on the command line).
The disassembled output is generated by the same code that is used by
the kernel verifier.
Example output:
$ bpftool --json --pretty prog dump xlated id 1
[{
"disasm": "(bf) r6 = r1"
},{
"disasm": "(61) r7 = *(u32 *)(r6 +16)"
},{
"disasm": "(95) exit"
}
]
$ bpftool --json --pretty prog dump xlated id 1 opcodes
[{
"disasm": "(bf) r6 = r1",
"opcodes": {
"code": "0xbf",
"src_reg": "0x1",
"dst_reg": "0x6",
"off": ["0x00","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
},{
"disasm": "(61) r7 = *(u32 *)(r6 +16)",
"opcodes": {
"code": "0x61",
"src_reg": "0x6",
"dst_reg": "0x7",
"off": ["0x10","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
},{
"disasm": "(95) exit",
"opcodes": {
"code": "0x95",
"src_reg": "0x0",
"dst_reg": "0x0",
"off": ["0x00","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
}
]
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-10-24 00:24:10 +08:00
|
|
|
|
2018-05-04 09:37:16 +08:00
|
|
|
void print_data_json(uint8_t *data, size_t len)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
jsonw_start_array(json_wtr);
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
jsonw_printf(json_wtr, "%d", data[i]);
|
|
|
|
jsonw_end_array(json_wtr);
|
|
|
|
}
|
|
|
|
|
tools: bpftool: add JSON output for `bpftool prog dump xlated *` command
Add a new printing function to dump translated eBPF instructions as
JSON. As for plain output, opcodes are printed only on request (when
`opcodes` is provided on the command line).
The disassembled output is generated by the same code that is used by
the kernel verifier.
Example output:
$ bpftool --json --pretty prog dump xlated id 1
[{
"disasm": "(bf) r6 = r1"
},{
"disasm": "(61) r7 = *(u32 *)(r6 +16)"
},{
"disasm": "(95) exit"
}
]
$ bpftool --json --pretty prog dump xlated id 1 opcodes
[{
"disasm": "(bf) r6 = r1",
"opcodes": {
"code": "0xbf",
"src_reg": "0x1",
"dst_reg": "0x6",
"off": ["0x00","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
},{
"disasm": "(61) r7 = *(u32 *)(r6 +16)",
"opcodes": {
"code": "0x61",
"src_reg": "0x6",
"dst_reg": "0x7",
"off": ["0x10","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
},{
"disasm": "(95) exit",
"opcodes": {
"code": "0x95",
"src_reg": "0x0",
"dst_reg": "0x0",
"off": ["0x00","0x00"
],
"imm": ["0x00","0x00","0x00","0x00"
]
}
}
]
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-10-24 00:24:10 +08:00
|
|
|
void print_hex_data_json(uint8_t *data, size_t len)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
jsonw_start_array(json_wtr);
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
jsonw_printf(json_wtr, "\"0x%02hhx\"", data[i]);
|
|
|
|
jsonw_end_array(json_wtr);
|
|
|
|
}
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
/* extra params for nftw cb */
|
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
2021-10-24 04:51:52 +08:00
|
|
|
static struct hashmap *build_fn_table;
|
2020-07-21 10:48:16 +08:00
|
|
|
static enum bpf_obj_type build_fn_type;
|
|
|
|
|
|
|
|
static int do_build_table_cb(const char *fpath, const struct stat *sb,
|
|
|
|
int typeflag, struct FTW *ftwbuf)
|
|
|
|
{
|
|
|
|
struct bpf_prog_info pinned_info;
|
|
|
|
__u32 len = sizeof(pinned_info);
|
|
|
|
enum bpf_obj_type objtype;
|
|
|
|
int fd, err = 0;
|
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
2021-10-24 04:51:52 +08:00
|
|
|
char *path;
|
2020-07-21 10:48:16 +08:00
|
|
|
|
|
|
|
if (typeflag != FTW_F)
|
|
|
|
goto out_ret;
|
|
|
|
|
|
|
|
fd = open_obj_pinned(fpath, true);
|
|
|
|
if (fd < 0)
|
|
|
|
goto out_ret;
|
|
|
|
|
|
|
|
objtype = get_fd_type(fd);
|
|
|
|
if (objtype != build_fn_type)
|
|
|
|
goto out_close;
|
|
|
|
|
|
|
|
memset(&pinned_info, 0, sizeof(pinned_info));
|
|
|
|
if (bpf_obj_get_info_by_fd(fd, &pinned_info, &len))
|
|
|
|
goto out_close;
|
|
|
|
|
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
2021-10-24 04:51:52 +08:00
|
|
|
path = strdup(fpath);
|
|
|
|
if (!path) {
|
2020-07-21 10:48:16 +08:00
|
|
|
err = -1;
|
|
|
|
goto out_close;
|
|
|
|
}
|
|
|
|
|
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
2021-10-24 04:51:52 +08:00
|
|
|
err = hashmap__append(build_fn_table, u32_as_hash_field(pinned_info.id), path);
|
|
|
|
if (err) {
|
|
|
|
p_err("failed to append entry to hashmap for ID %u, path '%s': %s",
|
|
|
|
pinned_info.id, path, strerror(errno));
|
2020-07-21 10:48:16 +08:00
|
|
|
goto out_close;
|
|
|
|
}
|
|
|
|
|
|
|
|
out_close:
|
|
|
|
close(fd);
|
|
|
|
out_ret:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
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
2021-10-24 04:51:52 +08:00
|
|
|
int build_pinned_obj_table(struct hashmap *tab,
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
enum bpf_obj_type type)
|
|
|
|
{
|
|
|
|
struct mntent *mntent = NULL;
|
|
|
|
FILE *mntfile = NULL;
|
2020-07-21 10:48:16 +08:00
|
|
|
int flags = FTW_PHYS;
|
|
|
|
int nopenfd = 16;
|
|
|
|
int err = 0;
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
|
|
|
|
mntfile = setmntent("/proc/mounts", "r");
|
|
|
|
if (!mntfile)
|
|
|
|
return -1;
|
|
|
|
|
2020-07-21 10:48:16 +08:00
|
|
|
build_fn_table = tab;
|
|
|
|
build_fn_type = type;
|
|
|
|
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
while ((mntent = getmntent(mntfile))) {
|
2020-07-21 10:48:16 +08:00
|
|
|
char *path = mntent->mnt_dir;
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
|
|
|
|
if (strncmp(mntent->mnt_type, "bpf", 3) != 0)
|
|
|
|
continue;
|
2020-07-21 10:48:16 +08:00
|
|
|
err = nftw(path, do_build_table_cb, nopenfd, flags);
|
|
|
|
if (err)
|
|
|
|
break;
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
}
|
|
|
|
fclose(mntfile);
|
2020-07-21 10:48:16 +08:00
|
|
|
return err;
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08: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
2021-10-24 04:51:52 +08:00
|
|
|
void delete_pinned_obj_table(struct hashmap *map)
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08: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
2021-10-24 04:51:52 +08:00
|
|
|
struct hashmap_entry *entry;
|
|
|
|
size_t bkt;
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08: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
2021-10-24 04:51:52 +08:00
|
|
|
if (!map)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hashmap__for_each_entry(map, entry, bkt)
|
|
|
|
free(entry->value);
|
|
|
|
|
|
|
|
hashmap__free(map);
|
tools: bpftool: show filenames of pinned objects
Added support to show filenames of pinned objects.
For example:
root@test# ./bpftool prog
3: tracepoint name tracepoint__irq tag f677a7dd722299a3
loaded_at Oct 26/11:39 uid 0
xlated 160B not jited memlock 4096B map_ids 4
pinned /sys/fs/bpf/softirq_prog
4: tracepoint name tracepoint__irq tag ea5dc530d00b92b6
loaded_at Oct 26/11:39 uid 0
xlated 392B not jited memlock 4096B map_ids 4,6
root@test# ./bpftool --json --pretty prog
[{
"id": 3,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "f677a7dd722299a3",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 160,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4
],
"pinned": ["/sys/fs/bpf/softirq_prog"
]
},{
"id": 4,
"type": "tracepoint",
"name": "tracepoint__irq",
"tag": "ea5dc530d00b92b6",
"loaded_at": "Oct 26/11:39",
"uid": 0,
"bytes_xlated": 392,
"jited": false,
"bytes_memlock": 4096,
"map_ids": [4,6
],
"pinned": []
}
]
root@test# ./bpftool map
4: hash name start flags 0x0
key 4B value 16B max_entries 10240 memlock 1003520B
pinned /sys/fs/bpf/softirq_map1
5: hash name iptr flags 0x0
key 4B value 8B max_entries 10240 memlock 921600B
root@test# ./bpftool --json --pretty map
[{
"id": 4,
"type": "hash",
"name": "start",
"flags": 0,
"bytes_key": 4,
"bytes_value": 16,
"max_entries": 10240,
"bytes_memlock": 1003520,
"pinned": ["/sys/fs/bpf/softirq_map1"
]
},{
"id": 5,
"type": "hash",
"name": "iptr",
"flags": 0,
"bytes_key": 4,
"bytes_value": 8,
"max_entries": 10240,
"bytes_memlock": 921600,
"pinned": []
}
]
Signed-off-by: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-11-08 12:55:48 +08:00
|
|
|
}
|
2017-12-28 10:39:10 +08:00
|
|
|
|
2018-05-04 09:37:16 +08:00
|
|
|
unsigned int get_page_size(void)
|
|
|
|
{
|
|
|
|
static int result;
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
result = getpagesize();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-05-04 09:37:15 +08:00
|
|
|
unsigned int get_possible_cpus(void)
|
|
|
|
{
|
2019-06-11 08:56:52 +08:00
|
|
|
int cpus = libbpf_num_possible_cpus();
|
2018-05-04 09:37:15 +08:00
|
|
|
|
2019-06-11 08:56:52 +08:00
|
|
|
if (cpus < 0) {
|
|
|
|
p_err("Can't get # of possible cpus: %s", strerror(-cpus));
|
2018-05-04 09:37:15 +08:00
|
|
|
exit(-1);
|
|
|
|
}
|
2019-06-11 08:56:52 +08:00
|
|
|
return cpus;
|
2018-05-04 09:37:15 +08:00
|
|
|
}
|
|
|
|
|
2017-12-28 10:39:10 +08:00
|
|
|
static char *
|
|
|
|
ifindex_to_name_ns(__u32 ifindex, __u32 ns_dev, __u32 ns_ino, char *buf)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = stat("/proc/self/ns/net", &st);
|
|
|
|
if (err) {
|
|
|
|
p_err("Can't stat /proc/self: %s", strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (st.st_dev != ns_dev || st.st_ino != ns_ino)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return if_indextoname(ifindex, buf);
|
|
|
|
}
|
|
|
|
|
2018-01-17 08:05:21 +08:00
|
|
|
static int read_sysfs_hex_int(char *path)
|
|
|
|
{
|
|
|
|
char vendor_id_buf[8];
|
|
|
|
int len;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = open(path, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
|
|
|
p_err("Can't open %s: %s", path, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = read(fd, vendor_id_buf, sizeof(vendor_id_buf));
|
|
|
|
close(fd);
|
|
|
|
if (len < 0) {
|
|
|
|
p_err("Can't read %s: %s", path, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (len >= (int)sizeof(vendor_id_buf)) {
|
|
|
|
p_err("Value in %s too long", path);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
vendor_id_buf[len] = 0;
|
|
|
|
|
|
|
|
return strtol(vendor_id_buf, NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int read_sysfs_netdev_hex_int(char *devname, const char *entry_name)
|
|
|
|
{
|
|
|
|
char full_path[64];
|
|
|
|
|
|
|
|
snprintf(full_path, sizeof(full_path), "/sys/class/net/%s/device/%s",
|
|
|
|
devname, entry_name);
|
|
|
|
|
|
|
|
return read_sysfs_hex_int(full_path);
|
|
|
|
}
|
|
|
|
|
2018-10-19 02:34:55 +08:00
|
|
|
const char *
|
|
|
|
ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
|
|
|
|
const char **opt)
|
2018-01-17 08:05:21 +08:00
|
|
|
{
|
|
|
|
char devname[IF_NAMESIZE];
|
|
|
|
int vendor_id;
|
|
|
|
int device_id;
|
|
|
|
|
|
|
|
if (!ifindex_to_name_ns(ifindex, ns_dev, ns_ino, devname)) {
|
|
|
|
p_err("Can't get net device name for ifindex %d: %s", ifindex,
|
|
|
|
strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
vendor_id = read_sysfs_netdev_hex_int(devname, "vendor");
|
|
|
|
if (vendor_id < 0) {
|
|
|
|
p_err("Can't get device vendor id for %s", devname);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (vendor_id) {
|
|
|
|
case 0x19ee:
|
|
|
|
device_id = read_sysfs_netdev_hex_int(devname, "device");
|
|
|
|
if (device_id != 0x4000 &&
|
|
|
|
device_id != 0x6000 &&
|
|
|
|
device_id != 0x6003)
|
|
|
|
p_info("Unknown NFP device ID, assuming it is NFP-6xxx arch");
|
2018-10-19 02:34:55 +08:00
|
|
|
*opt = "ctx4";
|
2018-01-17 08:05:21 +08:00
|
|
|
return "NFP-6xxx";
|
|
|
|
default:
|
|
|
|
p_err("Can't get bfd arch name for device vendor id 0x%04x",
|
|
|
|
vendor_id);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-28 10:39:10 +08:00
|
|
|
void print_dev_plain(__u32 ifindex, __u64 ns_dev, __u64 ns_inode)
|
|
|
|
{
|
|
|
|
char name[IF_NAMESIZE];
|
|
|
|
|
|
|
|
if (!ifindex)
|
|
|
|
return;
|
|
|
|
|
2018-12-01 00:25:47 +08:00
|
|
|
printf(" offloaded_to ");
|
2017-12-28 10:39:10 +08:00
|
|
|
if (ifindex_to_name_ns(ifindex, ns_dev, ns_inode, name))
|
|
|
|
printf("%s", name);
|
|
|
|
else
|
|
|
|
printf("ifindex %u ns_dev %llu ns_ino %llu",
|
|
|
|
ifindex, ns_dev, ns_inode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_dev_json(__u32 ifindex, __u64 ns_dev, __u64 ns_inode)
|
|
|
|
{
|
|
|
|
char name[IF_NAMESIZE];
|
|
|
|
|
|
|
|
if (!ifindex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
jsonw_name(json_wtr, "dev");
|
|
|
|
jsonw_start_object(json_wtr);
|
|
|
|
jsonw_uint_field(json_wtr, "ifindex", ifindex);
|
|
|
|
jsonw_uint_field(json_wtr, "ns_dev", ns_dev);
|
|
|
|
jsonw_uint_field(json_wtr, "ns_inode", ns_inode);
|
|
|
|
if (ifindex_to_name_ns(ifindex, ns_dev, ns_inode, name))
|
|
|
|
jsonw_string_field(json_wtr, "ifname", name);
|
|
|
|
jsonw_end_object(json_wtr);
|
|
|
|
}
|
2018-10-16 07:30:36 +08:00
|
|
|
|
|
|
|
int parse_u32_arg(int *argc, char ***argv, __u32 *val, const char *what)
|
|
|
|
{
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
if (*val) {
|
|
|
|
p_err("%s already specified", what);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*val = strtoul(**argv, &endptr, 0);
|
|
|
|
if (*endptr) {
|
|
|
|
p_err("can't parse %s as %s", **argv, what);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
tools: bpftool: Restore message on failure to guess program type
In commit 4a3d6c6a6e4d ("libbpf: Reduce log level for custom section
names"), log level for messages for libbpf_attach_type_by_name() and
libbpf_prog_type_by_name() was downgraded from "info" to "debug". The
latter function, in particular, is used by bpftool when attempting to
load programs, and this change caused bpftool to exit with no hint or
error message when it fails to detect the type of the program to load
(unless "-d" option was provided).
To help users understand why bpftool fails to load the program, let's do
a second run of the function with log level in "debug" mode in case of
failure.
Before:
# bpftool prog load sample_ret0.o /sys/fs/bpf/sample_ret0
# echo $?
255
Or really verbose with -d flag:
# bpftool -d prog load sample_ret0.o /sys/fs/bpf/sample_ret0
libbpf: loading sample_ret0.o
libbpf: section(1) .strtab, size 134, link 0, flags 0, type=3
libbpf: skip section(1) .strtab
libbpf: section(2) .text, size 16, link 0, flags 6, type=1
libbpf: found program .text
libbpf: section(3) .debug_abbrev, size 55, link 0, flags 0, type=1
libbpf: skip section(3) .debug_abbrev
libbpf: section(4) .debug_info, size 75, link 0, flags 0, type=1
libbpf: skip section(4) .debug_info
libbpf: section(5) .rel.debug_info, size 32, link 14, flags 0, type=9
libbpf: skip relo .rel.debug_info(5) for section(4)
libbpf: section(6) .debug_str, size 150, link 0, flags 30, type=1
libbpf: skip section(6) .debug_str
libbpf: section(7) .BTF, size 155, link 0, flags 0, type=1
libbpf: section(8) .BTF.ext, size 80, link 0, flags 0, type=1
libbpf: section(9) .rel.BTF.ext, size 32, link 14, flags 0, type=9
libbpf: skip relo .rel.BTF.ext(9) for section(8)
libbpf: section(10) .debug_frame, size 40, link 0, flags 0, type=1
libbpf: skip section(10) .debug_frame
libbpf: section(11) .rel.debug_frame, size 16, link 14, flags 0, type=9
libbpf: skip relo .rel.debug_frame(11) for section(10)
libbpf: section(12) .debug_line, size 74, link 0, flags 0, type=1
libbpf: skip section(12) .debug_line
libbpf: section(13) .rel.debug_line, size 16, link 14, flags 0, type=9
libbpf: skip relo .rel.debug_line(13) for section(12)
libbpf: section(14) .symtab, size 96, link 1, flags 0, type=2
libbpf: looking for externs among 4 symbols...
libbpf: collected 0 externs total
libbpf: failed to guess program type from ELF section '.text'
libbpf: supported section(type) names are: socket sk_reuseport kprobe/ [...]
After:
# bpftool prog load sample_ret0.o /sys/fs/bpf/sample_ret0
libbpf: failed to guess program type from ELF section '.text'
libbpf: supported section(type) names are: socket sk_reuseport kprobe/ [...]
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200311021205.9755-1-quentin@isovalent.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2020-03-11 10:12:05 +08:00
|
|
|
|
|
|
|
int __printf(2, 0)
|
|
|
|
print_all_levels(__maybe_unused enum libbpf_print_level level,
|
|
|
|
const char *format, va_list args)
|
|
|
|
{
|
|
|
|
return vfprintf(stderr, format, args);
|
|
|
|
}
|
2020-06-20 07:16:58 +08:00
|
|
|
|
|
|
|
static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
|
|
|
|
{
|
|
|
|
unsigned int id = 0;
|
|
|
|
int fd, nb_fds = 0;
|
|
|
|
void *tmp;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
struct bpf_prog_info info = {};
|
|
|
|
__u32 len = sizeof(info);
|
|
|
|
|
|
|
|
err = bpf_prog_get_next_id(id, &id);
|
|
|
|
if (err) {
|
|
|
|
if (errno != ENOENT) {
|
|
|
|
p_err("%s", strerror(errno));
|
|
|
|
goto err_close_fds;
|
|
|
|
}
|
|
|
|
return nb_fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = bpf_prog_get_fd_by_id(id);
|
|
|
|
if (fd < 0) {
|
|
|
|
p_err("can't get prog by id (%u): %s",
|
|
|
|
id, strerror(errno));
|
|
|
|
goto err_close_fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
|
|
if (err) {
|
|
|
|
p_err("can't get prog info (%u): %s",
|
|
|
|
id, strerror(errno));
|
|
|
|
goto err_close_fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tag && memcmp(nametag, info.tag, BPF_TAG_SIZE)) ||
|
|
|
|
(!tag && strncmp(nametag, info.name, BPF_OBJ_NAME_LEN))) {
|
|
|
|
close(fd);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nb_fds > 0) {
|
|
|
|
tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
|
|
|
|
if (!tmp) {
|
|
|
|
p_err("failed to realloc");
|
|
|
|
goto err_close_fd;
|
|
|
|
}
|
|
|
|
*fds = tmp;
|
|
|
|
}
|
|
|
|
(*fds)[nb_fds++] = fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
err_close_fd:
|
|
|
|
close(fd);
|
|
|
|
err_close_fds:
|
|
|
|
while (--nb_fds >= 0)
|
|
|
|
close((*fds)[nb_fds]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int prog_parse_fds(int *argc, char ***argv, int **fds)
|
|
|
|
{
|
|
|
|
if (is_prefix(**argv, "id")) {
|
|
|
|
unsigned int id;
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
id = strtoul(**argv, &endptr, 0);
|
|
|
|
if (*endptr) {
|
|
|
|
p_err("can't parse %s as ID", **argv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
(*fds)[0] = bpf_prog_get_fd_by_id(id);
|
|
|
|
if ((*fds)[0] < 0) {
|
|
|
|
p_err("get by id (%u): %s", id, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
} else if (is_prefix(**argv, "tag")) {
|
|
|
|
unsigned char tag[BPF_TAG_SIZE];
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
if (sscanf(**argv, BPF_TAG_FMT, tag, tag + 1, tag + 2,
|
|
|
|
tag + 3, tag + 4, tag + 5, tag + 6, tag + 7)
|
|
|
|
!= BPF_TAG_SIZE) {
|
|
|
|
p_err("can't parse tag");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
return prog_fd_by_nametag(tag, fds, true);
|
|
|
|
} else if (is_prefix(**argv, "name")) {
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
name = **argv;
|
|
|
|
if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
|
|
|
|
p_err("can't parse name");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
return prog_fd_by_nametag(name, fds, false);
|
|
|
|
} else if (is_prefix(**argv, "pinned")) {
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
path = **argv;
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
(*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_PROG);
|
|
|
|
if ((*fds)[0] < 0)
|
|
|
|
return -1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int prog_parse_fd(int *argc, char ***argv)
|
|
|
|
{
|
|
|
|
int *fds = NULL;
|
|
|
|
int nb_fds, fd;
|
|
|
|
|
|
|
|
fds = malloc(sizeof(int));
|
|
|
|
if (!fds) {
|
|
|
|
p_err("mem alloc failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
nb_fds = prog_parse_fds(argc, argv, &fds);
|
|
|
|
if (nb_fds != 1) {
|
|
|
|
if (nb_fds > 1) {
|
|
|
|
p_err("several programs match this handle");
|
|
|
|
while (nb_fds--)
|
|
|
|
close(fds[nb_fds]);
|
|
|
|
}
|
|
|
|
fd = -1;
|
|
|
|
goto exit_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = fds[0];
|
|
|
|
exit_free:
|
|
|
|
free(fds);
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int map_fd_by_name(char *name, int **fds)
|
|
|
|
{
|
|
|
|
unsigned int id = 0;
|
|
|
|
int fd, nb_fds = 0;
|
|
|
|
void *tmp;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
struct bpf_map_info info = {};
|
|
|
|
__u32 len = sizeof(info);
|
|
|
|
|
|
|
|
err = bpf_map_get_next_id(id, &id);
|
|
|
|
if (err) {
|
|
|
|
if (errno != ENOENT) {
|
|
|
|
p_err("%s", strerror(errno));
|
|
|
|
goto err_close_fds;
|
|
|
|
}
|
|
|
|
return nb_fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = bpf_map_get_fd_by_id(id);
|
|
|
|
if (fd < 0) {
|
|
|
|
p_err("can't get map by id (%u): %s",
|
|
|
|
id, strerror(errno));
|
|
|
|
goto err_close_fds;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, &info, &len);
|
|
|
|
if (err) {
|
|
|
|
p_err("can't get map info (%u): %s",
|
|
|
|
id, strerror(errno));
|
|
|
|
goto err_close_fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp(name, info.name, BPF_OBJ_NAME_LEN)) {
|
|
|
|
close(fd);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nb_fds > 0) {
|
|
|
|
tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
|
|
|
|
if (!tmp) {
|
|
|
|
p_err("failed to realloc");
|
|
|
|
goto err_close_fd;
|
|
|
|
}
|
|
|
|
*fds = tmp;
|
|
|
|
}
|
|
|
|
(*fds)[nb_fds++] = fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
err_close_fd:
|
|
|
|
close(fd);
|
|
|
|
err_close_fds:
|
|
|
|
while (--nb_fds >= 0)
|
|
|
|
close((*fds)[nb_fds]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int map_parse_fds(int *argc, char ***argv, int **fds)
|
|
|
|
{
|
|
|
|
if (is_prefix(**argv, "id")) {
|
|
|
|
unsigned int id;
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
id = strtoul(**argv, &endptr, 0);
|
|
|
|
if (*endptr) {
|
|
|
|
p_err("can't parse %s as ID", **argv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
(*fds)[0] = bpf_map_get_fd_by_id(id);
|
|
|
|
if ((*fds)[0] < 0) {
|
|
|
|
p_err("get map by id (%u): %s", id, strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
} else if (is_prefix(**argv, "name")) {
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
name = **argv;
|
|
|
|
if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
|
|
|
|
p_err("can't parse name");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
return map_fd_by_name(name, fds);
|
|
|
|
} else if (is_prefix(**argv, "pinned")) {
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
path = **argv;
|
|
|
|
NEXT_ARGP();
|
|
|
|
|
|
|
|
(*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_MAP);
|
|
|
|
if ((*fds)[0] < 0)
|
|
|
|
return -1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
p_err("expected 'id', 'name' or 'pinned', got: '%s'?", **argv);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int map_parse_fd(int *argc, char ***argv)
|
|
|
|
{
|
|
|
|
int *fds = NULL;
|
|
|
|
int nb_fds, fd;
|
|
|
|
|
|
|
|
fds = malloc(sizeof(int));
|
|
|
|
if (!fds) {
|
|
|
|
p_err("mem alloc failed");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
nb_fds = map_parse_fds(argc, argv, &fds);
|
|
|
|
if (nb_fds != 1) {
|
|
|
|
if (nb_fds > 1) {
|
|
|
|
p_err("several maps match this handle");
|
|
|
|
while (nb_fds--)
|
|
|
|
close(fds[nb_fds]);
|
|
|
|
}
|
|
|
|
fd = -1;
|
|
|
|
goto exit_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = fds[0];
|
|
|
|
exit_free:
|
|
|
|
free(fds);
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = map_parse_fd(argc, argv);
|
|
|
|
if (fd < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
err = bpf_obj_get_info_by_fd(fd, info, info_len);
|
|
|
|
if (err) {
|
|
|
|
p_err("can't get map info: %s", strerror(errno));
|
|
|
|
close(fd);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|
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
2021-10-24 04:51:52 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|