1
// Copyright 2019-2023 The Inspektor Gadget authors
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
15
//go:build !withoutebpf
25
"github.com/cilium/ebpf"
26
"github.com/cilium/ebpf/link"
27
"github.com/cilium/ebpf/perf"
29
gadgetcontext "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-context"
30
"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets"
31
"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/oomkill/types"
32
eventtypes "github.com/inspektor-gadget/inspektor-gadget/pkg/types"
35
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -target $TARGET -cc clang -cflags ${CFLAGS} -type data_t oomkill ./bpf/oomkill.bpf.c -- -I./bpf/
46
enricher gadgets.DataEnricherByMntNs
47
eventCallback func(*types.Event)
50
func NewTracer(c *Config, enricher gadgets.DataEnricherByMntNs, eventCallback func(*types.Event)) (*Tracer, error) {
54
eventCallback: eventCallback,
57
if err := t.install(); err != nil {
67
// Stop stops the tracer
68
// TODO: Remove after refactoring
69
func (t *Tracer) Stop() {
73
func (t *Tracer) close() {
74
t.oomLink = gadgets.CloseLink(t.oomLink)
83
func (t *Tracer) install() error {
84
spec, err := loadOomkill()
86
return fmt.Errorf("loading ebpf program: %w", err)
89
if err := gadgets.LoadeBPFSpec(t.config.MountnsMap, spec, nil, &t.objs); err != nil {
90
return fmt.Errorf("loading ebpf spec: %w", err)
93
kprobe, err := link.Kprobe("oom_kill_process", t.objs.IgOomKill, nil)
95
return fmt.Errorf("attaching kprobe: %w", err)
99
reader, err := perf.NewReader(t.objs.oomkillMaps.Events, gadgets.PerfBufferPages*os.Getpagesize())
101
return fmt.Errorf("creating perf ring buffer: %w", err)
108
func (t *Tracer) run() {
110
record, err := t.reader.Read()
112
if errors.Is(err, perf.ErrClosed) {
113
// nothing to do, we're done
117
msg := fmt.Sprintf("Error reading perf ring buffer: %s", err)
118
t.eventCallback(types.Base(eventtypes.Err(msg)))
122
bpfEvent := (*oomkillDataT)(unsafe.Pointer(&record.RawSample[0]))
124
event := types.Event{
125
Event: eventtypes.Event{
126
Type: eventtypes.NORMAL,
127
Timestamp: gadgets.WallTimeFromBootTime(bpfEvent.Timestamp),
129
TriggeredPid: bpfEvent.Fpid,
130
TriggeredUid: bpfEvent.Fuid,
131
TriggeredGid: bpfEvent.Fgid,
132
TriggeredComm: gadgets.FromCString(bpfEvent.Fcomm[:]),
133
KilledPid: bpfEvent.Tpid,
134
KilledComm: gadgets.FromCString(bpfEvent.Tcomm[:]),
135
Pages: bpfEvent.Pages,
136
WithMountNsID: eventtypes.WithMountNsID{MountNsID: bpfEvent.MountNsId},
139
if t.enricher != nil {
140
t.enricher.EnrichByMntNs(&event.CommonData, event.MountNsID)
143
t.eventCallback(&event)
147
// --- Registry changes
149
func (t *Tracer) Run(gadgetCtx gadgets.GadgetContext) error {
151
if err := t.install(); err != nil {
152
return fmt.Errorf("installing tracer: %w", err)
156
gadgetcontext.WaitForTimeoutOrDone(gadgetCtx)
161
func (t *Tracer) SetMountNsMap(mountnsMap *ebpf.Map) {
162
t.config.MountnsMap = mountnsMap
165
func (t *Tracer) SetEventHandler(handler any) {
166
nh, ok := handler.(func(ev *types.Event))
168
panic("event handler invalid")
173
func (g *GadgetDesc) NewInstance() (gadgets.Gadget, error) {