...

Source file src/github.com/cilium/ebpf/btf/handle.go

Documentation: github.com/cilium/ebpf/btf

     1  package btf
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/cilium/ebpf/internal/sys"
     9  	"github.com/cilium/ebpf/internal/unix"
    10  )
    11  
    12  // HandleInfo describes a Handle.
    13  type HandleInfo struct {
    14  	// ID of this handle in the kernel. The ID is only valid as long as the
    15  	// associated handle is kept alive.
    16  	ID ID
    17  
    18  	// Name is an identifying name for the BTF, currently only used by the
    19  	// kernel.
    20  	Name string
    21  
    22  	// IsKernel is true if the BTF originated with the kernel and not
    23  	// userspace.
    24  	IsKernel bool
    25  
    26  	// Size of the raw BTF in bytes.
    27  	size uint32
    28  }
    29  
    30  func newHandleInfoFromFD(fd *sys.FD) (*HandleInfo, error) {
    31  	// We invoke the syscall once with a empty BTF and name buffers to get size
    32  	// information to allocate buffers. Then we invoke it a second time with
    33  	// buffers to receive the data.
    34  	var btfInfo sys.BtfInfo
    35  	if err := sys.ObjInfo(fd, &btfInfo); err != nil {
    36  		return nil, fmt.Errorf("get BTF info for fd %s: %w", fd, err)
    37  	}
    38  
    39  	if btfInfo.NameLen > 0 {
    40  		// NameLen doesn't account for the terminating NUL.
    41  		btfInfo.NameLen++
    42  	}
    43  
    44  	// Don't pull raw BTF by default, since it may be quite large.
    45  	btfSize := btfInfo.BtfSize
    46  	btfInfo.BtfSize = 0
    47  
    48  	nameBuffer := make([]byte, btfInfo.NameLen)
    49  	btfInfo.Name, btfInfo.NameLen = sys.NewSlicePointerLen(nameBuffer)
    50  	if err := sys.ObjInfo(fd, &btfInfo); err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return &HandleInfo{
    55  		ID:       ID(btfInfo.Id),
    56  		Name:     unix.ByteSliceToString(nameBuffer),
    57  		IsKernel: btfInfo.KernelBtf != 0,
    58  		size:     btfSize,
    59  	}, nil
    60  }
    61  
    62  // IsModule returns true if the BTF is for the kernel itself.
    63  func (i *HandleInfo) IsVmlinux() bool {
    64  	return i.IsKernel && i.Name == "vmlinux"
    65  }
    66  
    67  // IsModule returns true if the BTF is for a kernel module.
    68  func (i *HandleInfo) IsModule() bool {
    69  	return i.IsKernel && i.Name != "vmlinux"
    70  }
    71  
    72  // HandleIterator allows enumerating BTF blobs loaded into the kernel.
    73  type HandleIterator struct {
    74  	// The ID of the last retrieved handle. Only valid after a call to Next.
    75  	ID  ID
    76  	err error
    77  }
    78  
    79  // Next retrieves a handle for the next BTF blob.
    80  //
    81  // [Handle.Close] is called if *handle is non-nil to avoid leaking fds.
    82  //
    83  // Returns true if another BTF blob was found. Call [HandleIterator.Err] after
    84  // the function returns false.
    85  func (it *HandleIterator) Next(handle **Handle) bool {
    86  	if *handle != nil {
    87  		(*handle).Close()
    88  		*handle = nil
    89  	}
    90  
    91  	id := it.ID
    92  	for {
    93  		attr := &sys.BtfGetNextIdAttr{Id: id}
    94  		err := sys.BtfGetNextId(attr)
    95  		if errors.Is(err, os.ErrNotExist) {
    96  			// There are no more BTF objects.
    97  			return false
    98  		} else if err != nil {
    99  			it.err = fmt.Errorf("get next BTF ID: %w", err)
   100  			return false
   101  		}
   102  
   103  		id = attr.NextId
   104  		*handle, err = NewHandleFromID(id)
   105  		if errors.Is(err, os.ErrNotExist) {
   106  			// Try again with the next ID.
   107  			continue
   108  		} else if err != nil {
   109  			it.err = fmt.Errorf("retrieve handle for ID %d: %w", id, err)
   110  			return false
   111  		}
   112  
   113  		it.ID = id
   114  		return true
   115  	}
   116  }
   117  
   118  // Err returns an error if iteration failed for some reason.
   119  func (it *HandleIterator) Err() error {
   120  	return it.err
   121  }
   122  

View as plain text