github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/internal/pinning.go (about)

     1  package internal
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  
    10  	"github.com/cilium/ebpf/internal/sys"
    11  	"github.com/cilium/ebpf/internal/unix"
    12  )
    13  
    14  func Pin(currentPath, newPath string, fd *sys.FD) error {
    15  	if newPath == "" {
    16  		return errors.New("given pinning path cannot be empty")
    17  	}
    18  	if currentPath == newPath {
    19  		return nil
    20  	}
    21  
    22  	fsType, err := FSType(filepath.Dir(newPath))
    23  	if err != nil {
    24  		return err
    25  	}
    26  	if fsType != unix.BPF_FS_MAGIC {
    27  		return fmt.Errorf("%s is not on a bpf filesystem", newPath)
    28  	}
    29  
    30  	defer runtime.KeepAlive(fd)
    31  
    32  	if currentPath == "" {
    33  		return sys.ObjPin(&sys.ObjPinAttr{
    34  			Pathname: sys.NewStringPointer(newPath),
    35  			BpfFd:    fd.Uint(),
    36  		})
    37  	}
    38  
    39  	// Renameat2 is used instead of os.Rename to disallow the new path replacing
    40  	// an existing path.
    41  	err = unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE)
    42  	if err == nil {
    43  		// Object is now moved to the new pinning path.
    44  		return nil
    45  	}
    46  	if !os.IsNotExist(err) {
    47  		return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err)
    48  	}
    49  	// Internal state not in sync with the file system so let's fix it.
    50  	return sys.ObjPin(&sys.ObjPinAttr{
    51  		Pathname: sys.NewStringPointer(newPath),
    52  		BpfFd:    fd.Uint(),
    53  	})
    54  }
    55  
    56  func Unpin(pinnedPath string) error {
    57  	if pinnedPath == "" {
    58  		return nil
    59  	}
    60  	err := os.Remove(pinnedPath)
    61  	if err == nil || os.IsNotExist(err) {
    62  		return nil
    63  	}
    64  	return err
    65  }