Skip to content

Commit

Permalink
Remove support for mounting bpffs
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelroquetto committed Oct 11, 2024
1 parent 70cb2de commit 4cf890f
Show file tree
Hide file tree
Showing 14 changed files with 5 additions and 186 deletions.
3 changes: 0 additions & 3 deletions pkg/beyla/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"io"
"log/slog"
"os"
"time"

"github.com/caarlos0/env/v9"
Expand Down Expand Up @@ -47,8 +46,6 @@ var DefaultConfig = Config{
EBPF: config.EPPFTracer{
BatchLength: 100,
BatchTimeout: time.Second,
BpfBaseDir: "/var/run/beyla",
BpfPath: fmt.Sprintf("beyla-%d", os.Getpid()),
HTTPRequestTimeout: 30 * time.Second,
},
Grafana: otel.GrafanaConfig{
Expand Down
2 changes: 0 additions & 2 deletions pkg/beyla/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ network:
EBPF: config.EPPFTracer{
BatchLength: 100,
BatchTimeout: time.Second,
BpfBaseDir: "/var/run/beyla",
BpfPath: DefaultConfig.EBPF.BpfPath,
HTTPRequestTimeout: 30 * time.Second,
},
Grafana: otel.GrafanaConfig{
Expand Down
8 changes: 0 additions & 8 deletions pkg/config/ebpf_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ type EPPFTracer struct {
// reach the BatchLength size
BatchTimeout time.Duration `yaml:"batch_timeout" env:"BEYLA_BPF_BATCH_TIMEOUT"`

// BpfBaseDir specifies the base directory where the BPF pinned maps will be mounted.
// By default, it will be /var/run/beyla
BpfBaseDir string `yaml:"bpf_fs_base_dir" env:"BEYLA_BPF_FS_BASE_DIR"`

// BpfPath specifies the path in the base directory where the BPF pinned maps will be mounted.
// By default, it will be beyla-<pid>.
BpfPath string `yaml:"bpf_fs_path" env:"BEYLA_BPF_FS_PATH"`

// If enabled, the kprobes based HTTP request tracking will start tracking the request
// headers to process any 'Traceparent' fields.
TrackRequestHeaders bool `yaml:"track_request_headers" env:"BEYLA_BPF_TRACK_REQUEST_HEADERS"`
Expand Down
2 changes: 0 additions & 2 deletions pkg/internal/appolly/appolly.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/grafana/beyla/pkg/beyla"
"github.com/grafana/beyla/pkg/internal/discover"
"github.com/grafana/beyla/pkg/internal/ebpf"
"github.com/grafana/beyla/pkg/internal/pipe"
"github.com/grafana/beyla/pkg/internal/pipe/global"
"github.com/grafana/beyla/pkg/internal/request"
Expand Down Expand Up @@ -109,7 +108,6 @@ func (i *Instrumenter) ReadAndForward() error {
bp.Run(i.ctx)

log.Info("exiting auto-instrumenter")
discover.UnmountBPFFS(ebpf.BuildPinPath(i.config), log)

return nil
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/internal/discover/attacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ type TraceAttacher struct {
DiscoveredTracers chan *ebpf.Instrumentable
DeleteTracers chan *ebpf.Instrumentable
Metrics imetrics.Reporter
pinPath string
beylaPID int

// processInstances keeps track of the instances of each process. This will help making sure
Expand Down Expand Up @@ -56,7 +55,6 @@ func (ta *TraceAttacher) attacherLoop() (pipe.FinalFunc[[]Event[ebpf.Instrumenta
ta.existingTracers = map[uint64]*ebpf.ProcessTracer{}
ta.processInstances = maps.MultiCounter[uint64]{}
ta.beylaPID = os.Getpid()
ta.pinPath = ebpf.BuildPinPath(ta.Cfg)

if err := ta.init(); err != nil {
ta.log.Error("cant start process tracer. Stopping it", "error", err)
Expand Down
79 changes: 0 additions & 79 deletions pkg/internal/discover/attacher_linux.go
Original file line number Diff line number Diff line change
@@ -1,96 +1,17 @@
package discover

import (
"context"
"fmt"
"log/slog"
"os"
"time"

"github.com/cilium/ebpf/rlimit"
"golang.org/x/sys/unix"

"github.com/grafana/beyla/pkg/internal/helpers"
)

func (ta *TraceAttacher) close() {
ta.unmountBpfPinPath()
}

func (ta *TraceAttacher) mountBpfPinPath() error {
ta.log.Debug("mounting BPF map pinning", "path", ta.pinPath)
if _, err := os.Stat(ta.pinPath); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("accessing %s stat: %w", ta.pinPath, err)
}
ta.log.Debug("BPF map pinning path does not exist. Creating before mounting")
if err := os.MkdirAll(ta.pinPath, 0700); err != nil {
return fmt.Errorf("creating directory %s: %w", ta.pinPath, err)
}
}

return ta.bpfMount(ta.pinPath)
}

func UnmountBPFFS(pinPath string, log *slog.Logger) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

done := make(chan struct{})

go func() {
if err := unix.Unmount(pinPath, unix.MNT_FORCE|unix.MNT_DETACH); err != nil {
log.Debug("can't unmount pinned root. Try unmounting and removing it manually", "error", err)
}
log.Debug("unmounted bpf file system")
if err := os.RemoveAll(pinPath); err != nil {
log.Warn("can't remove pinned root. Try removing it manually", "error", err)
} else {
log.Debug("removed pin path")
}
close(done)
}()

select {
case <-done:
log.Debug("Unmount BPF finished")
case <-ctx.Done():
log.Debug("Timed out while waiting for BPF unmount to finish")
}
}

func (ta *TraceAttacher) unmountBpfPinPath() {
UnmountBPFFS(ta.pinPath, ta.log)
}

func (ta *TraceAttacher) bpfMount(pinPath string) error {
mounted, bpffsInstance, err := IsMountFS(FilesystemTypeBPFFS, pinPath)
if err != nil {
return err
}
if !mounted {
caps, err := helpers.GetCurrentProcCapabilities()

if err == nil && !caps.Has(unix.CAP_SYS_ADMIN) {
return fmt.Errorf("beyla requires CAP_SYS_ADMIN in order to mount %s", pinPath)
}

return unix.Mount(pinPath, pinPath, "bpf", 0, "")
}
if !bpffsInstance {
return fmt.Errorf("mount in the custom directory %s has a different filesystem than BPFFS", pinPath)
}
ta.log.Info(fmt.Sprintf("Detected mounted BPF filesystem at %v", pinPath))

return nil
}

func (ta *TraceAttacher) init() error {
if err := rlimit.RemoveMemlock(); err != nil {
return fmt.Errorf("removing memory lock: %w", err)
}
if err := ta.mountBpfPinPath(); err != nil {
return fmt.Errorf("can't mount BPF filesystem: %w", err)
}
return nil
}
55 changes: 0 additions & 55 deletions pkg/internal/discover/attacher_linux_privileged_test.go

This file was deleted.

2 changes: 0 additions & 2 deletions pkg/internal/discover/attacher_nolinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ func (ta *TraceAttacher) init() error {
}

func (ta *TraceAttacher) close() {}

func UnmountBPFFS(_ string, _ *slog.Logger) {}
1 change: 0 additions & 1 deletion pkg/internal/discover/mountinfo_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
const (
// FilesystemType superblock magic numbers for filesystems,
// to be used for IsMountFS.
FilesystemTypeBPFFS = unix.BPF_FS_MAGIC
FilesystemTypeCgroup2 = unix.CGROUP2_SUPER_MAGIC
)

Expand Down
9 changes: 0 additions & 9 deletions pkg/internal/discover/mountinfo_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,4 @@ func TestIsMountFS(t *testing.T) {
assert.NoError(t, err)
assert.True(t, mounted)
assert.True(t, matched)

mounted, matched, err = IsMountFS(FilesystemTypeBPFFS, "/sys/fs/bpf")
assert.NoError(t, err)
// We can't expect /sys/fs/bpf is mounted, so only check fstype
// if it is mounted. IOW, if /sys/fs/bpf is a mount point,
// we expect it to be bpffs.
if mounted {
assert.True(t, matched)
}
}
4 changes: 2 additions & 2 deletions pkg/internal/discover/watcher_proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,10 @@ func fetchProcessPorts(scanPorts bool) (map[PID]processAttrs, error) {

func loadBPFWatcher(cfg *beyla.Config, events chan<- watcher.Event) error {
wt := watcher.New(cfg, events)
return ebpf.RunUtilityTracer(wt, ebpf.BuildPinPath(cfg))
return ebpf.RunUtilityTracer(wt)
}

func loadBPFLogger(cfg *beyla.Config) error {
wt := logger.New(cfg)
return ebpf.RunUtilityTracer(wt, ebpf.BuildPinPath(cfg))
return ebpf.RunUtilityTracer(wt)
}
1 change: 0 additions & 1 deletion pkg/internal/ebpf/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ const (
type ProcessTracer struct {
log *slog.Logger //nolint:unused
Programs []Tracer
PinPath string

SystemWide bool
Type ProcessTracerType
Expand Down
6 changes: 1 addition & 5 deletions pkg/internal/ebpf/tracer_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ func (pt *ProcessTracer) Init() error {
return nil
}

func BuildPinPath(_ *beyla.Config) string {
return ""
}

func (pt *ProcessTracer) NewExecutable(_ *Instrumentable) error {
return nil
}
Expand All @@ -39,6 +35,6 @@ func (pt *ProcessTracer) NewExecutableInstance(_ *link.Executable, _ *Instrument

func (pt *ProcessTracer) UnlinkExecutable(_ *exec.FileInfo) {}

func RunUtilityTracer(_ UtilityTracer, _ string) error {
func RunUtilityTracer(_ UtilityTracer) error {
return nil
}
17 changes: 2 additions & 15 deletions pkg/internal/ebpf/tracer_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"log/slog"
"os"
"path"
"reflect"
"strings"
"sync"
Expand Down Expand Up @@ -70,7 +69,6 @@ func resolveInternalMaps(spec *ebpf.CollectionSpec) (*ebpf.CollectionOptions, er
func NewProcessTracer(cfg *beyla.Config, tracerType ProcessTracerType, programs []Tracer) *ProcessTracer {
return &ProcessTracer{
Programs: programs,
PinPath: BuildPinPath(cfg),
SystemWide: cfg.Discovery.SystemWide,
Type: tracerType,
Instrumentables: map[uint64]*instrumenter{},
Expand All @@ -92,13 +90,6 @@ func (pt *ProcessTracer) Run(ctx context.Context, out chan<- []request.Span) {
}()
}

// BuildPinPath pinpath must be unique for a given executable group
// it will be:
// - current beyla PID
func BuildPinPath(cfg *beyla.Config) string {
return path.Join(cfg.EBPF.BpfBaseDir, cfg.EBPF.BpfPath)
}

func (pt *ProcessTracer) loadSpec(p Tracer) (*ebpf.CollectionSpec, error) {
spec, err := p.Load()
if err != nil {
Expand All @@ -121,7 +112,7 @@ func (pt *ProcessTracer) loadTracers() error {

for _, p := range pt.Programs {
plog := log.With("program", reflect.TypeOf(p))
plog.Debug("loading eBPF program", "PinPath", pt.PinPath, "type", pt.Type)
plog.Debug("loading eBPF program", "type", pt.Type)
spec, err := pt.loadSpec(p)
if err != nil {
return err
Expand All @@ -132,7 +123,6 @@ func (pt *ProcessTracer) loadTracers() error {
return err
}

collOpts.Maps = ebpf.MapOptions{PinPath: pt.PinPath}
collOpts.Programs = ebpf.ProgramOptions{LogSize: 640 * 1024}

if err := spec.LoadAndAssign(p.BpfObjects(), collOpts); err != nil {
Expand All @@ -151,7 +141,6 @@ func (pt *ProcessTracer) loadTracers() error {
return err
}

collOpts.Maps = ebpf.MapOptions{PinPath: pt.PinPath}
collOpts.Programs = ebpf.ProgramOptions{LogSize: 640 * 1024}

err = spec.LoadAndAssign(p.BpfObjects(), collOpts)
Expand Down Expand Up @@ -266,7 +255,7 @@ func printVerifierErrorInfo(err error) {
}
}

func RunUtilityTracer(p UtilityTracer, pinPath string) error {
func RunUtilityTracer(p UtilityTracer) error {
i := instrumenter{}
plog := ptlog()
plog.Debug("loading independent eBPF program")
Expand All @@ -280,8 +269,6 @@ func RunUtilityTracer(p UtilityTracer, pinPath string) error {
return err
}

collOpts.Maps = ebpf.MapOptions{PinPath: pinPath}

if err := spec.LoadAndAssign(p.BpfObjects(), collOpts); err != nil {
printVerifierErrorInfo(err)
return fmt.Errorf("loading and assigning BPF objects: %w", err)
Expand Down

0 comments on commit 4cf890f

Please sign in to comment.