From c92a463f431cb7a50e1b6962197e982d4db5af6c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 22 Jun 2024 07:54:03 +0000 Subject: [PATCH] link: allow pinning perf event based links Support pinning of Kprobe and Uprobe links. It's not possible to retrieve the perf event of a pinned link, so PerfEvent() now returns an error. Signed-off-by: Jiri Olsa --- link/kprobe_multi.go | 8 -------- link/link.go | 2 +- link/perf_event.go | 29 ++++++++++------------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/link/kprobe_multi.go b/link/kprobe_multi.go index 850c5f8b5..f7a8291f9 100644 --- a/link/kprobe_multi.go +++ b/link/kprobe_multi.go @@ -130,14 +130,6 @@ func (kml *kprobeMultiLink) Update(prog *ebpf.Program) error { return fmt.Errorf("update kprobe_multi: %w", ErrNotSupported) } -func (kml *kprobeMultiLink) Pin(string) error { - return fmt.Errorf("pin kprobe_multi: %w", ErrNotSupported) -} - -func (kml *kprobeMultiLink) Unpin() error { - return fmt.Errorf("unpin kprobe_multi: %w", ErrNotSupported) -} - func (kml *kprobeMultiLink) Info() (*Info, error) { var info sys.KprobeMultiLinkInfo if err := sys.ObjInfo(kml.fd, &info); err != nil { diff --git a/link/link.go b/link/link.go index 9e8ca49c6..9c34616c9 100644 --- a/link/link.go +++ b/link/link.go @@ -119,7 +119,7 @@ func wrapRawLink(raw *RawLink) (_ Link, err error) { case UprobeMultiType: return &uprobeMultiLink{*raw}, nil case PerfEventType: - return nil, fmt.Errorf("recovering perf event fd: %w", ErrNotSupported) + return &perfEventLink{*raw, nil}, nil case TCXType: return &tcxLink{*raw}, nil case NetfilterType: diff --git a/link/perf_event.go b/link/perf_event.go index 89eab233b..1d8feb58c 100644 --- a/link/perf_event.go +++ b/link/perf_event.go @@ -99,30 +99,16 @@ type perfEventLink struct { func (pl *perfEventLink) isLink() {} -// Pinning requires the underlying perf event FD to stay open. -// -// | PerfEvent FD | BpfLink FD | Works | -// |--------------|------------|-------| -// | Open | Open | Yes | -// | Closed | Open | No | -// | Open | Closed | No (Pin() -> EINVAL) | -// | Closed | Closed | No (Pin() -> EINVAL) | -// -// There is currently no pretty way to recover the perf event FD -// when loading a pinned link, so leave as not supported for now. -func (pl *perfEventLink) Pin(string) error { - return fmt.Errorf("perf event link pin: %w", ErrNotSupported) -} - -func (pl *perfEventLink) Unpin() error { - return fmt.Errorf("perf event link unpin: %w", ErrNotSupported) -} - func (pl *perfEventLink) Close() error { if err := pl.fd.Close(); err != nil { return fmt.Errorf("perf link close: %w", err) } + // when created from pinned link + if pl.pe == nil { + return nil + } + if err := pl.pe.Close(); err != nil { return fmt.Errorf("perf event close: %w", err) } @@ -136,6 +122,11 @@ func (pl *perfEventLink) Update(prog *ebpf.Program) error { var _ PerfEvent = (*perfEventLink)(nil) func (pl *perfEventLink) PerfEvent() (*os.File, error) { + // when created from pinned link + if pl.pe == nil { + return nil, ErrNotSupported + } + fd, err := pl.pe.fd.Dup() if err != nil { return nil, err