diff --git a/nixos/tests/bpf.nix b/nixos/tests/bpf.nix index 150ed0958862..0020c7ee2d69 100644 --- a/nixos/tests/bpf.nix +++ b/nixos/tests/bpf.nix @@ -16,14 +16,14 @@ import ./make-test-python.nix ({ pkgs, ... }: { # list probes machine.succeed("bpftrace -l") # simple BEGIN probe (user probe on bpftrace itself) - print(machine.succeed("bpftrace -e 'BEGIN { print(\"ok\"); exit(); }'")) + print(machine.succeed("bpftrace -e 'BEGIN { print(\"ok\\n\"); exit(); }'")) # tracepoint print(machine.succeed("bpftrace -e 'tracepoint:syscalls:sys_enter_* { print(probe); exit() }'")) # kprobe print(machine.succeed("bpftrace -e 'kprobe:schedule { print(probe); exit() }'")) # BTF print(machine.succeed("bpftrace -e 'kprobe:schedule { " - " printf(\"tgid: %d\", ((struct task_struct*) curtask)->tgid); exit() " + " printf(\"tgid: %d\\n\", ((struct task_struct*) curtask)->tgid); exit() " "}'")) # module BTF (bpftrace >= 0.17) # test is currently disabled on aarch64 as kfunc does not work there yet @@ -32,5 +32,8 @@ import ./make-test-python.nix ({ pkgs, ... }: { "bpftrace -e 'kfunc:nft_trans_alloc_gfp { " " printf(\"portid: %d\\n\", args->ctx->portid); " "} BEGIN { exit() }'")) + # glibc includes + print(machine.succeed("bpftrace -e '#include \n" + "BEGIN { printf(\"ok %d\\n\", EINVAL); exit(); }'")) ''; }) diff --git a/pkgs/by-name/bp/bpftrace/override-system-headers.patch b/pkgs/by-name/bp/bpftrace/override-system-headers.patch new file mode 100644 index 000000000000..624c4d6c7eff --- /dev/null +++ b/pkgs/by-name/bp/bpftrace/override-system-headers.patch @@ -0,0 +1,94 @@ +From c1737d4ab6ab263932caa9e3ac170ebe3e28d404 Mon Sep 17 00:00:00 2001 +From: Dominique Martinet +Date: Fri, 14 Jun 2024 21:56:46 +0900 +Subject: [PATCH] clang_parser system_include_paths: allow overriding at + compile time + +While bpftrace depends on libclang it can be installed without a clang +frontend, so some distributions might want to make these paths fixed as +they are unlikely to change. + +In particular, this is necessary to include system libraries as used by +older versions of tcpaccept.bt (they now no longer require these since +#3152, but that illustrate this was a recurring problem) + +(cherry picked from commit 5bf5f86313600b16c8c23e03b31337941cbefdd0) +--- + CMakeLists.txt | 2 ++ + src/CMakeLists.txt | 4 +++- + src/clang_parser.cpp | 19 +++++++++++++++---- + 3 files changed, 20 insertions(+), 5 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index cd620d0e56e5..ade33c503efb 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -21,6 +21,8 @@ set(VENDOR_GTEST OFF CACHE BOOL "Clone gtest from github") + set(BUILD_FUZZ OFF CACHE BOOL "Build bpftrace for fuzzing") + set(USE_LIBFUZZER OFF CACHE BOOL "Use libfuzzer for fuzzing") + set(FUZZ_TARGET "codegen" CACHE STRING "Fuzzing target") ++set(KERNEL_HEADERS_DIR "" CACHE PATH "Hard-code kernel headers directory") ++set(SYSTEM_INCLUDE_PATHS "auto" CACHE STRING "Hard-code system include paths (colon separated, the default value \"auto\" queries clang at runtime)") + + set(ENABLE_SKB_OUTPUT ON CACHE BOOL "Enable skb_output, will include libpcap") + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 88f5928c8a75..eadb11207052 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -88,11 +88,13 @@ endif() + + # compile definitions + +-set(KERNEL_HEADERS_DIR "" CACHE PATH "Hard-code kernel headers directory") + if (KERNEL_HEADERS_DIR) + MESSAGE(STATUS "Using KERNEL_HEADERS_DIR=${KERNEL_HEADERS_DIR}") + target_compile_definitions(runtime PUBLIC KERNEL_HEADERS_DIR="${KERNEL_HEADERS_DIR}") + endif() ++if (NOT SYSTEM_INCLUDE_PATHS EQUAL "auto") ++ MESSAGE(STATUS "Using SYSTEM_INCLUDE_PATHS=${SYSTEM_INCLUDE_PATHS}") ++endif() + + execute_process( + COMMAND git describe --abbrev=4 --dirty --tags +diff --git a/src/clang_parser.cpp b/src/clang_parser.cpp +index 8b6689454267..9367e6692eb0 100644 +--- a/src/clang_parser.cpp ++++ b/src/clang_parser.cpp +@@ -882,11 +882,9 @@ std::string ClangParser::get_arch_include_path() + return "/usr/include/" + std::string(utsname.machine) + "-linux-gnu"; + } + +-std::vector ClangParser::system_include_paths() ++static void query_clang_include_dirs(std::vector &result) + { +- std::vector result; +- try +- { ++ try { + auto clang = "clang-" + std::to_string(LLVM_VERSION_MAJOR); + auto cmd = clang + " -Wp,-v -x c -fsyntax-only /dev/null 2>&1"; + auto check = exec_system(cmd.c_str()); +@@ -902,6 +900,19 @@ std::vector ClangParser::system_include_paths() + catch (std::runtime_error &) + { // If exec_system fails, just ignore it + } ++} ++ ++std::vector ClangParser::system_include_paths() ++{ ++ std::vector result; ++ std::istringstream lines(SYSTEM_INCLUDE_PATHS); ++ std::string line; ++ while (std::getline(lines, line, ':')) { ++ if (line == "auto") ++ query_clang_include_dirs(result); ++ else ++ result.push_back(trim(line)); ++ } + + if (result.empty()) + result = { "/usr/local/include", "/usr/include" }; +-- +2.45.2 + diff --git a/pkgs/by-name/bp/bpftrace/package.nix b/pkgs/by-name/bp/bpftrace/package.nix index bc5aab6a9406..8b1eb42d9a2a 100644 --- a/pkgs/by-name/bp/bpftrace/package.nix +++ b/pkgs/by-name/bp/bpftrace/package.nix @@ -1,6 +1,6 @@ { lib, stdenv, fetchFromGitHub , llvmPackages, elfutils, bcc -, libbpf, libbfd, libopcodes +, libbpf, libbfd, libopcodes, glibc , cereal, asciidoctor , cmake, pkg-config, flex, bison , util-linux @@ -41,9 +41,17 @@ stdenv.mkDerivation rec { "-DBUILD_TESTING=FALSE" "-DLIBBCC_INCLUDE_DIRS=${bcc}/include" "-DINSTALL_TOOL_DOCS=OFF" - "-DUSE_SYSTEM_BPF_BCC=ON" + "-DSYSTEM_INCLUDE_PATHS=${glibc.dev}/include" ]; + patches = [ + # https://github.com/bpftrace/bpftrace/pull/3243 (merged) + ./override-system-headers.patch + # https://github.com/bpftrace/bpftrace/pull/3152 (merged) + ./tcp-bt-no-includes.patch + # https://github.com/bpftrace/bpftrace/pull/3262 (merged) + ./runqlat-bt-no-includes.patch + ]; # Pull BPF scripts into $PATH (next to their bcc program equivalents), but do # not move them to keep `${pkgs.bpftrace}/share/bpftrace/tools/...` working. diff --git a/pkgs/by-name/bp/bpftrace/runqlat-bt-no-includes.patch b/pkgs/by-name/bp/bpftrace/runqlat-bt-no-includes.patch new file mode 100644 index 000000000000..659e4bc4bbfd --- /dev/null +++ b/pkgs/by-name/bp/bpftrace/runqlat-bt-no-includes.patch @@ -0,0 +1,45 @@ +From 9b5f22854297aabb924969c25af66461d8d2fcb9 Mon Sep 17 00:00:00 2001 +From: Dominique Martinet +Date: Fri, 21 Jun 2024 21:02:09 +0900 +Subject: [PATCH] tools/runqlat: provide TASK_RUNNING as a define + +runqlat requires kernel headers to run even with BTF, just because of a +define. +TASK_RUNNING isn't part of the stable API but it's never changed in all +of the linux git history so let's pretend it's stable and just define +it. + +If we find a way to handle kheaders again in the future we might want to +consider reverting this. + +Fixes: #3255 +(cherry picked from commit aa041d9d85f9ec11235c39fdcb5833412ec27083) +--- + tools/runqlat.bt | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/tools/runqlat.bt b/tools/runqlat.bt +index 3d71b76062eb..1298f399aee7 100755 +--- a/tools/runqlat.bt ++++ b/tools/runqlat.bt +@@ -11,7 +11,17 @@ + * 17-Sep-2018 Brendan Gregg Created this. + */ + ++#ifndef BPFTRACE_HAVE_BTF + #include ++#else ++/* ++ * With BTF providing types, full headers are not needed. ++ * We only need to supply the preprocessor defines used in this script. ++ * TASK_RUNNING is not arch-dependant and has not changed in the linux ++ * git history (it is not part of the stable API though) ++ */ ++#define TASK_RUNNING 0 ++#endif + + BEGIN + { +-- +2.45.2 + diff --git a/pkgs/by-name/bp/bpftrace/tcp-bt-no-includes.patch b/pkgs/by-name/bp/bpftrace/tcp-bt-no-includes.patch new file mode 100644 index 000000000000..fa2052358103 --- /dev/null +++ b/pkgs/by-name/bp/bpftrace/tcp-bt-no-includes.patch @@ -0,0 +1,114 @@ +From ebb12512f6ea0a1113ad8ddf30db26128f7a3426 Mon Sep 17 00:00:00 2001 +From: Dominique Martinet +Date: Sun, 23 Jun 2024 20:41:01 +0900 +Subject: [PATCH] With BTF, users do not need libc headers installed for + AF_INET/AF_INET6 + +Signed-off-by: Bernhard Kaindl +(cherry picked from commit c0b9d252a43f99b9091245dedb178a6874803306) +--- + tools/tcpaccept.bt | 8 +++++++- + tools/tcpconnect.bt | 8 +++++++- + tools/tcpdrop.bt | 8 +++++++- + tools/tcplife.bt | 8 +++++++- + tools/tcpretrans.bt | 8 +++++++- + 5 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/tools/tcpaccept.bt b/tools/tcpaccept.bt +index 08e6af0158fc..cbffe36889ee 100755 +--- a/tools/tcpaccept.bt ++++ b/tools/tcpaccept.bt +@@ -20,7 +20,13 @@ + #include + #include + #else +-#include ++/* ++ * With BTF providing types, socket headers are not needed. ++ * We only need to supply the preprocessor defines in this script. ++ * AF_INET/AF_INET6 are part of the stable arch-independent Linux ABI ++ */ ++#define AF_INET 2 ++#define AF_INET6 10 + #endif + + BEGIN +diff --git a/tools/tcpconnect.bt b/tools/tcpconnect.bt +index 1ac1eb99e9ad..636337275cd8 100755 +--- a/tools/tcpconnect.bt ++++ b/tools/tcpconnect.bt +@@ -22,7 +22,13 @@ + #include + #include + #else +-#include ++/* ++ * BTF provides the types, we just need to define AF_INET and AF_INET6. ++ * These are Linux ABI defines, and are not architecture-specific. ++ * With BTF, this allows tcpconnect.bt to work without glibc headers: ++ */ ++#define AF_INET 2 /* IPv4 */ ++#define AF_INET6 10 /* IPv6 */ + #endif + + BEGIN +diff --git a/tools/tcpdrop.bt b/tools/tcpdrop.bt +index fd3e55f490bf..a56bf69fcc6c 100755 +--- a/tools/tcpdrop.bt ++++ b/tools/tcpdrop.bt +@@ -24,7 +24,13 @@ + #include + #include + #else +-#include ++/* ++ * With BTF providing types, socket headers are not needed. ++ * We only need to supply the preprocessor defines in this script. ++ * AF_INET/AF_INET6 are part of the stable arch-independent Linux ABI ++ */ ++#define AF_INET 2 ++#define AF_INET6 10 + #endif + + BEGIN +diff --git a/tools/tcplife.bt b/tools/tcplife.bt +index dd4c1d68284e..d5a09c4e5da9 100755 +--- a/tools/tcplife.bt ++++ b/tools/tcplife.bt +@@ -19,7 +19,13 @@ + #include + #include + #else +-#include ++/* ++ * With BTF providing types, socket headers are not needed. ++ * We only need to supply the preprocessor defines in this script. ++ * AF_INET/AF_INET6 are part of the stable arch-independent Linux ABI ++ */ ++#define AF_INET 2 ++#define AF_INET6 10 + #endif + + BEGIN +diff --git a/tools/tcpretrans.bt b/tools/tcpretrans.bt +index ee2975d6e545..32a11bfa81b2 100755 +--- a/tools/tcpretrans.bt ++++ b/tools/tcpretrans.bt +@@ -21,7 +21,13 @@ + #include + #include + #else +-#include ++/* ++ * With BTF providing types, socket headers are not needed. ++ * We only need to supply the preprocessor defines in this script. ++ * AF_INET/AF_INET6 are part of the stable arch-independent Linux ABI ++ */ ++#define AF_INET 2 ++#define AF_INET6 10 + #endif + + BEGIN +-- +2.45.2 +