mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-12-27 04:12:29 +01:00
compile and install bpftool in its own package. bpftool isn't compatible with musl, so a few patches have been added. The patches have been sent upstream here: https://lkml.kernel.org/r/20220424051022.2619648-1-asmadeus@codewreck.org and have already been merged without modification into linux v5.19-rc1
184 lines
4.5 KiB
Diff
184 lines
4.5 KiB
Diff
From 56cbc4a5e7d98901a13d1e662c794133036ba25a Mon Sep 17 00:00:00 2001
|
|
From: Dominique Martinet <asmadeus@codewreck.org>
|
|
Date: Sat, 23 Apr 2022 23:03:11 +0900
|
|
Subject: [PATCH 3/4] tools/bpf: musl compat: replace nftw with
|
|
FTW_ACTIONRETVAL
|
|
|
|
musl nftw implementation does not support FTW_ACTIONRETVAL.
|
|
|
|
There have been multiple attempts at pushing the feature in musl
|
|
upstream but it has been refused or ignored all the times:
|
|
|
|
In this case we only care about /proc/<pid>/fd/<fd>, so it's not
|
|
too difficult to reimplement directly instead, and the new
|
|
implementation makes 'bpftool perf' slightly faster because it doesn't
|
|
needlessly stat/readdir unneeded directories (54ms -> 13ms on my machine)
|
|
|
|
https://www.openwall.com/lists/musl/2021/03/26/1
|
|
https://www.openwall.com/lists/musl/2022/01/22/1
|
|
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
|
|
---
|
|
accepted by upstream without modification, can be dropped after update
|
|
to v5.19 or higher (merged in v5.19-rc1 as
|
|
93bc2e9e943d20a51473a49009db3243de6e098d )
|
|
|
|
tools/bpf/bpftool/perf.c | 116 ++++++++++++++++++++-------------------
|
|
1 file changed, 59 insertions(+), 57 deletions(-)
|
|
|
|
diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
|
|
index 50de087b0db7..de793872544e 100644
|
|
--- a/tools/bpf/bpftool/perf.c
|
|
+++ b/tools/bpf/bpftool/perf.c
|
|
@@ -11,7 +11,7 @@
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
-#include <ftw.h>
|
|
+#include <dirent.h>
|
|
|
|
#include <bpf/bpf.h>
|
|
|
|
@@ -147,81 +147,83 @@ static void print_perf_plain(int pid, int fd, __u32 prog_id, __u32 fd_type,
|
|
}
|
|
}
|
|
|
|
-static int show_proc(const char *fpath, const struct stat *sb,
|
|
- int tflag, struct FTW *ftwbuf)
|
|
+static int show_proc(void)
|
|
{
|
|
__u64 probe_offset, probe_addr;
|
|
__u32 len, prog_id, fd_type;
|
|
- int err, pid = 0, fd = 0;
|
|
+ int err, pid, fd;
|
|
+ DIR *proc, *pid_fd;
|
|
+ struct dirent *proc_de, *pid_fd_de;
|
|
const char *pch;
|
|
char buf[4096];
|
|
|
|
- /* prefix always /proc */
|
|
- pch = fpath + 5;
|
|
- if (*pch == '\0')
|
|
- return 0;
|
|
+ proc = opendir("/proc");
|
|
+ if (!proc)
|
|
+ return -1;
|
|
+ while ((proc_de = readdir(proc))) {
|
|
+ pid = 0;
|
|
+ pch = proc_de->d_name;
|
|
|
|
- /* pid should be all numbers */
|
|
- pch++;
|
|
- while (isdigit(*pch)) {
|
|
- pid = pid * 10 + *pch - '0';
|
|
- pch++;
|
|
+ /* pid should be all numbers */
|
|
+ while (isdigit(*pch)) {
|
|
+ pid = pid * 10 + *pch - '0';
|
|
+ pch++;
|
|
+ }
|
|
+ if (*pch != '\0')
|
|
+ continue;
|
|
+
|
|
+ err = snprintf(buf, sizeof(buf), "/proc/%s/fd", proc_de->d_name);
|
|
+ if (err < 0 || err >= (int)sizeof(buf))
|
|
+ continue;
|
|
+
|
|
+ pid_fd = opendir(buf);
|
|
+ if (!pid_fd)
|
|
+ continue;
|
|
+
|
|
+ while ((pid_fd_de = readdir(pid_fd))) {
|
|
+ fd = 0;
|
|
+ pch = pid_fd_de->d_name;
|
|
+
|
|
+ /* fd should be all numbers */
|
|
+ while (isdigit(*pch)) {
|
|
+ fd = fd * 10 + *pch - '0';
|
|
+ pch++;
|
|
+ }
|
|
+ if (*pch != '\0')
|
|
+ continue;
|
|
+
|
|
+ /* query (pid, fd) for potential perf events */
|
|
+ len = sizeof(buf);
|
|
+ err = bpf_task_fd_query(pid, fd, 0, buf, &len, &prog_id, &fd_type,
|
|
+ &probe_offset, &probe_addr);
|
|
+ if (err < 0)
|
|
+ continue;
|
|
+
|
|
+ if (json_output)
|
|
+ print_perf_json(pid, fd, prog_id, fd_type, buf, probe_offset,
|
|
+ probe_addr);
|
|
+ else
|
|
+ print_perf_plain(pid, fd, prog_id, fd_type, buf, probe_offset,
|
|
+ probe_addr);
|
|
+ }
|
|
+ closedir(pid_fd);
|
|
}
|
|
- if (*pch == '\0')
|
|
- return 0;
|
|
- if (*pch != '/')
|
|
- return FTW_SKIP_SUBTREE;
|
|
-
|
|
- /* check /proc/<pid>/fd directory */
|
|
- pch++;
|
|
- if (strncmp(pch, "fd", 2))
|
|
- return FTW_SKIP_SUBTREE;
|
|
- pch += 2;
|
|
- if (*pch == '\0')
|
|
- return 0;
|
|
- if (*pch != '/')
|
|
- return FTW_SKIP_SUBTREE;
|
|
-
|
|
- /* check /proc/<pid>/fd/<fd_num> */
|
|
- pch++;
|
|
- while (isdigit(*pch)) {
|
|
- fd = fd * 10 + *pch - '0';
|
|
- pch++;
|
|
- }
|
|
- if (*pch != '\0')
|
|
- return FTW_SKIP_SUBTREE;
|
|
-
|
|
- /* query (pid, fd) for potential perf events */
|
|
- len = sizeof(buf);
|
|
- err = bpf_task_fd_query(pid, fd, 0, buf, &len, &prog_id, &fd_type,
|
|
- &probe_offset, &probe_addr);
|
|
- if (err < 0)
|
|
- return 0;
|
|
-
|
|
- if (json_output)
|
|
- print_perf_json(pid, fd, prog_id, fd_type, buf, probe_offset,
|
|
- probe_addr);
|
|
- else
|
|
- print_perf_plain(pid, fd, prog_id, fd_type, buf, probe_offset,
|
|
- probe_addr);
|
|
-
|
|
+ closedir(proc);
|
|
return 0;
|
|
}
|
|
|
|
static int do_show(int argc, char **argv)
|
|
{
|
|
- int flags = FTW_ACTIONRETVAL | FTW_PHYS;
|
|
- int err = 0, nopenfd = 16;
|
|
+ int err;
|
|
|
|
if (!has_perf_query_support())
|
|
return -1;
|
|
|
|
if (json_output)
|
|
jsonw_start_array(json_wtr);
|
|
- if (nftw("/proc", show_proc, nopenfd, flags) == -1) {
|
|
- p_err("%s", strerror(errno));
|
|
- err = -1;
|
|
- }
|
|
+
|
|
+ err = show_proc();
|
|
+
|
|
if (json_output)
|
|
jsonw_end_array(json_wtr);
|
|
|
|
--
|
|
2.35.1
|
|
|