Browse Source

Move libbpf and eBPF CO-RE bundling into CMake. (#17484)

* Move libbpf and eBPF CO-RE bundling into CMake.

* Silence CMP0135 warnings.

* Fix handling of legacy eBPF code.

* Only enable eBPF by default on Linux.

* Correctly auto-detect the need for legacy libbpf.

* Fix include paths for libbpf linking.

* Add coreutils dependency on Alpine.

* Fix ebpf code handling.

* Fix lib path handling for libbpf.a.

* Correctly fix libbpf lib directory handling.

* Use correct comparison type.
Austin S. Hemmelgarn 10 months ago
parent
commit
aa6d30384d

+ 27 - 37
CMakeLists.txt

@@ -2,6 +2,10 @@
 
 cmake_minimum_required(VERSION 3.13.0)
 
+if(POLICY CMP0135)
+    cmake_policy(SET CMP0135 NEW)
+endif()
+
 #
 # version atrocities
 #
@@ -59,6 +63,7 @@ project(netdata
         HOMEPAGE_URL "https://www.netdata.cloud"
         LANGUAGES C CXX)
 list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/packaging/cmake/Modules")
+include(CMakeDependentOption)
 
 find_package(PkgConfig REQUIRED)
 
@@ -133,6 +138,9 @@ option(ENABLE_LOGS_MANAGEMENT_TESTS "enable logs management tests" True)
 option(ENABLE_SENTRY "enable sentry" False)
 option(ENABLE_WEBRTC "enable webrtc" False)
 
+cmake_dependent_option(FORCE_LEGACY_LIBBPF "Force usage of libbpf 0.0.9 instead of the latest version." False "ENABLE_PLUGIN_LIBBPF" False)
+mark_as_advanced(FORCE_LEGACY_LIBBPF)
+
 if(ENABLE_ACLK OR ENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE)
         set(NEED_PROTOBUF True)
 else()
@@ -236,6 +244,18 @@ else()
         add_definitions(-D_GNU_SOURCE)
 endif()
 
+if(ENABLE_PLUGIN_EBPF)
+        include(NetdataLibBPF)
+        include(NetdataEBPFCORE)
+
+        if(NOT LINUX)
+            message(FATAL_ERROR "The eBPF plugin is not supported on non-Linux systems")
+        endif()
+
+        netdata_bundle_libbpf()
+        netdata_fetch_ebpf_co_re()
+endif()
+
 #
 # Libm
 #
@@ -657,17 +677,10 @@ set(LIBNETDATA_FILES
 )
 
 if(ENABLE_PLUGIN_EBPF)
-        message(CHECK_START "Checking for vendored libbpf for eBPF plugin")
-        if (EXISTS "${CMAKE_SOURCE_DIR}/externaldeps/libbpf/libbpf.a" AND EXISTS "${CMAKE_SOURCE_DIR}/src/libnetdata/ebpf/includes/dc.skel.h")
-                message(CHECK_PASS "found")
-                list(APPEND LIBNETDATA_FILES
-                     src/libnetdata/ebpf/ebpf.c
-                     src/libnetdata/ebpf/ebpf.h
-                )
-        else()
-                message(CHECK_FAIL "not found")
-                message(FATAL_ERROR "eBPF plugin requires a vendored copy of libbpf.")
-        endif()
+        list(APPEND LIBNETDATA_FILES
+                src/libnetdata/ebpf/ebpf.c
+                src/libnetdata/ebpf/ebpf.h
+        )
 endif()
 
 set(LIBH2O_FILES
@@ -1502,16 +1515,7 @@ target_link_libraries(libnetdata PUBLIC
 
 # ebpf
 if(ENABLE_PLUGIN_EBPF)
-        target_link_libraries(libnetdata PUBLIC ${CMAKE_SOURCE_DIR}/externaldeps/libbpf/libbpf.a)
-        target_include_directories(libnetdata BEFORE PUBLIC
-                ${CMAKE_SOURCE_DIR}/externaldeps/libbpf/include
-                ${CMAKE_SOURCE_DIR}/externaldeps/libbpf/include/uapi
-        )
-
-        pkg_check_modules(ELF REQUIRED libelf)
-        target_include_directories(libnetdata BEFORE PUBLIC ${ELF_INCLUDE_DIRS})
-        target_compile_options(libnetdata PUBLIC ${ELF_CFLAGS_OTHER})
-        target_link_libraries(libnetdata PUBLIC ${ELF_LIBRARIES})
+        netdata_add_libbpf_to_target(libnetdata)
 endif()
 
 # judy
@@ -1907,27 +1911,13 @@ if(ENABLE_PLUGIN_EBPF)
             src/collectors/ebpf.plugin/ebpf_unittest.h
             src/collectors/ebpf.plugin/ebpf_functions.c
             src/collectors/ebpf.plugin/ebpf_functions.h
-            src/libnetdata/ebpf/includes/cachestat.skel.h
-            src/libnetdata/ebpf/includes/dc.skel.h
-            src/libnetdata/ebpf/includes/disk.skel.h
-            src/libnetdata/ebpf/includes/fd.skel.h
-            src/libnetdata/ebpf/includes/filesystem.skel.h
-            src/libnetdata/ebpf/includes/hardirq.skel.h
-            src/libnetdata/ebpf/includes/mdflush.skel.h
-            src/libnetdata/ebpf/includes/mount.skel.h
-            src/libnetdata/ebpf/includes/oomkill.skel.h
-            src/libnetdata/ebpf/includes/process.skel.h
-            src/libnetdata/ebpf/includes/shm.skel.h
-            src/libnetdata/ebpf/includes/socket.skel.h
-            src/libnetdata/ebpf/includes/softirq.skel.h
-            src/libnetdata/ebpf/includes/swap.skel.h
-            src/libnetdata/ebpf/includes/sync.skel.h
-            src/libnetdata/ebpf/includes/vfs.skel.h
     )
 
     add_executable(ebpf.plugin ${EBPF_PLUGIN_FILES})
     target_link_libraries(ebpf.plugin libnetdata)
 
+    netdata_add_ebpf_co_re_to_target(ebpf.plugin)
+
     install(TARGETS ebpf.plugin
             COMPONENT ebpf_plugin
             DESTINATION usr/libexec/netdata/plugins.d)

+ 0 - 4
contrib/debian/rules

@@ -64,10 +64,6 @@ override_dh_installinit:
 	dh_installinit
 
 override_dh_auto_configure:
-	if [ $(HAVE_EBPF) -eq 1 ]; then \
-		packaging/bundle-libbpf.sh . ${TOP}/usr/libexec/netdata/plugins.d; \
-		packaging/bundle-ebpf-co-re.sh . ${TOP}/usr/libexec/netdata/plugins.d; \
-	fi
 	dh_auto_configure -- -G Ninja \
 		-DCMAKE_BUILD_TYPE=RelWithDebInfo \
 		-DCMAKE_INSTALL_PREFIX=/ \

+ 39 - 209
netdata-installer.sh

@@ -245,13 +245,16 @@ USAGE: ${PROGRAM} [options]
 HEREDOC
 }
 
+if [ "$(uname -s)" = "Linux" ]; then
+    ENABLE_EBPF=1
+fi
+
 DONOTSTART=0
 DONOTWAIT=0
 NETDATA_PREFIX=
 LIBS_ARE_HERE=0
 NETDATA_ENABLE_ML=""
 ENABLE_DBENGINE=1
-ENABLE_EBPF=1
 ENABLE_GO=1
 ENABLE_H2O=1
 ENABLE_CLOUD=1
@@ -323,14 +326,8 @@ while [ -n "${1}" ]; do
       # XXX: No longer supported.
       ;;
     "--disable-telemetry") NETDATA_DISABLE_TELEMETRY=1 ;;
-    "--enable-ebpf")
-      ENABLE_EBPF=1
-      NETDATA_DISABLE_EBPF=0
-      ;;
-    "--disable-ebpf")
-      ENABLE_EBPF=0
-      NETDATA_DISABLE_EBPF=1
-      ;;
+    "--enable-ebpf") ENABLE_EBPF=1 ;;
+    "--disable-ebpf") ENABLE_EBPF=0 ;;
     "--skip-available-ram-check") SKIP_RAM_CHECK=1 ;;
     "--one-time-build")
       # XXX: No longer supported
@@ -556,199 +553,6 @@ fi
 
 trap build_error EXIT
 
-# -----------------------------------------------------------------------------
-
-get_kernel_version() {
-  r="$(uname -r | cut -f 1 -d '-')"
-
-  tmpfile="$(mktemp)"
-  echo "${r}" | tr '.' ' ' > "${tmpfile}"
-
-  read -r maj min patch _ < "${tmpfile}"
-
-  rm -f "${tmpfile}"
-
-  printf "%03d%03d%03d" "${maj}" "${min}" "${patch}"
-}
-
-detect_libc() {
-  libc=
-  if ldd --version 2>&1 | grep -q -i glibc; then
-    echo >&2 " Detected GLIBC"
-    libc="glibc"
-  elif ldd --version 2>&1 | grep -q -i 'gnu libc'; then
-    echo >&2 " Detected GLIBC"
-    libc="glibc"
-  elif ldd --version 2>&1 | grep -q -i musl; then
-    echo >&2 " Detected musl"
-    libc="musl"
-  else
-      cmd=$(ldd /bin/sh | grep -w libc | cut -d" " -f 3)
-      if bash -c "${cmd}" 2>&1 | grep -q -i "GNU C Library"; then
-        echo >&2 " Detected GLIBC"
-        libc="glibc"
-      fi
-  fi
-
-  if [ -z "$libc" ]; then
-    warning "Cannot detect a supported libc on your system, eBPF support will be disabled."
-    return 1
-  fi
-
-  echo "${libc}"
-  return 0
-}
-
-build_libbpf() {
-  cd "${1}/src" > /dev/null || return 1
-  mkdir root build
-  # shellcheck disable=SC2086
-  run env CFLAGS='-fPIC -pipe' CXXFLAGS='-fPIC -pipe' LDFLAGS= BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=.. ${make} ${MAKEOPTS} install
-  cd - > /dev/null || return 1
-}
-
-copy_libbpf() {
-  target_dir="${PWD}/externaldeps/libbpf"
-
-  if [ "$(uname -m)" = x86_64 ]; then
-    lib_subdir="lib64"
-  else
-    lib_subdir="lib"
-  fi
-
-  run mkdir -p "${target_dir}" || return 1
-
-  run cp "${1}/usr/${lib_subdir}/libbpf.a" "${target_dir}/libbpf.a" || return 1
-  run cp -r "${1}/usr/include" "${target_dir}" || return 1
-  run cp -r "${1}/include/uapi" "${target_dir}/include" || return 1
-}
-
-bundle_libbpf() {
-  if { [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 1 ]; } || [ "$(uname -s)" != Linux ]; then
-    ENABLE_EBPF=0
-    NETDATA_DISABLE_EBPF=1
-    return 0
-  fi
-
-  if [ -z "${make}" ]; then
-    warning "No usable copy of Make found, which is required to bundle libbpf. Disabling eBPF support."
-    ENABLE_EBPF=0
-    NETDATA_DISABLE_EBPF=1
-    return 0
-  fi
-
-  # When libc is not detected, we do not have necessity to compile libbpf and we should not do download of eBPF programs
-  libc="${EBPF_LIBC:-"$(detect_libc)"}"
-  if [ -z "$libc" ]; then
-    NETDATA_DISABLE_EBPF=1
-    ENABLE_EBPF=0
-    return 0
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling libbpf."
-
-  progress "Prepare libbpf"
-
-  if [ "$(get_kernel_version)" -ge "004014000" ]; then
-    LIBBPF_PACKAGE_VERSION="$(cat packaging/current_libbpf.version)"
-    LIBBPF_PACKAGE_COMPONENT="current_libbpf"
-  else
-    LIBBPF_PACKAGE_VERSION="$(cat packaging/libbpf_0_0_9.version)"
-    LIBBPF_PACKAGE_COMPONENT="libbpf_0_0_9"
-  fi
-
-  tmp="$(mktemp -d -t netdata-libbpf-XXXXXX)"
-  LIBBPF_PACKAGE_BASENAME="v${LIBBPF_PACKAGE_VERSION}.tar.gz"
-
-  if fetch_and_verify "${LIBBPF_PACKAGE_COMPONENT}" \
-    "https://github.com/netdata/libbpf/archive/${LIBBPF_PACKAGE_BASENAME}" \
-    "${LIBBPF_PACKAGE_BASENAME}" \
-    "${tmp}" \
-    "${NETDATA_LOCAL_TARBALL_OVERRIDE_LIBBPF}"; then
-    if run tar --no-same-owner -xf "${tmp}/${LIBBPF_PACKAGE_BASENAME}" -C "${tmp}" &&
-      build_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" &&
-      copy_libbpf "${tmp}/libbpf-${LIBBPF_PACKAGE_VERSION}" &&
-      rm -rf "${tmp}"; then
-      run_ok "libbpf built and prepared."
-      ENABLE_EBPF=1
-    else
-      if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 0 ]; then
-        fatal "failed to build libbpf." I0005
-      else
-        run_failed "Failed to build libbpf. eBPF support will be disabled"
-        ENABLE_EBPF=0
-        NETDATA_DISABLE_EBPF=1
-      fi
-    fi
-  else
-    if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 0 ]; then
-      fatal "Failed to fetch sources for libbpf." I0006
-    else
-      run_failed "Unable to fetch sources for libbpf. eBPF support will be disabled"
-      ENABLE_EBPF=0
-      NETDATA_DISABLE_EBPF=1
-    fi
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-}
-
-bundle_libbpf
-
-copy_co_re() {
-  cp -R "${1}/includes" "src/libnetdata/ebpf/"
-}
-
-bundle_ebpf_co_re() {
-  if { [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 1 ]; } || [ "$(uname -s)" != Linux ]; then
-    return 0
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling libbpf."
-
-  progress "eBPF CO-RE"
-
-  CORE_PACKAGE_VERSION="$(cat packaging/ebpf-co-re.version)"
-
-  tmp="$(mktemp -d -t netdata-ebpf-co-re-XXXXXX)"
-  CORE_PACKAGE_BASENAME="netdata-ebpf-co-re-glibc-${CORE_PACKAGE_VERSION}.tar.xz"
-
-  if fetch_and_verify "ebpf-co-re" \
-    "https://github.com/netdata/ebpf-co-re/releases/download/${CORE_PACKAGE_VERSION}/${CORE_PACKAGE_BASENAME}" \
-    "${CORE_PACKAGE_BASENAME}" \
-    "${tmp}" \
-    "${NETDATA_LOCAL_TARBALL_OVERRIDE_CORE}"; then
-    if run tar --no-same-owner -xf "${tmp}/${CORE_PACKAGE_BASENAME}" -C "${tmp}" &&
-      copy_co_re "${tmp}" &&
-      rm -rf "${tmp}"; then
-      run_ok "libbpf built and prepared."
-      ENABLE_EBPF=1
-    else
-      if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 0 ]; then
-        fatal "Failed to get eBPF CO-RE files." I0007
-      else
-        run_failed "Failed to get eBPF CO-RE files. eBPF support will be disabled"
-        NETDATA_DISABLE_EBPF=1
-        ENABLE_EBPF=0
-        enable_feature PLUGIN_EBPF 0
-      fi
-    fi
-  else
-    if [ -n "${NETDATA_DISABLE_EBPF}" ] && [ "${NETDATA_DISABLE_EBPF}" = 0 ]; then
-      fatal "Failed to fetch eBPF CO-RE files." I0008
-    else
-      run_failed "Failed to fetch eBPF CO-RE files. eBPF support will be disabled"
-      NETDATA_DISABLE_EBPF=1
-      ENABLE_EBPF=0
-      enable_feature PLUGIN_EBPF 0
-    fi
-  fi
-
-  [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
-}
-
-bundle_ebpf_co_re
-
 # -----------------------------------------------------------------------------
 build_fluentbit() {
   env_cmd="env CFLAGS='-w' CXXFLAGS='-w' LDFLAGS="
@@ -1249,15 +1053,41 @@ fi
 
 [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
 
+detect_libc() {
+  libc=
+  if ldd --version 2>&1 | grep -q -i glibc; then
+    echo >&2 " Detected GLIBC"
+    libc="glibc"
+  elif ldd --version 2>&1 | grep -q -i 'gnu libc'; then
+    echo >&2 " Detected GLIBC"
+    libc="glibc"
+  elif ldd --version 2>&1 | grep -q -i musl; then
+    echo >&2 " Detected musl"
+    libc="musl"
+  else
+      cmd=$(ldd /bin/sh | grep -w libc | cut -d" " -f 3)
+      if bash -c "${cmd}" 2>&1 | grep -q -i "GNU C Library"; then
+        echo >&2 " Detected GLIBC"
+        libc="glibc"
+      fi
+  fi
+
+  if [ -z "$libc" ]; then
+    warning "Cannot detect a supported libc on your system, eBPF support will be disabled."
+    return 1
+  fi
+
+  echo "${libc}"
+}
+
 should_install_ebpf() {
-  if [ "${NETDATA_DISABLE_EBPF:=0}" -eq 1 ]; then
-    run_failed "eBPF has been explicitly disabled, it will not be available in this install."
+  if [ "${ENABLE_EBPF:-0}" -eq 0 ]; then
     return 1
   fi
 
-  if [ "$(uname -s)" != "Linux" ] || [ "$(uname -m)" != "x86_64" ]; then
-    if [ "${NETDATA_DISABLE_EBPF:=1}" -eq 0 ]; then
-      run_failed "Currently eBPF is only supported on Linux on X86_64."
+  if [ "$(uname -m)" != "x86_64" ]; then
+    if [ "${ENABLE_EBPF:-0}" -eq 1 ]; then
+      run_failed "Currently eBPF is only supported on Linux on x86_64."
     fi
 
     return 1
@@ -1328,10 +1158,10 @@ install_ebpf() {
 
   remove_old_ebpf
 
-  progress "Installing eBPF plugin"
+  progress "Installing eBPF programs"
 
   # Detect libc
-  libc="${EBPF_LIBC:-"$(detect_libc)"}"
+  libc="$(detect_libc)"
 
   EBPF_VERSION="$(cat packaging/ebpf.version)"
   EBPF_TARBALL="netdata-kernel-collector-${libc}-${EBPF_VERSION}.tar.xz"

+ 0 - 14
netdata.spec.in

@@ -315,20 +315,6 @@ happened, on your systems and applications.
 
 %prep
 %setup -q -n "%{name}-%{version}"
-%if 0%{?_have_ebpf}
-%if 0%{?centos_ver:1}
-%if %{centos_ver} < 8
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} centos7
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version}
-%else
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} centos8
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version}
-%endif
-%else
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-libbpf.sh ${RPM_BUILD_DIR}/%{name}-%{version} other
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-ebpf-co-re.sh ${RPM_BUILD_DIR}/%{name}-%{version}
-%endif
-%endif
 
 %build
 # Conf step

+ 0 - 9
packaging/bundle-ebpf-co-re.sh

@@ -1,9 +0,0 @@
-#!/bin/sh
-
-SRCDIR="${1}"
-
-CORE_VERSION="$(cat "${SRCDIR}/packaging/ebpf-co-re.version")"
-CORE_TARBALL="netdata-ebpf-co-re-glibc-${CORE_VERSION}.tar.xz"
-curl -sSL --connect-timeout 10 --retry 3 "https://github.com/netdata/ebpf-co-re/releases/download/${CORE_VERSION}/${CORE_TARBALL}" > "${CORE_TARBALL}" || exit 1
-grep "${CORE_TARBALL}" "${SRCDIR}/packaging/ebpf-co-re.checksums" | sha256sum -c - || exit 1
-tar -xa --no-same-owner -f "${CORE_TARBALL}" -C "${SRCDIR}/src/libnetdata/ebpf" || exit 1

+ 0 - 27
packaging/bundle-libbpf.sh

@@ -1,27 +0,0 @@
-#!/bin/bash
-
-if [ "$(uname -m)" = x86_64 ]; then
-    lib_subdir="lib64"
-else
-    lib_subdir="lib"
-fi
-
-if [ "${2}" != "centos7" ]; then
-  cp "${1}/packaging/current_libbpf.checksums" "${1}/packaging/libbpf.checksums"
-  cp "${1}/packaging/current_libbpf.version" "${1}/packaging/libbpf.version"
-else
-  cp "${1}/packaging/libbpf_0_0_9.checksums" "${1}/packaging/libbpf.checksums"
-  cp "${1}/packaging/libbpf_0_0_9.version" "${1}/packaging/libbpf.version"
-fi
-
-LIBBPF_TARBALL="v$(cat "${1}/packaging/libbpf.version").tar.gz"
-LIBBPF_BUILD_PATH="${1}/externaldeps/libbpf/libbpf-$(cat "${1}/packaging/libbpf.version")"
-
-mkdir -p "${1}/externaldeps/libbpf" || exit 1
-curl -sSL --connect-timeout 10 --retry 3 "https://github.com/netdata/libbpf/archive/${LIBBPF_TARBALL}" > "${LIBBPF_TARBALL}" || exit 1
-sha256sum -c "${1}/packaging/libbpf.checksums" || exit 1
-tar -xz --no-same-owner -f "${LIBBPF_TARBALL}" -C "${1}/externaldeps/libbpf" || exit 1
-make -C "${LIBBPF_BUILD_PATH}/src" BUILD_STATIC_ONLY=1 OBJDIR=build/ DESTDIR=../ install || exit 1
-cp -r "${LIBBPF_BUILD_PATH}/usr/${lib_subdir}/libbpf.a" "${1}/externaldeps/libbpf" || exit 1
-cp -r "${LIBBPF_BUILD_PATH}/usr/include" "${1}/externaldeps/libbpf" || exit 1
-cp -r "${LIBBPF_BUILD_PATH}/include/uapi" "${1}/externaldeps/libbpf/include" || exit 1

+ 27 - 0
packaging/cmake/Modules/NetdataEBPFCORE.cmake

@@ -0,0 +1,27 @@
+# Handling for eBPF CO-RE files
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include(ExternalProject)
+
+set(ebpf-co-re_SOURCE_DIR "${CMAKE_BINARY_DIR}/ebpf-co-re")
+
+# Fetch and install our eBPF CO-RE files
+function(netdata_fetch_ebpf_co_re)
+    ExternalProject_Add(
+        ebpf-co-re
+        URL https://github.com/netdata/ebpf-co-re/releases/download/v1.4.0/netdata-ebpf-co-re-glibc-v1.4.0.tar.xz
+        URL_HASH SHA256=e2283d6e78961c18e964666ee3468492a28454c9e60945027516bdd45e3f4395
+        SOURCE_DIR "${ebpf-co-re_SOURCE_DIR}"
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND ""
+        INSTALL_COMMAND ""
+        EXCLUDE_FROM_ALL 1
+    )
+endfunction()
+
+function(netdata_add_ebpf_co_re_to_target _target)
+        add_dependencies(${_target} ebpf-co-re)
+        target_include_directories(${_target} BEFORE PRIVATE "${ebpf-co-re_SOURCE_DIR}")
+endfunction()

+ 125 - 0
packaging/cmake/Modules/NetdataLibBPF.cmake

@@ -0,0 +1,125 @@
+# Handling for libbpf (used by the eBPF plugin)
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include(ExternalProject)
+include(NetdataUtil)
+
+set(libbpf_SOURCE_DIR "${CMAKE_BINARY_DIR}/libbpf")
+
+# Check what libc we're using.
+#
+# Sets the specified variable to the name of the libc or "unknown"
+function(netdata_identify_libc _libc_name)
+    message(INFO "Detecting libc implementation")
+
+    execute_process(COMMAND ldd --version
+                    COMMAND grep -q -i -E "glibc|gnu libc"
+                    RESULT_VARIABLE LDD_IS_GLIBC
+                    OUTPUT_VARIABLE LDD_OUTPUT
+                    ERROR_VARIABLE LDD_OUTPUT)
+
+    if(LDD_IS_GLIBC)
+        set(${_libc_name} glibc PARENT_SCOPE)
+        return()
+    endif()
+
+    execute_process(COMMAND ldd --version
+                    COMMAND grep -q -i -E "musl"
+                    RESULT_VARIABLE LDD_IS_MUSL
+                    OUTPUT_VARIABLE LDD_OUTPUT
+                    ERROR_VARIABLE LDD_OUTPUT)
+
+    if(LDD_IS_MUSL)
+        set(${_libc_name} musl PARENT_SCOPE)
+        return()
+    endif()
+
+    set(${_libc_name} unknown PARENT_SCOPE)
+endfunction()
+
+# Check if the kernel is old enough that we need to use a legacy copy of eBPF.
+function(_need_legacy_libbpf _var)
+    if(FORCE_LEGACY_LIBBPF)
+        set(${_var} TRUE PARENT_SCOPE)
+        return()
+    endif()
+
+    netdata_detect_host_kernel_version()
+
+    if(HOST_KERNEL_VERSION VERSION_LESS "4.14.0")
+        set(${_var} TRUE PARENT_SCOPE)
+    else()
+        set(${_var} FALSE PARENT_SCOPE)
+    endif()
+endfunction()
+
+# Prepare a vendored copy of libbpf
+function(netdata_bundle_libbpf)
+    _need_legacy_libbpf(USE_LEGACY_LIBBPF)
+
+    if(USE_LEGACY_LIBBPF)
+        set(_libbpf_tag 673424c56127bb556e64095f41fd60c26f9083ec) # v0.0.9_netdata-1
+    else()
+        set(_libbpf_tag b981a3a138e3a30024e4e143d62cff2dc307121e) # v1.4.0p_netdata
+    endif()
+
+    netdata_identify_libc(_libc)
+
+    string(REGEX MATCH "glibc|musl" _libc_supported "${_libc}")
+
+    if(NOT _libc_supported)
+        message(FATAL_ERROR "This system’s libc (detected: ${_libc}) is not not supported by the eBPF plugin.")
+    endif()
+
+    find_program(MAKE_COMMAND make)
+
+    if(MAKE_COMMAND STREQUAL MAKE_COMMAND-NOTFOUND)
+        message(FATAL_ERROR "GNU Make is required when building the eBPF plugin, but could not be found.")
+    endif()
+
+    pkg_check_modules(ELF REQUIRED libelf)
+    pkg_check_modules(ZLIB REQUIRED zlib)
+
+    set(_libbpf_lib_dir lib)
+
+    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+        set(_libbpf_lib_dir lib64)
+    endif()
+
+    set(_libbpf_library "${libbpf_SOURCE_DIR}/usr/${_libbpf_lib_dir}/libbpf.a")
+
+    ExternalProject_Add(
+        libbpf
+        GIT_REPOSITORY https://github.com/netdata/libbpf.git
+        GIT_TAG ${_libbpf_tag}
+        SOURCE_DIR "${libbpf_SOURCE_DIR}"
+        CONFIGURE_COMMAND ""
+        BUILD_COMMAND ${MAKE_COMMAND} -C src BUILD_STATIC_ONLY=1 OBJDIR=build/ DESTDIR=../ install
+        BUILD_IN_SOURCE 1
+        BUILD_BYPRODUCTS "${_libbpf_library}"
+        INSTALL_COMMAND ""
+        EXCLUDE_FROM_ALL 1
+    )
+
+    add_library(libbpf_library STATIC IMPORTED GLOBAL)
+    set_property(
+        TARGET libbpf_library
+        PROPERTY IMPORTED_LOCATION "${_libbpf_library}"
+    )
+    set_property(
+        TARGET libbpf_library
+        PROPERTY INTERFACE_LINK_LIBRARIES "${ELF_LIBRARIES};${ZLIB_LIBRARIES}"
+    )
+    set(NETDATA_LIBBPF_INCLUDE_DIRECTORIES "${libbpf_SOURCE_DIR}/usr/include;${libbpf_SOURCE_DIR}/include;${ELF_INCLUDE_DIRECTORIES};${ZLIB_INCLUDE_DIRECTORIES}" PARENT_SCOPE)
+    set(NETDATA_LIBBPF_COMPILE_DEFINITIONS "${ELF_CFLAGS_OTHER};${ZLIB_CFLAGS_OTHER}" PARENT_SCOPE)
+endfunction()
+
+# Add libbpf as a link dependency for the given target.
+function(netdata_add_libbpf_to_target _target)
+    target_link_libraries(${_target} PUBLIC libbpf_library)
+    target_include_directories(${_target} BEFORE PUBLIC "${NETDATA_LIBBPF_INCLUDE_DIRECTORIES}")
+    target_compile_definitions(${_target} PUBLIC "${NETDATA_LIBBPF_COMPILE_DEFINITIONS}")
+    add_dependencies(${_target} libbpf)
+endfunction()

+ 34 - 0
packaging/cmake/Modules/NetdataUtil.cmake

@@ -0,0 +1,34 @@
+# Utility functions used by other modules.
+#
+# Copyright (c) 2024 Netdata Inc.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+include_guard()
+
+# Determine the version of the host kernel.
+#
+# Only works on UNIX-like systems, stores the version in the cache
+# variable HOST_KERNEL_VERSION.
+function(netdata_detect_host_kernel_version)
+    if(DEFINED HOST_KERNEL_VERSION)
+        if(NOT DEFINED CACHE HOST_KERNEL_VERSION)
+            message(STATUS "Using user supplied kernel version (${HOST_KERNEL_VERSION}) instead of detecting it.")
+        endif()
+    endif()
+
+    message(CHECK_START "Determining host kernel version")
+
+    execute_process(COMMAND uname -r
+                    RESULT_VARIABLE _uname_result
+                    OUTPUT_VARIABLE _uname_output)
+
+    if(NOT _uname_result)
+        message(CHECK_FAIL "unknown")
+        set(HOST_KERNEL_VERSION "0.0.0" CACHE STRING "Detected host kernel version")
+        return()
+    endif()
+
+    string(REGEX REPLACE "-.+$" "" _kversion "${_uname_output}")
+    message(CHECK_PASS "${_kversion}")
+    set(HOST_KERNEL_VERSION "${_kversion}" CACHE STRING "Detected host kernel version")
+endfunction()

+ 0 - 1
packaging/current_libbpf.checksums

@@ -1 +0,0 @@
-ee11746df46d5cb7f828ea3fea641d98ed8e3784d8505fbcd337767c31cc0e3e  v1.4.0p_netdata.tar.gz

Some files were not shown because too many files changed in this diff