Skip to content

Commit

Permalink
fix!: GetMapsIDsByName new signature
Browse files Browse the repository at this point in the history
* feat: add GetMapNextID function

It retrieves the next available map ID after the given startID.

* GetMapsIDsByName now has a new signature.

The new signature makes possible to track the last map ID obtained.

This is a breaking change.
  • Loading branch information
aymericDD authored Oct 23, 2023
1 parent 7a58b8e commit 6f549ef
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 17 deletions.
62 changes: 47 additions & 15 deletions map-low.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package libbpfgo
import "C"

import (
"errors"
"fmt"
"syscall"
"unsafe"
Expand Down Expand Up @@ -99,29 +100,60 @@ func GetMapByID(id uint32) (*BPFMapLow, error) {
}, nil
}

// GetMapsIDsByName searches for maps with a given name.
// It returns a slice of unsigned 32-bit integers representing the IDs of matching maps.
// If no maps are found, it returns an empty slice and no error.
func GetMapsIDsByName(name string) ([]uint32, error) {
bpfMapsIds := []uint32{}
// GetMapNextID retrieves the next available map ID after the given startID.
// It returns the next map ID and an error if one occurs during the operation.
func GetMapNextID(startId uint32) (uint32, error) {
startIDC := C.uint(startId)
retC := C.bpf_map_get_next_id(startIDC, &startIDC)
if retC == 0 {
return uint32(startIDC), nil
}

return uint32(startIDC), fmt.Errorf("failed to get next map id: %w", syscall.Errno(-retC))
}

startId := C.uint(0)
nextId := C.uint(0)
// GetMapsIDsByName searches for maps with a specified name and collects their IDs.
// It starts the search from the given 'startId' and continues until no more matching maps are found.
// The function returns a slice of unsigned 32-bit integers representing the IDs of matching maps.
// If no maps with the provided 'name' are found, it returns an empty slice and no error.
// The 'startId' is modified and returned as the last processed map ID.
//
// Example Usage:
//
// name := "myMap" // The name of the map you want to find.
// startId := uint32(0) // The map ID to start the search from.
//
// var mapIDs []uint32 // Initialize an empty slice to collect map IDs.
// var err error // Initialize an error variable.
//
// // Retry mechanism in case of errors using the last processed 'startId'.
// for {
// mapIDs, err = GetMapsIDsByName(name, startId)
// if err != nil {
// // Handle other errors, possibly with a retry mechanism.
// // You can use the 'startId' who contains the last processed map ID to continue the search.
// } else {
// // Successful search, use the 'mapIDs' slice containing the IDs of matching maps.
// // Update 'startId' to the last processed map ID to continue the search.
// }
// }
func GetMapsIDsByName(name string, startId *uint32) ([]uint32, error) {
var (
bpfMapsIds []uint32
err error
)

for {
retC := C.bpf_map_get_next_id(startId, &nextId)
errno := syscall.Errno(-retC)
if retC < 0 {
if errno == syscall.ENOENT {
*startId, err = GetMapNextID(*startId)
if err != nil {
if errors.Is(err, syscall.ENOENT) {
return bpfMapsIds, nil
}

return bpfMapsIds, fmt.Errorf("failed to get next map id: %w", errno)
return bpfMapsIds, err
}

startId = nextId + 1

bpfMapLow, err := GetMapByID(uint32(nextId))
bpfMapLow, err := GetMapByID(*startId)
if err != nil {
return bpfMapsIds, err
}
Expand Down
11 changes: 11 additions & 0 deletions selftest/map-getmapsbyname/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,15 @@ struct {
__uint(value_size, sizeof(u32));
} test_name SEC(".maps");

struct test_struct {
char value[10];
};

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1);
__type(key, int);
__type(value, struct test_struct);
} test_hash_name SEC(".maps");

char LICENSE[] SEC("license") = "Dual BSD/GPL";
16 changes: 14 additions & 2 deletions selftest/map-getmapsbyname/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
const (
BPFMapNameToNotFind = "not_found"
// The following properties are used to identify the map
BPFHashMapNameToFind = "test_hash_name"
BPFMapNameToFind = "test_name"
BPFMapTypeToFind = bpf.MapTypeArray
BPFMapMaxEntriesToFind = 1
Expand All @@ -29,12 +30,23 @@ func main() {

bpfModule.BPFLoadObject()

notFoundMapsIDs, err := bpf.GetMapsIDsByName(BPFMapNameToNotFind)
startId := uint32(0)
notFoundMapsIDs, err := bpf.GetMapsIDsByName(BPFMapNameToNotFind, &startId)
if len(notFoundMapsIDs) != 0 {
log.Fatalf("the %s map should not be found, but it was found with ids: %v", BPFMapNameToNotFind, notFoundMapsIDs)
}

mapsIDs, err := bpf.GetMapsIDsByName(BPFMapNameToFind)
startId = 0
bpfHashMapsIDs, err := bpf.GetMapsIDsByName(BPFHashMapNameToFind, &startId)
if err != nil {
log.Fatal(err)
}
if len(bpfHashMapsIDs) == 0 {
log.Fatalf("the %s map should be found", BPFHashMapNameToFind)
}

startId = 0
mapsIDs, err := bpf.GetMapsIDsByName(BPFMapNameToFind, &startId)
if err != nil {
log.Fatal(err)
}
Expand Down

0 comments on commit 6f549ef

Please sign in to comment.