gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

pinning.go (1797B)


      1 package internal
      2 
      3 import (
      4 	"errors"
      5 	"fmt"
      6 	"os"
      7 	"path/filepath"
      8 	"runtime"
      9 	"unsafe"
     10 
     11 	"github.com/cilium/ebpf/internal/sys"
     12 	"github.com/cilium/ebpf/internal/unix"
     13 )
     14 
     15 func Pin(currentPath, newPath string, fd *sys.FD) error {
     16 	const bpfFSType = 0xcafe4a11
     17 
     18 	if newPath == "" {
     19 		return errors.New("given pinning path cannot be empty")
     20 	}
     21 	if currentPath == newPath {
     22 		return nil
     23 	}
     24 
     25 	var statfs unix.Statfs_t
     26 	if err := unix.Statfs(filepath.Dir(newPath), &statfs); err != nil {
     27 		return err
     28 	}
     29 
     30 	fsType := int64(statfs.Type)
     31 	if unsafe.Sizeof(statfs.Type) == 4 {
     32 		// We're on a 32 bit arch, where statfs.Type is int32. bpfFSType is a
     33 		// negative number when interpreted as int32 so we need to cast via
     34 		// uint32 to avoid sign extension.
     35 		fsType = int64(uint32(statfs.Type))
     36 	}
     37 
     38 	if fsType != bpfFSType {
     39 		return fmt.Errorf("%s is not on a bpf filesystem", newPath)
     40 	}
     41 
     42 	defer runtime.KeepAlive(fd)
     43 
     44 	if currentPath == "" {
     45 		return sys.ObjPin(&sys.ObjPinAttr{
     46 			Pathname: sys.NewStringPointer(newPath),
     47 			BpfFd:    fd.Uint(),
     48 		})
     49 	}
     50 
     51 	// Renameat2 is used instead of os.Rename to disallow the new path replacing
     52 	// an existing path.
     53 	err := unix.Renameat2(unix.AT_FDCWD, currentPath, unix.AT_FDCWD, newPath, unix.RENAME_NOREPLACE)
     54 	if err == nil {
     55 		// Object is now moved to the new pinning path.
     56 		return nil
     57 	}
     58 	if !os.IsNotExist(err) {
     59 		return fmt.Errorf("unable to move pinned object to new path %v: %w", newPath, err)
     60 	}
     61 	// Internal state not in sync with the file system so let's fix it.
     62 	return sys.ObjPin(&sys.ObjPinAttr{
     63 		Pathname: sys.NewStringPointer(newPath),
     64 		BpfFd:    fd.Uint(),
     65 	})
     66 }
     67 
     68 func Unpin(pinnedPath string) error {
     69 	if pinnedPath == "" {
     70 		return nil
     71 	}
     72 	err := os.Remove(pinnedPath)
     73 	if err == nil || os.IsNotExist(err) {
     74 		return nil
     75 	}
     76 	return err
     77 }