Skip to content

Commit

Permalink
features: implement feature probe for StructOpsMap
Browse files Browse the repository at this point in the history
With the libbpf feature probe API being reworked a while back, a probe for
StructOps maps was also implemented. Setting an invalid vmlinux type id
and checking for ENOTSUPP signals the map's availability.

Signed-off-by: Timo Beckers <timo@isovalent.com>
  • Loading branch information
ti-mo committed Aug 1, 2022
1 parent d173cba commit ceb1b94
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 17 deletions.
18 changes: 10 additions & 8 deletions features/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ func createMapTypeAttr(mt ebpf.MapType) *sys.MapCreateAttr {
a.BtfKeyTypeId = 1 // BTF_KIND_INT
a.BtfValueTypeId = 3 // BTF_KIND_ARRAY
a.BtfFd = ^uint32(0)
case ebpf.StructOpsMap:
// StructOps requires setting a vmlinux type id, but id 1 will always
// resolve to some type of integer. This will cause ENOTSUPP.
a.BtfVmlinuxValueTypeId = 1
}

return a
Expand All @@ -100,14 +104,6 @@ func validateMaptype(mt ebpf.MapType) error {
if mt > mt.Max() {
return os.ErrInvalid
}

if mt == ebpf.StructOpsMap {
// A probe for StructOpsMap has vmlinux BTF requirements we currently
// cannot meet. Once we figure out how to add a working probe in this
// package, we can remove this check.
return errors.New("a probe for MapType StructOpsMap isn't implemented")
}

return nil
}

Expand All @@ -131,6 +127,12 @@ func haveMapType(mt ebpf.MapType) error {
err = nil
}

// ENOTSUPP means the map type is at least known to the kernel.
case errors.Is(err, sys.ENOTSUPP):
if mt == ebpf.StructOpsMap {
err = nil
}

// EINVAL occurs when attempting to create a map with an unknown type.
// E2BIG occurs when MapCreateAttr contains non-zero bytes past the end
// of the struct known by the running kernel, meaning the kernel is too old
Expand Down
10 changes: 1 addition & 9 deletions features/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var mapTypeMinVersion = map[ebpf.MapType]string{
ebpf.Stack: "4.20",
ebpf.SkStorage: "5.2",
ebpf.DevMapHash: "5.4",
ebpf.StructOpsMap: "5.6", // requires vmlinux BTF, skip for now
ebpf.StructOpsMap: "5.6",
ebpf.RingBuf: "5.8",
ebpf.InodeStorage: "5.10",
ebpf.TaskStorage: "5.11",
Expand All @@ -55,10 +55,6 @@ func TestHaveMapType(t *testing.T) {
feature := fmt.Sprintf("map type %s", mt.String())

t.Run(mt.String(), func(t *testing.T) {
if mt == ebpf.StructOpsMap {
t.Skip("Test for map type StructOpsMap requires working probe")
}

testutils.SkipOnOldKernel(t, minVersion, feature)

if err := HaveMapType(mt); err != nil {
Expand All @@ -80,8 +76,4 @@ func TestHaveMapTypeInvalid(t *testing.T) {
if err := HaveMapType(ebpf.MapType(math.MaxUint32)); !errors.Is(err, os.ErrInvalid) {
t.Fatalf("Expected os.ErrInvalid but was: %v", err)
}

if err := HaveMapType(ebpf.MapType(ebpf.StructOpsMap)); err == nil {
t.Fatal("Expected but was nil")
}
}

0 comments on commit ceb1b94

Please sign in to comment.