23

libbpfgo 使用示例:编写使用 perfbuf map 的 ebpf 程序

 1 year ago
source link: https://mozillazg.com/2022/05/ebpf-libbpfgo-use-perfbuf-map.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

本文简单记录一下如何编写一个使用 perfbuf map 传递数据的 ebpf 程序, 以及如何使用 libbpfgo 处理 perfbuf map 中存储的数据。

ebpf 代码

ebpf c 代码中使用 perfbuf map 的方法主要分两步:

  1. 首先定义一个 BPF_MAP_TYPE_PERF_EVENT_ARRAY 类型的 map
  2. 然后通过 bpf_perf_event_output 函数写入数据即可

示例程序代码片段如下:

    /* BPF perfbuf map */
/* 定义 map */
    struct {
            __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
            __uint(key_size, sizeof(u32));
            __uint(value_size, sizeof(u32));
    } events SEC(".maps");

    SEC("kprobe/do_sys_openat2")
    int kprobe__do_sys_openat2(struct pt_regs *ctx)
    {
                    struct event e = {};

                    e.pid = bpf_get_current_pid_tgid() >> 32;

        // 写数据
                    bpf_perf_event_output(ctx, &events, 0xffffffffULL, &e, sizeof(e));

                    return 0;
    }

golang 代码

使用 libbpfgo 读取这个 map 里的数据的方法主要有三步:

  1. 调用 InitPerfBuf 方法初始化一个 perfbuf map 数据接收实例
  2. 通过 Start() 启动实例
  3. 接收并解码数据

相关代码片段示例如下:

eventsChannel := make(chan []byte)
// 因为 perfbuf map 会有数据丢失的问题,可以通过 lostChannel 感知丢失了多少次数据
lostChannel := make(chan uint64)
pb, err := bpfModule.InitPerfBuf("events", eventsChannel, lostChannel, 1)
if err != nil {
        panic(err)
}

pb.Start()
defer func() {
        pb.Stop()
        pb.Close()
}()

for {
        select {
        case e := <-eventsChannel:
                // 解码收到的数据: u32 pid
                pid := binary.LittleEndian.Uint32(e[0:4])
                log.Printf("pid %d", pid)
        case e := <-lostChannel:
                log.Printf("lost %d events", e)
        }
}

完整的代码详见:https://github.com/mozillazg/hello-libbpfgo/tree/master/02-perf-buf


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK