mirror of
https://github.com/opencontainers/runc.git
synced 2025-11-01 03:22:38 +08:00
Bumps [github.com/cilium/ebpf](https://github.com/cilium/ebpf) from 0.16.0 to 0.17.0. - [Release notes](https://github.com/cilium/ebpf/releases) - [Commits](https://github.com/cilium/ebpf/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: github.com/cilium/ebpf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
158 lines
3.5 KiB
Go
158 lines
3.5 KiB
Go
package btf
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"github.com/cilium/ebpf/internal"
|
|
"github.com/cilium/ebpf/internal/linux"
|
|
)
|
|
|
|
var kernelBTF = struct {
|
|
sync.RWMutex
|
|
kernel *Spec
|
|
modules map[string]*Spec
|
|
}{
|
|
modules: make(map[string]*Spec),
|
|
}
|
|
|
|
// FlushKernelSpec removes any cached kernel type information.
|
|
func FlushKernelSpec() {
|
|
kernelBTF.Lock()
|
|
defer kernelBTF.Unlock()
|
|
|
|
kernelBTF.kernel = nil
|
|
kernelBTF.modules = make(map[string]*Spec)
|
|
}
|
|
|
|
// LoadKernelSpec returns the current kernel's BTF information.
|
|
//
|
|
// Defaults to /sys/kernel/btf/vmlinux and falls back to scanning the file system
|
|
// for vmlinux ELFs. Returns an error wrapping ErrNotSupported if BTF is not enabled.
|
|
func LoadKernelSpec() (*Spec, error) {
|
|
kernelBTF.RLock()
|
|
spec := kernelBTF.kernel
|
|
kernelBTF.RUnlock()
|
|
|
|
if spec == nil {
|
|
kernelBTF.Lock()
|
|
defer kernelBTF.Unlock()
|
|
|
|
spec = kernelBTF.kernel
|
|
}
|
|
|
|
if spec != nil {
|
|
return spec.Copy(), nil
|
|
}
|
|
|
|
spec, _, err := loadKernelSpec()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
kernelBTF.kernel = spec
|
|
return spec.Copy(), nil
|
|
}
|
|
|
|
// LoadKernelModuleSpec returns the BTF information for the named kernel module.
|
|
//
|
|
// Defaults to /sys/kernel/btf/<module>.
|
|
// Returns an error wrapping ErrNotSupported if BTF is not enabled.
|
|
// Returns an error wrapping fs.ErrNotExist if BTF for the specific module doesn't exist.
|
|
func LoadKernelModuleSpec(module string) (*Spec, error) {
|
|
kernelBTF.RLock()
|
|
spec := kernelBTF.modules[module]
|
|
kernelBTF.RUnlock()
|
|
|
|
if spec != nil {
|
|
return spec.Copy(), nil
|
|
}
|
|
|
|
base, err := LoadKernelSpec()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("load kernel spec: %w", err)
|
|
}
|
|
|
|
kernelBTF.Lock()
|
|
defer kernelBTF.Unlock()
|
|
|
|
if spec = kernelBTF.modules[module]; spec != nil {
|
|
return spec.Copy(), nil
|
|
}
|
|
|
|
spec, err = loadKernelModuleSpec(module, base)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
kernelBTF.modules[module] = spec
|
|
return spec.Copy(), nil
|
|
}
|
|
|
|
func loadKernelSpec() (_ *Spec, fallback bool, _ error) {
|
|
fh, err := os.Open("/sys/kernel/btf/vmlinux")
|
|
if err == nil {
|
|
defer fh.Close()
|
|
|
|
spec, err := loadRawSpec(fh, internal.NativeEndian, nil)
|
|
return spec, false, err
|
|
}
|
|
|
|
file, err := findVMLinux()
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
defer file.Close()
|
|
|
|
spec, err := LoadSpecFromReader(file)
|
|
return spec, true, err
|
|
}
|
|
|
|
func loadKernelModuleSpec(module string, base *Spec) (*Spec, error) {
|
|
dir, file := filepath.Split(module)
|
|
if dir != "" || filepath.Ext(file) != "" {
|
|
return nil, fmt.Errorf("invalid module name %q", module)
|
|
}
|
|
|
|
fh, err := os.Open(filepath.Join("/sys/kernel/btf", module))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer fh.Close()
|
|
|
|
return loadRawSpec(fh, internal.NativeEndian, base)
|
|
}
|
|
|
|
// findVMLinux scans multiple well-known paths for vmlinux kernel images.
|
|
func findVMLinux() (*os.File, error) {
|
|
release, err := linux.KernelRelease()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// use same list of locations as libbpf
|
|
// https://github.com/libbpf/libbpf/blob/9a3a42608dbe3731256a5682a125ac1e23bced8f/src/btf.c#L3114-L3122
|
|
locations := []string{
|
|
"/boot/vmlinux-%s",
|
|
"/lib/modules/%s/vmlinux-%[1]s",
|
|
"/lib/modules/%s/build/vmlinux",
|
|
"/usr/lib/modules/%s/kernel/vmlinux",
|
|
"/usr/lib/debug/boot/vmlinux-%s",
|
|
"/usr/lib/debug/boot/vmlinux-%s.debug",
|
|
"/usr/lib/debug/lib/modules/%s/vmlinux",
|
|
}
|
|
|
|
for _, loc := range locations {
|
|
file, err := os.Open(fmt.Sprintf(loc, release))
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
continue
|
|
}
|
|
return file, err
|
|
}
|
|
|
|
return nil, fmt.Errorf("no BTF found for kernel version %s: %w", release, internal.ErrNotSupported)
|
|
}
|