diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/Makefile b/36-tracepoint-args-sched_switch-use-custom-struct/Makefile new file mode 120000 index 0000000..d981720 --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/Makefile @@ -0,0 +1 @@ +../common/Makefile \ No newline at end of file diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/README.md b/36-tracepoint-args-sched_switch-use-custom-struct/README.md new file mode 100644 index 0000000..d3ecaed --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/README.md @@ -0,0 +1,18 @@ + +https://mozillazg.com/2022/05/ebpf-libbpf-tracepoint-common-questions.html + +## Usage + +build: + +``` +$ make +``` + +run: + +``` +$ make run + +$ make cat +``` diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/Makefile b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/Makefile new file mode 120000 index 0000000..97ab7f0 --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/Makefile @@ -0,0 +1 @@ +../../common/cilium-ebpf.Makefile \ No newline at end of file diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/README.md b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/README.md new file mode 100644 index 0000000..bbf04bd --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/README.md @@ -0,0 +1,17 @@ + + +## Usage + +build: + +``` +$ make +``` + +run: + +``` +$ make run + +$ make cat +``` diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.go b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.go new file mode 100644 index 0000000..0b22678 --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.go @@ -0,0 +1,115 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build arm64be || armbe || mips || mips64 || mips64p32 || ppc64 || s390 || s390x || sparc || sparc64 + +package main + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +// loadBpf returns the embedded CollectionSpec for bpf. +func loadBpf() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_BpfBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf: %w", err) + } + + return spec, err +} + +// loadBpfObjects loads bpf and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpfObjects +// *bpfPrograms +// *bpfMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpfSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfSpecs struct { + bpfProgramSpecs + bpfMapSpecs +} + +// bpfSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfProgramSpecs struct { + TracepointSchedSchedSwitch *ebpf.ProgramSpec `ebpf:"tracepoint__sched__sched_switch"` +} + +// bpfMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfMapSpecs struct { +} + +// bpfObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfObjects struct { + bpfPrograms + bpfMaps +} + +func (o *bpfObjects) Close() error { + return _BpfClose( + &o.bpfPrograms, + &o.bpfMaps, + ) +} + +// bpfMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfMaps struct { +} + +func (m *bpfMaps) Close() error { + return _BpfClose() +} + +// bpfPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfPrograms struct { + TracepointSchedSchedSwitch *ebpf.Program `ebpf:"tracepoint__sched__sched_switch"` +} + +func (p *bpfPrograms) Close() error { + return _BpfClose( + p.TracepointSchedSchedSwitch, + ) +} + +func _BpfClose(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 bpf_bpfeb.o +var _BpfBytes []byte diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.o b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.o new file mode 100644 index 0000000..5450d6b Binary files /dev/null and b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfeb.o differ diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.go b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.go new file mode 100644 index 0000000..c0ed035 --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.go @@ -0,0 +1,115 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build 386 || amd64 || amd64p32 || arm || arm64 || loong64 || mips64le || mips64p32le || mipsle || ppc64le || riscv64 + +package main + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +// loadBpf returns the embedded CollectionSpec for bpf. +func loadBpf() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_BpfBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf: %w", err) + } + + return spec, err +} + +// loadBpfObjects loads bpf and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpfObjects +// *bpfPrograms +// *bpfMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpfSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfSpecs struct { + bpfProgramSpecs + bpfMapSpecs +} + +// bpfSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfProgramSpecs struct { + TracepointSchedSchedSwitch *ebpf.ProgramSpec `ebpf:"tracepoint__sched__sched_switch"` +} + +// bpfMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpfMapSpecs struct { +} + +// bpfObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfObjects struct { + bpfPrograms + bpfMaps +} + +func (o *bpfObjects) Close() error { + return _BpfClose( + &o.bpfPrograms, + &o.bpfMaps, + ) +} + +// bpfMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfMaps struct { +} + +func (m *bpfMaps) Close() error { + return _BpfClose() +} + +// bpfPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpfPrograms struct { + TracepointSchedSchedSwitch *ebpf.Program `ebpf:"tracepoint__sched__sched_switch"` +} + +func (p *bpfPrograms) Close() error { + return _BpfClose( + p.TracepointSchedSchedSwitch, + ) +} + +func _BpfClose(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 bpf_bpfel.o +var _BpfBytes []byte diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.o b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.o new file mode 100644 index 0000000..64941c3 Binary files /dev/null and b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/bpf_bpfel.o differ diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/main.go b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/main.go new file mode 100644 index 0000000..23cdee5 --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/cilium-ebpf/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "log" + "time" + + "github.com/cilium/ebpf/link" + "github.com/cilium/ebpf/rlimit" +) + +// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile +//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf ../main.bpf.c -- -I../ -I../output + +func main() { + if err := rlimit.RemoveMemlock(); err != nil { + log.Fatal(err) + } + + objs := bpfObjects{} + if err := loadBpfObjects(&objs, nil); err != nil { + log.Fatal(err) + } + defer objs.Close() + + tp, err := link.Tracepoint("sched", "sched_switch", objs.TracepointSchedSchedSwitch, nil) + if err != nil { + log.Println(err) + return + } + defer tp.Close() + + log.Println("Waiting for events...") + time.Sleep(time.Minute * 1024) + +} diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/main.bpf.c b/36-tracepoint-args-sched_switch-use-custom-struct/main.bpf.c new file mode 100644 index 0000000..77d446a --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/main.bpf.c @@ -0,0 +1,29 @@ +#include "vmlinux.h" + +#include +#include +#include + +// sudo cat /sys/kernel/debug/tracing/events/sched/sched_switch/format +struct sched_switch_args { + char _[8]; + char prev_comm[16]; + pid_t prev_pid; + int prev_prio; + long prev_state; + char next_comm[16]; + pid_t next_pid; + int next_prio; +}; + +SEC("tracepoint/sched/sched_switch") +int tracepoint__sched__sched_switch(struct sched_switch_args *ctx) { + u32 prev_pid = (u32)ctx->prev_pid; + u32 next_pid = (u32)ctx->next_pid; + + char fmt[] = "sched_switch %d -> %d\n"; + bpf_trace_printk(fmt, sizeof(fmt), prev_pid, next_pid); + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/36-tracepoint-args-sched_switch-use-custom-struct/main.go b/36-tracepoint-args-sched_switch-use-custom-struct/main.go new file mode 100644 index 0000000..a88a55a --- /dev/null +++ b/36-tracepoint-args-sched_switch-use-custom-struct/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "time" + + bpf "github.com/aquasecurity/libbpfgo" +) + +func main() { + bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") + if err != nil { + panic(err) + } + defer bpfModule.Close() + + if err := bpfModule.BPFLoadObject(); err != nil { + panic(err) + } + prog, err := bpfModule.GetProgram("tracepoint__sched__sched_switch") + if err != nil { + panic(err) + } + if _, err := prog.AttachTracepoint("sched", "sched_switch"); err != nil { + panic(err) + } + + for { + fmt.Println("Waiting...") + time.Sleep(10 * time.Second) + } +} diff --git a/README.rst b/README.rst index 67dee79..53a516c 100644 --- a/README.rst +++ b/README.rst @@ -154,7 +154,7 @@ Examples by program type: | ``BPF_PROG_TYPE_SYSCALL`` | | ``syscall`` | | +-------------------------------------------+----------------------------------------+----------------------------------+-----------------------+ | ``BPF_PROG_TYPE_TRACEPOINT`` | | ``tp+`` |`04`_ `07`_ `14`_ | -+ + +----------------------------------+ + ++ + +----------------------------------+`35`_ `36`_ + | | | ``tracepoint+`` | | +-------------------------------------------+----------------------------------------+----------------------------------+-----------------------+ | ``BPF_PROG_TYPE_TRACING`` | ``BPF_MODIFY_RETURN`` | ``fmod_ret+`` | | @@ -212,6 +212,8 @@ Examples by program type: .. _32: 32-fentry-hello .. _33: 33-xdp-hello .. _34: 34-iter-task-hello +.. _35: 35-tracepoint-args-use-custom-struct +.. _36: 36-tracepoint-args-sched_switch-use-custom-struct https://mozillazg.com/tag/libbpf.html