From 3100e20cd11587a31a41f561b3cbb9ce6476992d Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Mon, 2 Jun 2025 16:44:46 +0100 Subject: [PATCH 1/2] ci: fetch efW binaries from completed workflows The schedule workflows on the upstream repo tend to have flaky subtests. Use the completed filter to be less prone to such breakage. Signed-off-by: Lorenz Bauer --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03ac0d0dc..2df30a726 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -290,7 +290,7 @@ jobs: workflow_id: 'cicd.yml', event: 'schedule', branch: 'main', - status: 'success', // or 'completed' if upstream is buggy again + status: 'completed', per_page: 1 }); From f32d77ae6519528c6b07231235471fdfb6d22111 Mon Sep 17 00:00:00 2001 From: Lorenz Bauer Date: Mon, 2 Jun 2025 19:00:01 +0100 Subject: [PATCH 2/2] windows: canonicalise pin paths efW recently introduced rules for path canonicalisation. This breaks the existing code for walking all objects with a given prefix. Call into efW runtime to canonicalise the path when necessary. Signed-off-by: Lorenz Bauer --- internal/efw/object.go | 28 ++++++++++++++++++++++++++++ internal/testutils/bpffs_windows.go | 6 +++++- pin/walk_windows.go | 7 +++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/internal/efw/object.go b/internal/efw/object.go index 732d09754..560e2f09b 100644 --- a/internal/efw/object.go +++ b/internal/efw/object.go @@ -87,3 +87,31 @@ func EbpfGetNextPinnedObjectPath(startPath string, objectType ObjectType) (strin )) return windows.ByteSliceToString(tmp), objectType, err } + +/* +Canonicalize a path using filesystem canonicalization rules. + + _Must_inspect_result_ ebpf_result_t + ebpf_canonicalize_pin_path(_Out_writes_(output_size) char* output, size_t output_size, _In_z_ const char* input) +*/ +var ebpfCanonicalizePinPath = newProc("ebpf_canonicalize_pin_path") + +func EbpfCanonicalizePinPath(input string) (string, error) { + addr, err := ebpfCanonicalizePinPath.Find() + if err != nil { + return "", err + } + + inputBytes, err := windows.ByteSliceFromString(input) + if err != nil { + return "", err + } + + output := make([]byte, _EBPF_MAX_PIN_PATH_LENGTH) + err = errorResult(syscall.SyscallN(addr, + uintptr(unsafe.Pointer(&output[0])), + uintptr(len(output)), + uintptr(unsafe.Pointer(&inputBytes[0])), + )) + return windows.ByteSliceToString(output), err +} diff --git a/internal/testutils/bpffs_windows.go b/internal/testutils/bpffs_windows.go index 29cc97758..edf5fbd08 100644 --- a/internal/testutils/bpffs_windows.go +++ b/internal/testutils/bpffs_windows.go @@ -8,8 +8,9 @@ import ( "strings" "testing" - "github.com/cilium/ebpf/internal/efw" "github.com/go-quicktest/qt" + + "github.com/cilium/ebpf/internal/efw" ) // TempBPFFS creates a random prefix to use when pinning on Windows. @@ -17,6 +18,9 @@ func TempBPFFS(tb testing.TB) string { tb.Helper() path := filepath.Join("ebpf-go-test", strconv.Itoa(rand.Int())) + path, err := efw.EbpfCanonicalizePinPath(path) + qt.Assert(tb, qt.IsNil(err)) + tb.Cleanup(func() { tb.Helper() diff --git a/pin/walk_windows.go b/pin/walk_windows.go index ec8844287..8f268f1b9 100644 --- a/pin/walk_windows.go +++ b/pin/walk_windows.go @@ -2,6 +2,7 @@ package pin import ( "errors" + "fmt" "iter" "strings" @@ -15,6 +16,12 @@ import ( // Callers must invoke [Pin.Take] if they wish to hold on to the object. func WalkDir(root string, opts *ebpf.LoadPinOptions) iter.Seq2[*Pin, error] { return func(yield func(*Pin, error) bool) { + root, err := efw.EbpfCanonicalizePinPath(root) + if err != nil { + yield(nil, fmt.Errorf("failed to canonicalize pin path %q: %w", root, err)) + return + } + cursor := root for { next, _, err := efw.EbpfGetNextPinnedObjectPath(cursor, efw.EBPF_OBJECT_UNKNOWN)