diff --git a/cmd/kubectl-gadget/opensnoop.go b/cmd/kubectl-gadget/opensnoop.go deleted file mode 100644 index 41a08acdfd..0000000000 --- a/cmd/kubectl-gadget/opensnoop.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2019-2021 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "encoding/json" - "fmt" - "os" - "strings" - - "github.com/kinvolk/inspektor-gadget/cmd/kubectl-gadget/utils" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/types" - eventtypes "github.com/kinvolk/inspektor-gadget/pkg/types" - "github.com/spf13/cobra" -) - -var opensnoopCmd = &cobra.Command{ - Use: "opensnoop", - Short: "Trace open() system calls", - RunE: func(cmd *cobra.Command, args []string) error { - // print header - switch params.OutputMode { - case utils.OutputModeCustomColumns: - fmt.Println(getCustomOpensnoopColsHeader(params.CustomColumns)) - case utils.OutputModeColumns: - fmt.Printf("%-16s %-16s %-16s %-16s %-6s %-16s %-3s %3s %s\n", - "NODE", "NAMESPACE", "POD", "CONTAINER", - "PID", "COMM", "FD", "ERR", "PATH") - } - - config := &utils.TraceConfig{ - GadgetName: "opensnoop", - Operation: "start", - TraceOutputMode: "Stream", - TraceOutputState: "Started", - CommonFlags: ¶ms, - } - - err := utils.RunTraceAndPrintStream(config, opensnoopTransformLine) - if err != nil { - return fmt.Errorf("failed to run tracer: %w", err) - } - - return nil - }, -} - -func init() { - rootCmd.AddCommand(opensnoopCmd) - utils.AddCommonFlags(opensnoopCmd, ¶ms) -} - -// opensnoopTransformLine is called to transform an event to columns -// format according to the parameters -func opensnoopTransformLine(line string) string { - var sb strings.Builder - var e types.Event - - if err := json.Unmarshal([]byte(line), &e); err != nil { - fmt.Fprintf(os.Stderr, "error unmarshalling json: %s", err) - return "" - } - - if e.Type == eventtypes.ERR || e.Type == eventtypes.WARN || - e.Type == eventtypes.DEBUG || e.Type == eventtypes.INFO { - fmt.Fprintf(os.Stderr, "%s: node %s: %s", e.Type, e.Node, e.Message) - return "" - } - - if e.Type != eventtypes.NORMAL { - return "" - } - - switch params.OutputMode { - case utils.OutputModeColumns: - sb.WriteString(fmt.Sprintf("%-16s %-16s %-16s %-16s %-6d %-16s %-3d %3d %s", - e.Node, e.Namespace, e.Pod, e.Container, - e.Pid, e.Comm, e.Fd, e.Err, e.Path)) - case utils.OutputModeCustomColumns: - for _, col := range params.CustomColumns { - switch col { - case "node": - sb.WriteString(fmt.Sprintf("%-16s", e.Node)) - case "namespace": - sb.WriteString(fmt.Sprintf("%-16s", e.Namespace)) - case "pod": - sb.WriteString(fmt.Sprintf("%-16s", e.Pod)) - case "container": - sb.WriteString(fmt.Sprintf("%-16s", e.Container)) - case "pid": - sb.WriteString(fmt.Sprintf("%-6d", e.Pid)) - case "comm": - sb.WriteString(fmt.Sprintf("%-16s", e.Comm)) - case "fd": - sb.WriteString(fmt.Sprintf("%-2d", e.Fd)) - case "err": - sb.WriteString(fmt.Sprintf("%-3d", e.Err)) - case "path": - sb.WriteString(fmt.Sprintf("%-24s", e.Path)) - } - sb.WriteRune(' ') - } - } - - return sb.String() -} - -func getCustomOpensnoopColsHeader(cols []string) string { - var sb strings.Builder - - for _, col := range cols { - switch col { - case "node": - sb.WriteString(fmt.Sprintf("%-16s", "NODE")) - case "namespace": - sb.WriteString(fmt.Sprintf("%-16s", "NAMESPACE")) - case "pod": - sb.WriteString(fmt.Sprintf("%-16s", "POD")) - case "container": - sb.WriteString(fmt.Sprintf("%-16s", "CONTAINER")) - case "pid": - sb.WriteString(fmt.Sprintf("%-6s", "PID")) - case "comm": - sb.WriteString(fmt.Sprintf("%-16s", "COMM")) - case "fd": - sb.WriteString(fmt.Sprintf("%-3s", "FD")) - case "err": - sb.WriteString(fmt.Sprintf("%-3s", "ERR")) - case "path": - sb.WriteString(fmt.Sprintf("%-24s", "PATH")) - } - sb.WriteRune(' ') - } - - return sb.String() -} diff --git a/pkg/gadget-collection/gadget-collection.go b/pkg/gadget-collection/gadget-collection.go index a2dfb0da87..16e30b554d 100644 --- a/pkg/gadget-collection/gadget-collection.go +++ b/pkg/gadget-collection/gadget-collection.go @@ -23,7 +23,6 @@ import ( "github.com/kinvolk/inspektor-gadget/pkg/gadgets/filetop" networkpolicyadvisor "github.com/kinvolk/inspektor-gadget/pkg/gadgets/networkpolicy" "github.com/kinvolk/inspektor-gadget/pkg/gadgets/oomkill" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop" processcollector "github.com/kinvolk/inspektor-gadget/pkg/gadgets/process-collector" "github.com/kinvolk/inspektor-gadget/pkg/gadgets/seccomp" "github.com/kinvolk/inspektor-gadget/pkg/gadgets/snisnoop" @@ -38,7 +37,6 @@ func TraceFactories() map[string]gadgets.TraceFactory { "dns": dns.NewFactory(), "execsnoop": execsnoop.NewFactory(), "filetop": filetop.NewFactory(), - "opensnoop": opensnoop.NewFactory(), "network-policy-advisor": networkpolicyadvisor.NewFactory(), "oomkill": oomkill.NewFactory(), "process-collector": processcollector.NewFactory(), diff --git a/pkg/gadgets/opensnoop/gadget.go b/pkg/gadgets/opensnoop/gadget.go deleted file mode 100644 index 9b2ce81710..0000000000 --- a/pkg/gadgets/opensnoop/gadget.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2019-2022 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package opensnoop - -import ( - "encoding/json" - "fmt" - - log "github.com/sirupsen/logrus" - - "github.com/kinvolk/inspektor-gadget/pkg/gadgets" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/tracer" - - coretracer "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/tracer/core" - standardtracer "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/tracer/standard" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/types" - - gadgetv1alpha1 "github.com/kinvolk/inspektor-gadget/pkg/apis/gadget/v1alpha1" -) - -type Trace struct { - resolver gadgets.Resolver - - started bool - tracer tracer.Tracer -} - -type TraceFactory struct { - gadgets.BaseFactory -} - -func NewFactory() gadgets.TraceFactory { - return &TraceFactory{ - BaseFactory: gadgets.BaseFactory{DeleteTrace: deleteTrace}, - } -} - -func (f *TraceFactory) Description() string { - return `opensnoop traces open() system calls` -} - -func (f *TraceFactory) OutputModesSupported() map[string]struct{} { - return map[string]struct{}{ - "Stream": {}, - } -} - -func deleteTrace(name string, t interface{}) { - trace := t.(*Trace) - if trace.tracer != nil { - trace.tracer.Stop() - } -} - -func (f *TraceFactory) Operations() map[string]gadgets.TraceOperation { - n := func() interface{} { - return &Trace{ - resolver: f.Resolver, - } - } - - return map[string]gadgets.TraceOperation{ - "start": { - Doc: "Start opensnoop gadget", - Operation: func(name string, trace *gadgetv1alpha1.Trace) { - f.LookupOrCreate(name, n).(*Trace).Start(trace) - }, - }, - "stop": { - Doc: "Stop opensnoop gadget", - Operation: func(name string, trace *gadgetv1alpha1.Trace) { - f.LookupOrCreate(name, n).(*Trace).Stop(trace) - }, - }, - } -} - -func (t *Trace) Start(trace *gadgetv1alpha1.Trace) { - if t.started { - gadgets.CleanupTraceStatus(trace) - trace.Status.State = "Started" - return - } - - traceName := gadgets.TraceName(trace.ObjectMeta.Namespace, trace.ObjectMeta.Name) - - eventCallback := func(event types.Event) { - r, err := json.Marshal(event) - if err != nil { - log.Warnf("Gadget %s: error marshalling event: %s", trace.Spec.Gadget, err) - return - } - t.resolver.PublishEvent(traceName, string(r)) - } - - var err error - - config := &tracer.Config{ - MountnsMap: gadgets.TracePinPath(trace.ObjectMeta.Namespace, trace.ObjectMeta.Name), - } - t.tracer, err = coretracer.NewTracer(config, t.resolver, eventCallback, trace.Spec.Node) - if err != nil { - // TODO: The following line causes the client to fail. - // trace.Status.OperationWarning = fmt.Sprint("failed to create core tracer. Falling back to standard one") - - // fallback to standard tracer - log.Infof("Gadget %s: falling back to standard tracer. CO-RE tracer failed: %s", - trace.Spec.Gadget, err) - - t.tracer, err = standardtracer.NewTracer(config, t.resolver, eventCallback, trace.Spec.Node) - if err != nil { - trace.Status.OperationError = fmt.Sprintf("failed to create tracer: %s", err) - return - } - } - - t.started = true - - gadgets.CleanupTraceStatus(trace) - trace.Status.State = "Started" -} - -func (t *Trace) Stop(trace *gadgetv1alpha1.Trace) { - if !t.started { - trace.Status.OperationError = "Not started" - return - } - - t.tracer.Stop() - t.tracer = nil - t.started = false - - trace.Status.OperationError = "" - trace.Status.State = "Stopped" -} diff --git a/pkg/gadgets/opensnoop/tracer/core/bpf/Makefile b/pkg/gadgets/opensnoop/tracer/core/bpf/Makefile deleted file mode 100644 index 447921dda2..0000000000 --- a/pkg/gadgets/opensnoop/tracer/core/bpf/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -.PHONY: all -all: - GO111MODULE=on CGO_ENABLED=1 GOOS=linux go generate ../ - -clean: - rm -f ../opensnoop_bpf* diff --git a/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.bpf.c b/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.bpf.c deleted file mode 100644 index 3821c24d02..0000000000 --- a/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.bpf.c +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2019 Facebook -// Copyright (c) 2020 Netflix -#include -#include -#include -#include "opensnoop.h" - -#define TASK_RUNNING 0 - -const volatile __u64 min_us = 0; -const volatile pid_t targ_pid = 0; -const volatile pid_t targ_tgid = 0; -const volatile uid_t targ_uid = 0; -const volatile bool targ_failed = false; -const volatile bool filter_by_mnt_ns = false; - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 10240); - __type(key, u32); - __type(value, struct args_t); -} start SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); -} events SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 1024); - __uint(key_size, sizeof(u64)); - __uint(value_size, sizeof(u32)); -} mount_ns_set SEC(".maps"); - -static __always_inline bool valid_uid(uid_t uid) { - return uid != INVALID_UID; -} - -static __always_inline -bool trace_allowed(u32 tgid, u32 pid) -{ - struct task_struct *task; - u64 mntns_id; - u32 uid; - - /* filters */ - if (targ_tgid && targ_tgid != tgid) - return false; - if (targ_pid && targ_pid != pid) - return false; - if (valid_uid(targ_uid)) { - uid = (u32)bpf_get_current_uid_gid(); - if (targ_uid != uid) { - return false; - } - } - - task = (struct task_struct*)bpf_get_current_task(); - mntns_id = (u64) BPF_CORE_READ(task, nsproxy, mnt_ns, ns.inum); - - if (filter_by_mnt_ns && !bpf_map_lookup_elem(&mount_ns_set, &mntns_id)) - return false; - - return true; -} - -SEC("tracepoint/syscalls/sys_enter_open") -int tracepoint__syscalls__sys_enter_open(struct trace_event_raw_sys_enter* ctx) -{ - u64 id = bpf_get_current_pid_tgid(); - /* use kernel terminology here for tgid/pid: */ - u32 tgid = id >> 32; - u32 pid = id; - - /* store arg info for later lookup */ - if (trace_allowed(tgid, pid)) { - struct args_t args = {}; - args.fname = (const char *)ctx->args[0]; - args.flags = (int)ctx->args[1]; - bpf_map_update_elem(&start, &pid, &args, 0); - } - return 0; -} - -SEC("tracepoint/syscalls/sys_enter_openat") -int tracepoint__syscalls__sys_enter_openat(struct trace_event_raw_sys_enter* ctx) -{ - u64 id = bpf_get_current_pid_tgid(); - /* use kernel terminology here for tgid/pid: */ - u32 tgid = id >> 32; - u32 pid = id; - - /* store arg info for later lookup */ - if (trace_allowed(tgid, pid)) { - struct args_t args = {}; - args.fname = (const char *)ctx->args[1]; - args.flags = (int)ctx->args[2]; - bpf_map_update_elem(&start, &pid, &args, 0); - } - return 0; -} - -static __always_inline -int trace_exit(struct trace_event_raw_sys_exit* ctx) -{ - struct event event = {}; - struct args_t *ap; - int ret; - u32 pid = bpf_get_current_pid_tgid(); - struct task_struct *task; - u64 mntns_id; - - ap = bpf_map_lookup_elem(&start, &pid); - if (!ap) - return 0; /* missed entry */ - ret = ctx->ret; - if (targ_failed && ret >= 0) - goto cleanup; /* want failed only */ - - task = (struct task_struct*)bpf_get_current_task(); - mntns_id = (u64) BPF_CORE_READ(task, nsproxy, mnt_ns, ns.inum); - - if (filter_by_mnt_ns && !bpf_map_lookup_elem(&mount_ns_set, &mntns_id)) - return 0; - - /* event data */ - event.pid = bpf_get_current_pid_tgid() >> 32; - event.uid = bpf_get_current_uid_gid(); - bpf_get_current_comm(&event.comm, sizeof(event.comm)); - bpf_probe_read_user_str(&event.fname, sizeof(event.fname), ap->fname); - event.flags = ap->flags; - event.ret = ret; - event.mntns_id = mntns_id; - - /* emit event */ - bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, - &event, sizeof(event)); - -cleanup: - bpf_map_delete_elem(&start, &pid); - return 0; -} - -SEC("tracepoint/syscalls/sys_exit_open") -int tracepoint__syscalls__sys_exit_open(struct trace_event_raw_sys_exit* ctx) -{ - return trace_exit(ctx); -} - -SEC("tracepoint/syscalls/sys_exit_openat") -int tracepoint__syscalls__sys_exit_openat(struct trace_event_raw_sys_exit* ctx) -{ - return trace_exit(ctx); -} - -char LICENSE[] SEC("license") = "GPL"; diff --git a/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.h b/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.h deleted file mode 100644 index 7c54a210ba..0000000000 --- a/pkg/gadgets/opensnoop/tracer/core/bpf/opensnoop.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ -#ifndef __OPENSNOOP_H -#define __OPENSNOOP_H - -#define TASK_COMM_LEN 16 -#define NAME_MAX 255 -#define INVALID_UID ((uid_t)-1) - -struct args_t { - const char *fname; - int flags; -}; - -struct event { - /* user terminology for pid: */ - __u64 ts; - __u32 pid; - __u32 uid; - __u64 mntns_id; - int ret; - int flags; - char comm[TASK_COMM_LEN]; - char fname[NAME_MAX]; -}; - -#endif /* __OPENSNOOP_H */ diff --git a/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.go b/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.go deleted file mode 100644 index 8c16d82ef3..0000000000 --- a/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.go +++ /dev/null @@ -1,134 +0,0 @@ -// Code generated by bpf2go; DO NOT EDIT. -//go:build 386 || amd64 || amd64p32 || arm || arm64 || mips64le || mips64p32le || mipsle || ppc64le || riscv64 -// +build 386 amd64 amd64p32 arm arm64 mips64le mips64p32le mipsle ppc64le riscv64 - -package tracer - -import ( - "bytes" - _ "embed" - "fmt" - "io" - - "github.com/cilium/ebpf" -) - -// loadOpensnoop returns the embedded CollectionSpec for opensnoop. -func loadOpensnoop() (*ebpf.CollectionSpec, error) { - reader := bytes.NewReader(_OpensnoopBytes) - spec, err := ebpf.LoadCollectionSpecFromReader(reader) - if err != nil { - return nil, fmt.Errorf("can't load opensnoop: %w", err) - } - - return spec, err -} - -// loadOpensnoopObjects loads opensnoop and converts it into a struct. -// -// The following types are suitable as obj argument: -// -// *opensnoopObjects -// *opensnoopPrograms -// *opensnoopMaps -// -// See ebpf.CollectionSpec.LoadAndAssign documentation for details. -func loadOpensnoopObjects(obj interface{}, opts *ebpf.CollectionOptions) error { - spec, err := loadOpensnoop() - if err != nil { - return err - } - - return spec.LoadAndAssign(obj, opts) -} - -// opensnoopSpecs contains maps and programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type opensnoopSpecs struct { - opensnoopProgramSpecs - opensnoopMapSpecs -} - -// opensnoopSpecs contains programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type opensnoopProgramSpecs struct { - TracepointSyscallsSysEnterOpen *ebpf.ProgramSpec `ebpf:"tracepoint__syscalls__sys_enter_open"` - TracepointSyscallsSysEnterOpenat *ebpf.ProgramSpec `ebpf:"tracepoint__syscalls__sys_enter_openat"` - TracepointSyscallsSysExitOpen *ebpf.ProgramSpec `ebpf:"tracepoint__syscalls__sys_exit_open"` - TracepointSyscallsSysExitOpenat *ebpf.ProgramSpec `ebpf:"tracepoint__syscalls__sys_exit_openat"` -} - -// opensnoopMapSpecs contains maps before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type opensnoopMapSpecs struct { - Events *ebpf.MapSpec `ebpf:"events"` - MountNsSet *ebpf.MapSpec `ebpf:"mount_ns_set"` - Start *ebpf.MapSpec `ebpf:"start"` -} - -// opensnoopObjects contains all objects after they have been loaded into the kernel. -// -// It can be passed to loadOpensnoopObjects or ebpf.CollectionSpec.LoadAndAssign. -type opensnoopObjects struct { - opensnoopPrograms - opensnoopMaps -} - -func (o *opensnoopObjects) Close() error { - return _OpensnoopClose( - &o.opensnoopPrograms, - &o.opensnoopMaps, - ) -} - -// opensnoopMaps contains all maps after they have been loaded into the kernel. -// -// It can be passed to loadOpensnoopObjects or ebpf.CollectionSpec.LoadAndAssign. -type opensnoopMaps struct { - Events *ebpf.Map `ebpf:"events"` - MountNsSet *ebpf.Map `ebpf:"mount_ns_set"` - Start *ebpf.Map `ebpf:"start"` -} - -func (m *opensnoopMaps) Close() error { - return _OpensnoopClose( - m.Events, - m.MountNsSet, - m.Start, - ) -} - -// opensnoopPrograms contains all programs after they have been loaded into the kernel. -// -// It can be passed to loadOpensnoopObjects or ebpf.CollectionSpec.LoadAndAssign. -type opensnoopPrograms struct { - TracepointSyscallsSysEnterOpen *ebpf.Program `ebpf:"tracepoint__syscalls__sys_enter_open"` - TracepointSyscallsSysEnterOpenat *ebpf.Program `ebpf:"tracepoint__syscalls__sys_enter_openat"` - TracepointSyscallsSysExitOpen *ebpf.Program `ebpf:"tracepoint__syscalls__sys_exit_open"` - TracepointSyscallsSysExitOpenat *ebpf.Program `ebpf:"tracepoint__syscalls__sys_exit_openat"` -} - -func (p *opensnoopPrograms) Close() error { - return _OpensnoopClose( - p.TracepointSyscallsSysEnterOpen, - p.TracepointSyscallsSysEnterOpenat, - p.TracepointSyscallsSysExitOpen, - p.TracepointSyscallsSysExitOpenat, - ) -} - -func _OpensnoopClose(closers ...io.Closer) error { - for _, closer := range closers { - if err := closer.Close(); err != nil { - return err - } - } - return nil -} - -// Do not access this directly. -//go:embed opensnoop_bpfel.o -var _OpensnoopBytes []byte diff --git a/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.o b/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.o deleted file mode 100644 index dc4f76e43f..0000000000 Binary files a/pkg/gadgets/opensnoop/tracer/core/opensnoop_bpfel.o and /dev/null differ diff --git a/pkg/gadgets/opensnoop/tracer/core/tracer.go b/pkg/gadgets/opensnoop/tracer/core/tracer.go deleted file mode 100644 index f694fef827..0000000000 --- a/pkg/gadgets/opensnoop/tracer/core/tracer.go +++ /dev/null @@ -1,221 +0,0 @@ -//go:build linux -// +build linux - -// Copyright 2019-2021 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package tracer - -// #include -// #include "./bpf/opensnoop.h" -import "C" - -import ( - "errors" - "fmt" - "path/filepath" - "unsafe" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/link" - "github.com/cilium/ebpf/perf" - containercollection "github.com/kinvolk/inspektor-gadget/pkg/container-collection" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/tracer" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/types" - eventtypes "github.com/kinvolk/inspektor-gadget/pkg/types" -) - -//go:generate sh -c "GOOS=$(go env GOHOSTOS) GOARCH=$(go env GOHOSTARCH) go run github.com/cilium/ebpf/cmd/bpf2go -target bpfel -cc clang opensnoop ./bpf/opensnoop.bpf.c -- -I./bpf/ -I../../../../ -target bpf -D__TARGET_ARCH_x86" - -type Tracer struct { - config *tracer.Config - resolver containercollection.ContainerResolver - eventCallback func(types.Event) - node string - - objs opensnoopObjects - openEnterLink link.Link - openAtEnterLink link.Link - openExitLink link.Link - openAtExitLink link.Link - reader *perf.Reader -} - -func NewTracer(config *tracer.Config, resolver containercollection.ContainerResolver, - eventCallback func(types.Event), node string) (*Tracer, error) { - t := &Tracer{config: config} - - t.resolver = resolver - t.eventCallback = eventCallback - t.node = node - - if err := t.start(); err != nil { - t.Stop() - return nil, err - } - - return t, nil -} - -func (t *Tracer) Stop() { - if t.openEnterLink != nil { - t.openEnterLink.Close() - t.openEnterLink = nil - } - if t.openAtEnterLink != nil { - t.openAtEnterLink.Close() - t.openAtEnterLink = nil - } - if t.openExitLink != nil { - t.openExitLink.Close() - t.openExitLink = nil - } - if t.openAtExitLink != nil { - t.openAtExitLink.Close() - t.openAtExitLink = nil - } - - if t.reader != nil { - t.reader.Close() - t.reader = nil - } - - t.objs.Close() -} - -func (t *Tracer) start() error { - spec, err := loadOpensnoop() - if err != nil { - return fmt.Errorf("Failed to load ebpf program: %w", err) - } - - filter_by_mnt_ns := false - - if t.config.MountnsMap != "" { - filter_by_mnt_ns = true - m := spec.Maps["mount_ns_set"] - m.Pinning = ebpf.PinByName - m.Name = filepath.Base(t.config.MountnsMap) - } - - consts := map[string]interface{}{ - "filter_by_mnt_ns": filter_by_mnt_ns, - } - - if err := spec.RewriteConstants(consts); err != nil { - return fmt.Errorf("error RewriteConstants: %w", err) - } - - opts := ebpf.CollectionOptions{ - Maps: ebpf.MapOptions{ - PinPath: filepath.Dir(t.config.MountnsMap), - }, - } - - if err := spec.LoadAndAssign(&t.objs, &opts); err != nil { - return fmt.Errorf("Failed to load ebpf program: %w", err) - } - - openEnter, err := link.Tracepoint("syscalls", "sys_enter_open", t.objs.TracepointSyscallsSysEnterOpen) - if err != nil { - return fmt.Errorf("Error opening tracepoint: %w", err) - } - t.openEnterLink = openEnter - - openAtEnter, err := link.Tracepoint("syscalls", "sys_enter_openat", t.objs.TracepointSyscallsSysEnterOpenat) - if err != nil { - return fmt.Errorf("Error opening tracepoint: %w", err) - } - t.openAtEnterLink = openAtEnter - - openExit, err := link.Tracepoint("syscalls", "sys_exit_open", t.objs.TracepointSyscallsSysExitOpen) - if err != nil { - return fmt.Errorf("Error opening tracepoint: %w", err) - } - t.openExitLink = openExit - - openAtExit, err := link.Tracepoint("syscalls", "sys_exit_openat", t.objs.TracepointSyscallsSysExitOpenat) - if err != nil { - return fmt.Errorf("Error opening tracepoint: %w", err) - } - t.openAtExitLink = openAtExit - - reader, err := perf.NewReader(t.objs.opensnoopMaps.Events, 4096) - if err != nil { - return fmt.Errorf("Error creating perf ring buffer: %w", err) - } - t.reader = reader - - go t.run() - - return nil -} - -func (t *Tracer) run() { - for { - record, err := t.reader.Read() - if err != nil { - if errors.Is(err, perf.ErrClosed) { - // nothing to do, we're done - return - } - - msg := fmt.Sprintf("Error reading perf ring buffer: %s", err) - t.eventCallback(types.Base(eventtypes.Err(msg, t.node))) - return - } - - if record.LostSamples > 0 { - msg := fmt.Sprintf("lost %d samples", record.LostSamples) - t.eventCallback(types.Base(eventtypes.Warn(msg, t.node))) - continue - } - - eventC := (*C.struct_event)(unsafe.Pointer(&record.RawSample[0])) - - ret := int(eventC.ret) - fd := 0 - errval := 0 - - if ret >= 0 { - fd = ret - } else { - errval = -ret - } - - event := types.Event{ - Event: eventtypes.Event{ - Type: eventtypes.NORMAL, - Node: t.node, - }, - MountNsId: uint64(eventC.mntns_id), - Pid: uint32(eventC.pid), - Uid: uint32(eventC.uid), - Comm: C.GoString(&eventC.comm[0]), - Ret: ret, - Fd: fd, - Err: errval, - Path: C.GoString(&eventC.fname[0]), - } - - container := t.resolver.LookupContainerByMntns(event.MountNsId) - if container != nil { - event.Container = container.Name - event.Pod = container.Podname - event.Namespace = container.Namespace - } - - t.eventCallback(event) - } -} diff --git a/pkg/gadgets/opensnoop/tracer/interface.go b/pkg/gadgets/opensnoop/tracer/interface.go deleted file mode 100644 index d51d93eacc..0000000000 --- a/pkg/gadgets/opensnoop/tracer/interface.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2019-2022 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package tracer - -type Tracer interface { - Stop() -} - -type Config struct { - // TODO: Make it a *ebpf.Map once - // https://github.com/cilium/ebpf/issues/515 and - // https://github.com/cilium/ebpf/issues/517 are fixed - MountnsMap string -} diff --git a/pkg/gadgets/opensnoop/tracer/standard/tracer.go b/pkg/gadgets/opensnoop/tracer/standard/tracer.go deleted file mode 100644 index f69137f58a..0000000000 --- a/pkg/gadgets/opensnoop/tracer/standard/tracer.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2019-2022 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package standard - -import ( - "encoding/json" - "fmt" - - containercollection "github.com/kinvolk/inspektor-gadget/pkg/container-collection" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/tracer" - "github.com/kinvolk/inspektor-gadget/pkg/gadgets/opensnoop/types" - eventtypes "github.com/kinvolk/inspektor-gadget/pkg/types" -) - -type Tracer struct { - gadgets.StandardTracerBase - - resolver containercollection.ContainerResolver - eventCallback func(types.Event) - node string -} - -func NewTracer(config *tracer.Config, resolver containercollection.ContainerResolver, - eventCallback func(types.Event), node string) (*Tracer, error, -) { - lineCallback := func(line string) { - event := types.Event{} - event.Type = eventtypes.NORMAL - - if err := json.Unmarshal([]byte(line), &event); err != nil { - msg := fmt.Sprintf("failed to unmarshal event: %s", err) - eventCallback(types.Base(eventtypes.Warn(msg, node))) - return - } - - eventCallback(event) - } - - baseTracer, err := gadgets.NewStandardTracer(lineCallback, - "/usr/share/bcc/tools/opensnoop", - "--json", "--mntnsmap", config.MountnsMap, - "--containersmap", "/sys/fs/bpf/gadget/containers") - if err != nil { - return nil, err - } - - return &Tracer{ - StandardTracerBase: *baseTracer, - eventCallback: eventCallback, - resolver: resolver, // not used right now but could be useful in the future - node: node, - }, nil -} - -func (t *Tracer) Stop() { - if err := t.StandardTracerBase.Stop(); err != nil { - t.eventCallback(types.Base(eventtypes.Warn(err.Error(), t.node))) - } -} diff --git a/pkg/gadgets/opensnoop/types/types.go b/pkg/gadgets/opensnoop/types/types.go deleted file mode 100644 index 11ad84d32e..0000000000 --- a/pkg/gadgets/opensnoop/types/types.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019-2022 The Inspektor Gadget authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package types - -import ( - eventtypes "github.com/kinvolk/inspektor-gadget/pkg/types" -) - -type Event struct { - eventtypes.Event - - MountNsId uint64 `json:"mountnsid,omitempty"` - Pid uint32 `json:"pid,omitempty"` - Uid uint32 `json:"uid,omitempty"` - Comm string `json:"pcomm,omitempty"` - Fd int `json:"fd,omitempty"` - Ret int `json:"ret,omitempty"` - Err int `json:"err,omitempty"` - Path string `json:"path,omitempty"` -} - -func Base(ev eventtypes.Event) Event { - return Event{ - Event: ev, - } -}