github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/cmd/testsuite/integration/map_pinning_test.go (about)

     1  //go:build bpftests
     2  // +build bpftests
     3  
     4  package integration
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path"
    10  	"testing"
    11  
    12  	"github.com/dylandreimerink/gobpfld"
    13  	"github.com/dylandreimerink/gobpfld/bpfsys"
    14  	"github.com/dylandreimerink/gobpfld/bpftypes"
    15  	"github.com/dylandreimerink/gobpfld/kernelsupport"
    16  )
    17  
    18  func TestIntegrationMapPinning(t *testing.T) {
    19  	if !kernelsupport.CurrentFeatures.API.Has(kernelsupport.KFeatAPIObjPinGet) {
    20  		t.Skip("skipping, current kernel version doesn't support pinning")
    21  	}
    22  
    23  	const mapSize = 100
    24  
    25  	testMap := &gobpfld.ArrayMap{
    26  		AbstractMap: gobpfld.AbstractMap{
    27  			Name: gobpfld.MustNewObjName("xdp_stats_map"),
    28  			Definition: gobpfld.BPFMapDef{
    29  				Type:       bpftypes.BPF_MAP_TYPE_ARRAY,
    30  				KeySize:    4, // SizeOf(uint32)
    31  				ValueSize:  8, // SizeOf(uint64)
    32  				MaxEntries: mapSize,
    33  			},
    34  		},
    35  	}
    36  	testMap2 := &gobpfld.ArrayMap{
    37  		AbstractMap: gobpfld.AbstractMap{
    38  			Name: gobpfld.MustNewObjName("xdp_stats_map2"),
    39  			Definition: gobpfld.BPFMapDef{
    40  				Type:       bpftypes.BPF_MAP_TYPE_ARRAY,
    41  				KeySize:    4, // SizeOf(uint32)
    42  				ValueSize:  8, // SizeOf(uint64)
    43  				MaxEntries: mapSize,
    44  			},
    45  		},
    46  	}
    47  
    48  	pinPath2 := "abc/gei"
    49  
    50  	err := testMap2.Load()
    51  	if err != nil {
    52  		panic(fmt.Errorf("error while loading map: %w", err))
    53  	}
    54  
    55  	// Pin map 2 to the FS
    56  	err = testMap2.Pin(pinPath2)
    57  	if err != nil {
    58  		panic(fmt.Errorf("error while pinning map: %w", err))
    59  	}
    60  
    61  	// Unload it so we can unpin it later
    62  	err = testMap2.Close()
    63  	if err != nil {
    64  		panic(fmt.Errorf("error while unloading map: %w", err))
    65  	}
    66  
    67  	// Load map 1
    68  	err = testMap.Load()
    69  	if err != nil {
    70  		panic(fmt.Errorf("error while loading map: %w", err))
    71  	}
    72  
    73  	pinPath := "abc/def"
    74  
    75  	// Pin to the same dir as map 2
    76  	err = testMap.Pin(pinPath)
    77  	if err != nil {
    78  		panic(fmt.Errorf("error while pinning map: %w", err))
    79  	}
    80  
    81  	// Load map 1 so we can unpin it
    82  	err = testMap.Close()
    83  	if err != nil {
    84  		panic(fmt.Errorf("error while unloading map: %w", err))
    85  	}
    86  
    87  	// Unpin and remove pinned file
    88  	err = testMap.Unpin(pinPath, true)
    89  	if err != nil {
    90  		panic(fmt.Errorf("error while unpinning map: %w", err))
    91  	}
    92  
    93  	// Stat the dir to check that removing map 2 didn't remove the "abc" dir which still contains
    94  	// the pinned map 2
    95  	stat, err := os.Stat(fmt.Sprint(gobpfld.BPFSysPath, path.Dir(pinPath)))
    96  	if err != nil {
    97  		panic(fmt.Errorf("error while stating dir '%s': %w", path.Dir(pinPath), err))
    98  	}
    99  	if !stat.IsDir() {
   100  		panic(fmt.Errorf("path is not a dir: %s\n", path.Dir(pinPath)))
   101  	}
   102  
   103  	// Increment map 1 to check that the unpinned map 1 is still accessible
   104  	key := uint32(0)
   105  	value := uint64(0)
   106  
   107  	err = testMap.Get(key, &value)
   108  	if err != nil {
   109  		panic(fmt.Errorf("error while getting from map: %w", err))
   110  	}
   111  
   112  	value++
   113  
   114  	err = testMap.Set(key, &value, bpfsys.BPFMapElemAny)
   115  	if err != nil {
   116  		panic(fmt.Errorf("error while setting to map: %w", err))
   117  	}
   118  
   119  	// Unpin + remove map 2 to cleanup
   120  	err = testMap2.Unpin(pinPath2, true)
   121  	if err != nil {
   122  		panic(fmt.Errorf("error while unloading map: %w", err))
   123  	}
   124  
   125  	// Check that the dir of the pin path now has been removed after the last pinned map was unpinned
   126  	_, err = os.Stat(fmt.Sprint(gobpfld.BPFSysPath, path.Dir(pinPath)))
   127  	if err == nil {
   128  		panic(fmt.Errorf("no error while stating pin path dir: %s\n", path.Dir(pinPath)))
   129  	}
   130  }