Repository navigation
feat(node): start the eBPF descriptor tracker on request and refuse to start when the host cannot run it (ADR-1539) - #1993
Merged
Conversation
…o start when the host cannot run it (ADR-1539) (#1993) * feat(node): start the eBPF descriptor tracker on request and refuse to start when the host cannot run it (ADR-1539) The eBPF loader under cmd/vmafx-node/bpf was never started, VMAFX_EBPF_MOUNT_PREFIX was read by no code, and the tree held a stub whose Start always failed (docs audit 2026-10-03, defect 35). VMAFX_EBPF_BYPASS=1 now starts the tracker between the storage layer and the controller client, watching VMAFX_EBPF_MOUNT_PREFIX. The node refuses to start when storage does not mount under the prefix, and when bpf.Preflight fails, listing every reason: kernel older than 5.15, no kernel BTF, syscall tracepoints not visible in tracefs, no CAP_BPF+CAP_PERFMON or CAP_SYS_ADMIN. A relative or over-long prefix is refused instead of truncated; off Linux the request is refused. The bpf2go object (pinned v0.22.0, both endiannesses) is committed with a minimal vmlinux.h and regenerates byte for byte with the same clang. The loader now uses bpf2go's struct mirrors: the hand-written mount_prefix_t mirror was 264 bytes against the map's 260-byte value. Ring events decode without unsafe, and the descriptor cache prunes closed entries at 4096. The tracker records descriptors only: no read path uses them, because the vmaf CLI reads the mounted files itself and the mount runs without a VFS cache. The documentation says so, and the skipping benchmark that measured two identical FUSE reads is removed. * docs: regenerate the indexes and the citation map after rebasing
lusoris
force-pushed
the
feat/node-ebpf-loader
branch
from
October 4, 2026 05:11
5db0c2c to
8cf6d61
Compare
5 of 10 tasks
lusoris
added a commit
that referenced
this pull request
Oct 4, 2026
… loader (#2001) * fix(docs): point the platform figure's eBPF evidence at the generated loader #1993 removed cmd/vmafx-node/bpf/rclone_bypass_stub.go, which the phase4b-platform figure cited as evidence for rcloneBypassObjects, so `make docs-figures` (verify-all and the dedupe-gate-contract pre-push hook) failed on master. The symbol now lives in the bpf2go output rclonebypass_bpfel.go; the figure cites that file and its JSON is rebuilt.
3 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
VMAFX_EBPF_BYPASS=1now starts the node's eBPF descriptor tracker, and a host that cannot run it stops the node with every reason. Before, the loader undercmd/vmafx-node/bpfwas never started,VMAFX_EBPF_MOUNT_PREFIXwas read by no code, and the tree held a stub whoseStartalways failed (docs audit 2026-10-03, defect 35).OnStartbetween the storage layer and the controller client and stops after the client drained. It watchesVMAFX_EBPF_MOUNT_PREFIX; the node refuses to start unless storage mounts under that prefix (VMAFX_STORAGE_MODEresolving tomount,VMAFX_STORAGE_MOUNT_ROOTinside the prefix), since otherwise it would observe nothing.bpf.Preflightlists every failing requirement before any BPF syscall: kernel older than 5.15, no/sys/kernel/btf/vmlinux, syscall tracepoints not visible in tracefs, noCAP_BPF+CAP_PERFMONorCAP_SYS_ADMIN. A relative or over-long prefix is refused instead of truncated. Off little-endian Linux the request is refused.v0.22.0, little-endian targets) is committed with a minimalvmlinux.h; the same clang regenerates it byte for byte (go generate ./cmd/vmafx-node/bpf/, which also adds the licence header).mount_prefix_tmirror was 264 bytes against the map's 260-byte value, so the first map write would have been refused; the loader now uses bpf2go's mirrors and decodes ring events withoutunsafe. The descriptor cache only grew; it now prunes closed descriptors at 4096 entries.T-NODE-EBPF-BYPASS-NO-READ-PATH-2026-10-04tracks the gap.Type
feat— new featureChecklist
make format && make lintis green locally. Go: gofmt,go vet, gosec v2.29.0 (0 issues outside generated code), commit hooks (HISS audit, dedupe, shfmt, shellcheck, markdownlint, copyright) green.python3 scripts/ci/run_meson_test.py -- -C build. No libvmaf C change; Go tests below./cross-backend-diffand the worst ULP is ≤ 2. No SIMD/GPU code touched..c/.cpp/.cu/.h/.hpp, it has the appropriate license header (seeCONTRIBUTING.md).cmd/vmafx-node/bpf/vmlinux.hcarries the fork header.!orBREAKING CHANGE:and the migration path is documented below. Not breaking: the tracker stays off by default.docs/adr/_index_fragments/<NNNN-slug>.mdand the slug is appended todocs/adr/_index_fragments/_order.txt— do not editdocs/adr/README.mddirectly (regenerated byscripts/docs/concat-adr-index.sh; see ADR-0221).Bug-status hygiene (ADR-0165)
docs/state.mdupdated in this PR:T-NODE-EBPF-LOADER-NOT-WIRED-2026-10-04opened and closed (Recently closed);T-NODE-EBPF-BYPASS-NO-READ-PATH-2026-10-04opened (Open bugs).Netflix golden-data gate (ADR-0024)
assertAlmostEqual(...)score in the Netflix golden Python tests.Deep-dive deliverables (ADR-0108)
## Alternatives considered.AGENTS.mdinvariant note —cmd/vmafx-node/AGENTS.mdinvariant 15.changelog.d/added/node-ebpf-tracker.md.docs/rebase-notes.md, "vmafx-nodestarts the eBPF descriptor tracker on request (ADR-1539, 2026-10-04)".Reproducer
Evidence (2026-10-04, kernel 7.2.8, unprivileged): node packages
okunder-race. The node binary withVMAFX_EBPF_BYPASS=1exits 1: "VMAFX_EBPF_BYPASS is set but the eBPF tracker cannot start: ebpf: syscall tracepoints not visible in tracefs (mount /sys/kernel/tracing): ... permission denied ... ebpf: process lacks CAP_BPF and CAP_PERFMON (or CAP_SYS_ADMIN); CapEff=0x0". With the provider returning nil,TestEBPFStartFailsClosedandTestEBPFRefusedWithHTTPServefail;TestEmbeddedObjectMatchesMirrorschecks the object's programs, maps and struct sizes (it would catch the 264/260 mismatch).go generatereproduces the committed object byte for byte (clang 23.1.1).Known follow-ups
CAP_BPF; no privileged host was available to this change).T-NODE-EBPF-BYPASS-NO-READ-PATH-2026-10-04: a real read bypass needs a cached mount and a scorer input that reads the cache file.SPDX EUPL-1.2while it declares "Dual BSD/GPL" to the kernel (pre-existing); a maintainer licence decision.