libbpfgo icon indicating copy to clipboard operation
libbpfgo copied to clipboard

Ensure that batch APIs handle partial success conditions

Open javierhonduco opened this issue 2 years ago • 1 comments

More context on https://github.com/aquasecurity/libbpfgo/issues/159.

  • [ ] GetValueAndDeleteBatch
  • [ ] DeleteKeyBatch
  • [ ] GetValueBatch
  • [ ] UpdateBatch

javierhonduco avatar May 03 '22 08:05 javierhonduco

UpdateBatch is a special case. We cannot ignore the error of updating fewer entries than were requested.

Thinking about the Batch API, I suppose we should break it by returning the count updated by the kernel, thus leaving it up to the consumer to decide if it's a failure or not.

diff --git a/map-low.go b/map-low.go
index 7cf3d95..fd6ed73 100644
--- a/map-low.go
+++ b/map-low.go
@@ -247,7 +247,7 @@ func (m *BPFMapLow) DeleteKey(key unsafe.Pointer) error {
 // BPFMapLow Batch Operations
 //
 
-func (m *BPFMapLow) GetValueBatch(keys unsafe.Pointer, startKey, nextKey unsafe.Pointer, count uint32) ([][]byte, error) {
+func (m *BPFMapLow) GetValueBatch(keys unsafe.Pointer, startKey, nextKey unsafe.Pointer, count uint32) ([][]byte, uint32, error) {
        valueSize, err := calcMapValueSize(m.ValueSize(), m.Type())
        if err != nil {
                return nil, fmt.Errorf("map %s %w", m.Name(), err)
@@ -291,7 +291,7 @@ func (m *BPFMapLow) GetValueBatch(keys unsafe.Pointer, startKey, nextKey unsafe.
        return collectBatchValues(values, uint32(countC), valueSize), nil
 }
 
-func (m *BPFMapLow) GetValueAndDeleteBatch(keys, startKey, nextKey unsafe.Pointer, count uint32) ([][]byte, error) {
+func (m *BPFMapLow) GetValueAndDeleteBatch(keys, startKey, nextKey unsafe.Pointer, count uint32) ([][]byte, uint32, error) {
        valueSize, err := calcMapValueSize(m.ValueSize(), m.Type())
        if err != nil {
                return nil, fmt.Errorf("map %s %w", m.Name(), err)
@@ -328,7 +328,7 @@ func (m *BPFMapLow) GetValueAndDeleteBatch(keys, startKey, nextKey unsafe.Pointe
        return collectBatchValues(values, uint32(countC), valueSize), nil
 }
 
-func (m *BPFMapLow) UpdateBatch(keys, values unsafe.Pointer, count uint32) error {
+func (m *BPFMapLow) UpdateBatch(keys, values unsafe.Pointer, count uint32) (uint32, error) {
        countC := C.uint(count)
 
        optsC, errno := C.cgo_bpf_map_batch_opts_new(C.BPF_ANY, C.BPF_ANY)
@@ -355,7 +355,7 @@ func (m *BPFMapLow) UpdateBatch(keys, values unsafe.Pointer, count uint32) error
        return nil
 }
 
-func (m *BPFMapLow) DeleteKeyBatch(keys unsafe.Pointer, count uint32) error {
+func (m *BPFMapLow) DeleteKeyBatch(keys unsafe.Pointer, count uint32) (uint32, error) {
        countC := C.uint(count)
 
        optsC, errno := C.cgo_bpf_map_batch_opts_new(C.BPF_ANY, C.BPF_ANY)

geyslan avatar Aug 31 '23 12:08 geyslan