Skip to content

Commit b75248d

Browse files
ti-molmb
authored andcommitted
map: add Map.Handle() method for retrieving a Map's type information
Signed-off-by: Timo Beckers <[email protected]>
1 parent c6c6aba commit b75248d

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

info.go

+15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type MapInfo struct {
3030
Flags uint32
3131
// Name as supplied by user space at load time. Available from 4.15.
3232
Name string
33+
34+
btf btf.ID
3335
}
3436

3537
func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) {
@@ -50,6 +52,7 @@ func newMapInfoFromFd(fd *sys.FD) (*MapInfo, error) {
5052
info.MaxEntries,
5153
uint32(info.MapFlags),
5254
unix.ByteSliceToString(info.Name[:]),
55+
btf.ID(info.BtfId),
5356
}, nil
5457
}
5558

@@ -77,6 +80,18 @@ func (mi *MapInfo) ID() (MapID, bool) {
7780
return mi.id, mi.id > 0
7881
}
7982

83+
// BTFID returns the BTF ID associated with the Map.
84+
//
85+
// The ID is only valid as long as the associated Map is kept alive.
86+
// Available from 4.18.
87+
//
88+
// The bool return value indicates whether this optional field is available and
89+
// populated. (The field may be available but not populated if the kernel
90+
// supports the field but the Map was loaded without BTF information.)
91+
func (mi *MapInfo) BTFID() (btf.ID, bool) {
92+
return mi.btf, mi.btf > 0
93+
}
94+
8095
// programStats holds statistics of a program.
8196
type programStats struct {
8297
// Total accumulated runtime of the program ins ns.

map.go

+18
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,24 @@ func (m *Map) Info() (*MapInfo, error) {
571571
return newMapInfoFromFd(m.fd)
572572
}
573573

574+
// Handle returns a reference to the Map's type information in the kernel.
575+
//
576+
// Returns ErrNotSupported if the kernel has no BTF support, or if there is no
577+
// BTF associated with the Map.
578+
func (m *Map) Handle() (*btf.Handle, error) {
579+
info, err := m.Info()
580+
if err != nil {
581+
return nil, err
582+
}
583+
584+
id, ok := info.BTFID()
585+
if !ok {
586+
return nil, fmt.Errorf("map %s: retrieve BTF ID: %w", m, ErrNotSupported)
587+
}
588+
589+
return btf.NewHandleFromID(id)
590+
}
591+
574592
// MapLookupFlags controls the behaviour of the map lookup calls.
575593
type MapLookupFlags uint64
576594

map_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"unsafe"
1212

1313
"github.com/cilium/ebpf/asm"
14+
"github.com/cilium/ebpf/btf"
1415
"github.com/cilium/ebpf/internal"
1516
"github.com/cilium/ebpf/internal/sys"
1617
"github.com/cilium/ebpf/internal/testutils"
@@ -1791,6 +1792,34 @@ func TestMapPinning(t *testing.T) {
17911792
qt.Assert(t, qt.StringContains(err.Error(), "ValueSize"))
17921793
}
17931794

1795+
func TestMapHandle(t *testing.T) {
1796+
testutils.SkipOnOldKernel(t, "4.18", "btf_id in map info")
1797+
1798+
kv := &btf.Int{Size: 4}
1799+
m, err := NewMap(&MapSpec{
1800+
Type: Hash,
1801+
KeySize: kv.Size,
1802+
ValueSize: kv.Size,
1803+
Key: kv,
1804+
Value: kv,
1805+
MaxEntries: 1,
1806+
})
1807+
qt.Assert(t, qt.IsNil(err))
1808+
defer m.Close()
1809+
1810+
h, err := m.Handle()
1811+
qt.Assert(t, qt.IsNil(err))
1812+
qt.Assert(t, qt.IsNotNil(h))
1813+
defer h.Close()
1814+
1815+
spec, err := h.Spec(nil)
1816+
qt.Assert(t, qt.IsNil(err))
1817+
1818+
typ, err := spec.TypeByID(1)
1819+
qt.Assert(t, qt.IsNil(err))
1820+
qt.Assert(t, qt.ContentEquals(typ, btf.Type(kv)))
1821+
}
1822+
17941823
func TestPerfEventArrayCompatible(t *testing.T) {
17951824
ms := &MapSpec{
17961825
Type: PerfEventArray,

0 commit comments

Comments
 (0)