diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-12 23:02:59 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-12 23:02:59 +0200 |
| commit | f28dab3d42c6e4a33642b990f60f69abc2d89f07 (patch) | |
| tree | 892fc26e7c3733e43f4bf9246d951220faeb31a3 | |
| parent | 13e7970afb3eeac69f82df833f030711e5cf12ec (diff) | |
chore: pin libbpfgo v0.9.2-libbpf-1.5.1 workflow
| -rw-r--r-- | AGENTS.md | 9 | ||||
| -rw-r--r-- | Magefile.go | 33 | ||||
| -rw-r--r-- | README.md | 27 | ||||
| -rw-r--r-- | docs/libbpfgo-upgrade-plan.md | 113 | ||||
| -rw-r--r-- | go.mod | 6 | ||||
| -rw-r--r-- | go.sum | 12 |
6 files changed, 186 insertions, 14 deletions
@@ -4,7 +4,14 @@ This file provides guidance to AI coding assistants working with the I/O Riot NG ## Build/Test Commands -**Prerequisites**: Ensure libbpfgo is cloned at `../libbpfgo` relative to this repository. +**Prerequisites**: Ensure `libbpfgo` is cloned at `../libbpfgo` relative to this repository (or set `LIBBPFGO`), pinned to `v0.9.2-libbpf-1.5.1`, and rebuilt with: + +```bash +git -C ../libbpfgo checkout v0.9.2-libbpf-1.5.1 +git -C ../libbpfgo submodule update --init --recursive +make -C ../libbpfgo libbpfgo-static +``` + If builds/tests fail with missing libbpf headers (for example `bpf/bpf.h` not found), run `mage world` first. It bootstraps generation/dependencies and is the preferred first troubleshooting step before retrying `mage test` or `go test`. ```bash diff --git a/Magefile.go b/Magefile.go index 36db529..ecb4060 100644 --- a/Magefile.go +++ b/Magefile.go @@ -29,6 +29,7 @@ const ( binaryName = "ior" workloadBinaryName = "ioworkload" defaultLibbpfgoPath = "../libbpfgo" + libbpfgoRequiredTag = "v0.9.2-libbpf-1.5.1" bpfSourcePath = "internal/c/ior.bpf.c" bpfObjectPath = "internal/c/ior.bpf.o" bpfOutputPath = "ior.bpf.o" @@ -519,6 +520,9 @@ func Prof() error { } func buildBPFObject() error { + if err := ensureLibbpfgoStaticToolchain(); err != nil { + return err + } libbpfgo := libbpfgoPath() includeDir := filepath.Join(libbpfgo, "output") return sh.RunWithV(bpfEnv(), "clang", "-g", "-O2", "-Wall", "-fpie", "-target", "bpf", @@ -529,6 +533,35 @@ func bpfEnv() map[string]string { return map[string]string{"CC": "clang"} } +func ensureLibbpfgoStaticToolchain() error { + libbpfgo := libbpfgoPath() + requiredPaths := []string{ + filepath.Join(libbpfgo, "output"), + filepath.Join(libbpfgo, "output", "libbpf", "libbpf.a"), + filepath.Join(libbpfgo, "selftest", "common"), + } + for _, path := range requiredPaths { + if _, err := os.Stat(path); err == nil { + continue + } else if errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("missing libbpfgo static toolchain path %s\n%s", path, libbpfgoSetupHint(libbpfgo)) + } else { + return fmt.Errorf("stat %s: %w", path, err) + } + } + return nil +} + +func libbpfgoSetupHint(libbpfgo string) string { + return strings.Join([]string{ + fmt.Sprintf("expected a local libbpfgo checkout at %s pinned to %s", libbpfgo, libbpfgoRequiredTag), + "rebuild the static toolchain with:", + fmt.Sprintf(" git -C %s checkout %s", libbpfgo, libbpfgoRequiredTag), + fmt.Sprintf(" git -C %s submodule update --init --recursive", libbpfgo), + fmt.Sprintf(" make -C %s libbpfgo-static", libbpfgo), + }, "\n") +} + func ensureBenchProfilesDir() error { if err := os.MkdirAll(benchProfilesDir, 0o755); err != nil { return fmt.Errorf("ensure %s: %w", benchProfilesDir, err) @@ -16,6 +16,21 @@ This works only on Linux! - Go 1.26 or newer (ior relies on cgo via libbpfgo). +## Local libbpfgo Toolchain + +`ior` links against a locally built `libbpfgo` checkout. By default +`Magefile.go` expects that checkout at `../libbpfgo` relative to this repo; set +`LIBBPFGO=/absolute/path/to/libbpfgo` if you keep it elsewhere. + +Pin that checkout to `v0.9.2-libbpf-1.5.1` and rebuild the static artifacts +before running `mage` targets: + +```shell +git -C ../libbpfgo checkout v0.9.2-libbpf-1.5.1 +git -C ../libbpfgo submodule update --init --recursive +make -C ../libbpfgo libbpfgo-static +``` + ## Timing Semantics Each reported event pair has two timing counters: @@ -35,13 +50,13 @@ Important details: To get this running on Fedora 42, run: ```shell -mkdir ~/git -git clone https://codeberg.org/snonux/ior -git clone https://github.com/aquasecurity/libbpfgo +mkdir -p ~/git +git clone https://codeberg.org/snonux/ior ~/git/ior +git clone https://github.com/aquasecurity/libbpfgo ~/git/libbpfgo sudo dnf install -y golang clang bpftool elfutils-libelf-devel zlib-static glibc-static libzstd-static -cd libbpfgo -make -make libbpfgo-static +git -C ~/git/libbpfgo checkout v0.9.2-libbpf-1.5.1 +git -C ~/git/libbpfgo submodule update --init --recursive +make -C ~/git/libbpfgo libbpfgo-static ``` Need libelf static, which isn't in any repos. So we need to compile it ourselves. diff --git a/docs/libbpfgo-upgrade-plan.md b/docs/libbpfgo-upgrade-plan.md new file mode 100644 index 0000000..1290479 --- /dev/null +++ b/docs/libbpfgo-upgrade-plan.md @@ -0,0 +1,113 @@ +# libbpfgo Upgrade Plan + +## Goal + +Upgrade `ior` from `github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3.0...` +to the latest tagged upstream release `v0.9.2-libbpf-1.5.1`, and align the +repo's Go module, local static-link toolchain checkout, build instructions, and +runtime validation on that same tag. + +## Current State + +- `go.mod` / `go.sum` are expected to pin + `github.com/aquasecurity/libbpfgo v0.9.2-libbpf-1.5.1` +- `Magefile.go` defaults to the sibling checkout at `../libbpfgo` (local path: + `/home/paul/git/libbpfgo`) and should emit rebuild guidance if static + artifacts are missing +- The local checkout is currently ahead of the latest tag: + `v0.9.2-libbpf-1.5.1-23-g9a319d2` +- `README.md` / `AGENTS.md` should pin the tag, sync the `libbpf` submodule, + and document the static rebuild workflow explicitly + +## Upgrade Target + +- Upstream tag: `v0.9.2-libbpf-1.5.1` +- Local checkout to use for static headers/archive: + `/home/paul/git/libbpfgo` +- Repo-relative default checkout path used by `Magefile.go`: `../libbpfgo` +- Override path for local experiments: `LIBBPFGO=/absolute/path/to/libbpfgo` +- Do not target `libbpfgo` `main` as part of this upgrade unless a tagged + release blocker is found + +## Pinned Source of Truth + +- `go.mod` / `go.sum` should pin `github.com/aquasecurity/libbpfgo + v0.9.2-libbpf-1.5.1` +- `README.md` and `AGENTS.md` should document the same checkout, tag, submodule, + and `make libbpfgo-static` workflow +- `Magefile.go` should fail with explicit rebuild guidance when the local + `libbpfgo` checkout is missing the static artifacts that `ior` expects + +## Breaking-Change Watchpoints + +- `v0.8.0-libbpf-1.5` includes a `BPFProg` API alignment change +- `v0.9.1-libbpf-1.5.1` changes `AttachUprobe` / + `AttachURetprobe` signatures +- `libbpf` minimum version moves from `1.3.x` to `1.5.1` +- Static builds require `git submodule update --init --recursive` in the local + `libbpfgo` checkout before `make libbpfgo-static` + +`ior` appears to use a narrow subset of APIs: + +- module loading (`NewModuleFromFile`, `NewModuleFromBuffer`, `BPFLoadObject`) +- maps (`GetMap`, `SetMaxEntries`, `InitGlobalVariable`) +- ringbuf (`InitRingBuf`) +- program lookup and tracepoint attach (`GetProgram`, `AttachTracepoint`) + +The direct API-break risk is therefore expected to be low, but compile/runtime +validation is still required. + +## Implementation Workstreams + +1. Align the version source of truth + - Pin `go.mod` / `go.sum` to `v0.9.2-libbpf-1.5.1` + - Align the local checkout instructions in `README.md` + - Align `AGENTS.md` and `Magefile.go` guidance with the same tag and rebuild flow + - Ensure the local checkout is reset to the exact tag and rebuilt + +2. Rebuild the local static toolchain + - In `/home/paul/git/libbpfgo`: + - `git checkout v0.9.2-libbpf-1.5.1` + - `git submodule update --init --recursive` + - `make libbpfgo-static` + +3. Compile and fix `ior` + - Rebuild `ior` against the upgraded wrapper and static `libbpf` + - Fix any compile/API regressions in: + - `internal/ior.go` + - `internal/bpfsetup.go` + - `internal/bpfembed.go` + - any `probemanager` adapter code if signatures changed + +4. Validate behavior + - Run `mage world` + - Run root-required integration coverage + - Specifically verify: + - embedded `ior.bpf.o` loading still works + - tracepoint attach/detach still works + - ring buffer event ingestion still works + - static build/link flags still work with the rebuilt local checkout + +5. Finalize docs and rollback guidance + - Document the exact `libbpfgo` tag and rebuild commands + - Mention the local checkout path used by `Magefile.go` + - Add troubleshooting notes for submodule sync / static rebuild failures + +## Validation Commands + +- `GOTOOLCHAIN=auto mage test` +- `GOTOOLCHAIN=auto mage world` +- `GOTOOLCHAIN=auto mage integrationTest` + +## References + +- Repo files: + - `go.mod` + - `README.md` + - `AGENTS.md` + - `Magefile.go` + - `internal/ior.go` + - `internal/bpfsetup.go` + - `internal/bpfembed.go` +- Local toolchain checkout: + - `/home/paul/git/libbpfgo` @@ -7,17 +7,17 @@ require ( charm.land/bubbletea/v2 v2.0.1 charm.land/lipgloss/v2 v2.0.0 github.com/DataDog/zstd v1.5.7 - github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3.0.20240111220235-90dbffffbdab + github.com/aquasecurity/libbpfgo v0.9.2-libbpf-1.5.1 + github.com/charmbracelet/harmonica v0.2.0 + github.com/charmbracelet/x/term v0.2.2 github.com/magefile/mage v1.15.0 ) require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/charmbracelet/colorprofile v0.4.2 // indirect - github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect - github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect @@ -6,8 +6,8 @@ charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo= charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14= github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3.0.20240111220235-90dbffffbdab h1:w74AraWsnj+AgEOk2uERlLtECCWutMtuwCGCCWzpBBs= -github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3.0.20240111220235-90dbffffbdab/go.mod h1:0rEApF1YBHGuZ4C8OYI9q5oDBVpgqtRqYATePl9mCDk= +github.com/aquasecurity/libbpfgo v0.9.2-libbpf-1.5.1 h1:TDN+16Nim3gimjuTxd+sFhb4v06mEeYH0JfRWAFowA0= +github.com/aquasecurity/libbpfgo v0.9.2-libbpf-1.5.1/go.mod h1:JQNC5NuGwyYC7IZum6JqPNVHarFAuab+h4lO6t0jIhc= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM= @@ -46,8 +46,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= @@ -58,3 +58,7 @@ golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= +kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= +kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= |
