From 6685ae7aa2cf90c2829b20450602a3036a91edae Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Sat, 7 Sep 2024 18:26:15 +0000 Subject: [PATCH] ci: Use pre-release LLVM versions from tarballs Instead of relying on Homebrew for macOS (which ships older LLVM versions) and `apt.llvm.org` for Linux (which often has bugs at the packaging level), we now use: - The tarball from Rust CI to provide `libLLVM`. This ensures it always matches the version used by the latest Rust nightly. - The tarball from https://github.com/llvm/llvm-project to provide `clang` and `llvm-objcopy`. In this case, an exact match with `libLLVM` in `rustc` is not necessary. Nevertheless, using the latest versions is preferred. Fixing the build on macOS runners is the main motivation behind this change. Co-authored-by: tyrone-wu --- .github/workflows/ci.yml | 62 +++++++++++++++++-------- test/integration-ebpf/src/test.rs | 18 ++++++- test/integration-test/src/tests/info.rs | 6 +++ 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c992c362..d4f56cd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,6 @@ on: env: CARGO_TERM_COLOR: always - LLVM_VERSION: 18 jobs: lint: @@ -183,14 +182,16 @@ jobs: strategy: fail-fast: false matrix: - runner: + include: # macos-14 is arm64 per # https://github.com/actions/runner-images#available-images which # doesn't support nested virtualization per # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#limitations-for-arm64-macos-runners - - macos-13 - - ubuntu-22.04 - runs-on: ${{ matrix.runner }} + - target: x86_64-apple-darwin + os: macos-13 + - target: x86_64-unknown-linux-gnu + os: ubuntu-22.04 + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: @@ -198,27 +199,29 @@ jobs: - name: Install prerequisites if: runner.os == 'Linux' - # ubuntu-22.04 comes with clang 14[0] which doesn't include support for signed and 64bit - # enum values which was added in clang 15[1]. - # # gcc-multilib provides at least which is referenced by libbpf. # - # llvm provides llvm-objcopy which is used to build the BTF relocation tests. + # ubuntu-22.04 comes with clang 14[0] which doesn't include support for signed and 64bit + # enum values which was added in clang 15[1]. llvm-objcopy is used to build the BTF + # relocation tests. Use the latest LLVM release tarball to provide both dependencies. # # [0] https://github.com/actions/runner-images/blob/ubuntu22/20230724.1/images/linux/Ubuntu2204-Readme.md # # [1] https://github.com/llvm/llvm-project/commit/dc1c43d run: | set -euxo pipefail - wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc - echo deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ env.LLVM_VERSION }} main | sudo tee /etc/apt/sources.list.d/llvm.list sudo apt update - sudo apt -y install clang-${{ env.LLVM_VERSION }} gcc-multilib llvm-${{ env.LLVM_VERSION }} locate qemu-system-{arm,x86} - echo /usr/lib/llvm-${{ env.LLVM_VERSION }}/bin >> $GITHUB_PATH - - - name: bpf-linker - if: runner.os == 'Linux' - run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git + sudo apt -y install gcc-multilib locate qemu-system-{arm,x86} + + llvm_tarball_url=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + https://api.github.com/repos/llvm/llvm-project/releases | jq -r \ + 'map(select(.prerelease)) | first | .assets | + map(select(.name | endswith("Linux-X64.tar.xz"))) | first | + .browser_download_url') + mkdir -p /tmp/llvm-upstream + wget -q -O - $llvm_tarball_url | tar -xJ --strip-components 1 \ + -C /tmp/llvm-upstream + echo /tmp/llvm-upstream/bin >> $GITHUB_PATH - name: Install prerequisites if: runner.os == 'macOS' @@ -227,8 +230,6 @@ jobs: # The tar shipped on macOS doesn't support --wildcards, so we need GNU tar. # # The clang shipped on macOS doesn't support BPF, so we need LLVM from brew. - # - # We also need LLVM for bpf-linker, see comment below. run: | set -euxo pipefail brew update @@ -249,10 +250,31 @@ jobs: - uses: Swatinem/rust-cache@v2 + - name: Install libLLVM + # Use LLVM tarball from Rust CI to make sure that the libLLVM version + # matches exactly the one used by the current Rust nightly. + run: | + set -euxo pipefail + # Get the partial SHA from Rust nightly. + rustc_sha=$(rustc +nightly --version | grep -oE '[a-f0-9]{7,40}') + # Get the full SHA from GitHub. + rustc_sha=$(curl -s https://api.github.com/repos/rust-lang/rust/commits/$rustc_sha \ + --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ + --header 'content-type: application/json' \ + | jq -r '.sha') + mkdir -p /tmp/rustc-llvm + wget -q -O - https://ci-artifacts.rust-lang.org/rustc-builds/$rustc_sha/rust-dev-nightly-${{ matrix.target }}.tar.xz | \ + tar -xJ --strip-components 2 -C /tmp/rustc-llvm + echo /tmp/rustc-llvm/bin >> $GITHUB_PATH + + - name: bpf-linker + if: runner.os == 'Linux' + run: cargo install bpf-linker --git https://github.com/aya-rs/bpf-linker.git + - name: bpf-linker if: runner.os == 'macOS' # NB: rustc doesn't ship libLLVM.so on macOS, so disable proxying (default feature). We also - # --force so that bpf-linker gets always relinked against the latest LLVM installed by brew. + # --force so that bpf-linker gets always relinked against the latest LLVM downloaded above. run: cargo install --force bpf-linker --git https://github.com/aya-rs/bpf-linker.git --no-default-features - name: Download debian kernels diff --git a/test/integration-ebpf/src/test.rs b/test/integration-ebpf/src/test.rs index 88f01e89..8774f596 100644 --- a/test/integration-ebpf/src/test.rs +++ b/test/integration-ebpf/src/test.rs @@ -3,8 +3,10 @@ use aya_ebpf::{ bindings::xdp_action, + bpf_printk, macros::{kprobe, kretprobe, tracepoint, uprobe, uretprobe, xdp}, programs::{ProbeContext, RetProbeContext, TracePointContext, XdpContext}, + EbpfContext, }; #[xdp] @@ -30,8 +32,20 @@ pub fn test_kretprobe(_ctx: RetProbeContext) -> u32 { } #[tracepoint] -pub fn test_tracepoint(_ctx: TracePointContext) -> u32 { - 0 +pub fn test_tracepoint(ctx: TracePointContext) -> u32 { + // Some arbitrary work, to make the program running for some time and have + // a real `run_time` in `test_program_info`. + let mut res = ctx.uid().wrapping_add(ctx.pid()); + for _ in 0..10_000 { + res = res.wrapping_mul(123); + res ^= (ctx.pid() << 3) ^ (ctx.uid() << 4); + res = res.rotate_left(2); + res = res.reverse_bits(); + res = res.swap_bytes(); + res = res.count_ones(); + unsafe { bpf_printk!(b"number %u", res) }; + } + res } #[uprobe] diff --git a/test/integration-test/src/tests/info.rs b/test/integration-test/src/tests/info.rs index 7774709c..70e55a5d 100644 --- a/test/integration-test/src/tests/info.rs +++ b/test/integration-test/src/tests/info.rs @@ -214,6 +214,12 @@ fn test_prog_stats() { .unwrap(); prog.load().unwrap(); prog.attach("syscalls", "sys_enter_bpf").unwrap(); + + // Executing bpf syscalls to trigger `sys_enter_bpf` + for _ in 0..5 { + let _ = loaded_programs().collect::>(); + } + let test_prog = prog.info().unwrap(); kernel_assert!(