美文网首页
ebpf开发环境

ebpf开发环境

作者: rushui | 来源:发表于2022-04-28 14:29 被阅读0次

    安装开发环境

    必要的开发工具:

    # For Ubuntu20.10+
    sudo apt-get install -y  make clang llvm libelf-dev libbpf-dev bpfcc-tools libbpfcc-dev linux-tools-$(uname -r) linux-headers-$(uname -r)
    
    # For RHEL8.2+
    sudo yum install libbpf-devel make clang llvm elfutils-libelf-devel bpftool bcc-tools bcc-devel
    

    libbpf-dev 这个库很可能需要从源码安装,具体的步骤你可以参考 libbpf 的 GitHub 仓库
    安装可能出现问题 ,参考:https://blog.csdn.net/dwh0403/article/details/120243023

    开发过程

    ebpf的一些工具 https://www.brendangregg.com/ebpf.html

    一般来说,这个过程分为以下 5 步:

    • 第一步,使用 C 语言开发一个 eBPF 程序;
    • 第二步,借助 LLVM 把 eBPF 程序编译成 BPF 字节码;
    • 第三步,通过 bpf 系统调用,把 BPF 字节码提交给内核;
    • 第四步,内核验证并运行 BPF 字节码,并把相应的状态保存到 BPF 映射中;
    • 第五步,用户程序通过 BPF 映射查询 BPF 字节码的运行状态

    使用 BCC 开发 eBPF 程序,可以把前面讲到的五步简化为下面的三步。

    第一步:使用 C 开发一个 eBPF 程序

    新建一个 hello.c 文件,并输入下面的内容:

    int hello_world(void *ctx)
    {
       bpf_trace_printk("Hello, World!");
       return 0;
    }
    

    就像所有编程语言的“ Hello World ”示例一样,这段代码的含义就是打印一句 “Hello, World!” 字符串。其中, bpf_trace_printk() 是一个最常用的 BPF 辅助函数,它的作用是输出一段字符串。不过,由于 eBPF 运行在内核中,它的输出并不是通常的标准输出(stdout),而是内核调试文件 /sys/kernel/debug/tracing/trace_pipe ,你可以直接使用 cat 命令来查看这个文件的内容。

    第二步:使用 Python 和 BCC 库开发一个用户态程序

    接下来,创建一个 hello.py 文件,并输入下面的内容

    #!/usr/bin/env python3
    # 1) import bcc library
    from bcc import BPF
    
    # 2) load BPF program
    b = BPF(src_file="hello.c")
    # 3) attach kprobe
    b.attach_kprobe(event="do_sys_openat2", fn_name="hello_world")
    # 4) read and print /sys/kernel/debug/tracing/trace_pipe
    b.trace_print()
    

    让我们来看看每一处的具体含义:

    • 第 1) 处导入了 BCC 库的 BPF 模块,以便接下来调用;
    • 第 2) 处调用 BPF() 加载第一步开发的 BPF 源代码;
    • 第 3) 处将 BPF 程序挂载到内核探针(简称 kprobe),其中 do_sys_openat2() 是系统调用 openat() 在内核中的实现;
    • 第 4) 处则是读取内核调试文件 /sys/kernel/debug/tracing/trace_pipe 的内容,并打印到标准输出中。在运行的时候,BCC 会调用 LLVM,把 BPF 源代码编译为字节码,再加载到内核中运行。

    第三步:执行 eBPF 程序

    用户态程序开发完成之后,最后一步就是执行它了。需要注意的是, eBPF 程序需要以 root 用户来运行,非 root 用户需要加上 sudo 来执行:

    sudo python3 hello.py
    

    稍等一会,你就可以看到如下的输出:

    b' cat-10656 [006] d... 2348.114455: bpf_trace_printk: Hello, World!'
    

    输出的格式可由 /sys/kernel/debug/tracing/trace_options 来修改。比如前面这个默认的输出中,每个字段的含义如下所示:

    • cat-10656 表示进程的名字和 PID;
    • [006] 表示 CPU 编号;
    • d… 表示一系列的选项;2348.114455 表示时间戳;
    • bpf_trace_printk 表示函数名;
    • 最后的 “Hello, World!” 就是调用 bpf_trace_printk() 传入的字符串。
      到了这里,恭喜你已经成功开发并运行了第一个 eBPF 程序!

    相关文章

      网友评论

          本文标题:ebpf开发环境

          本文链接:https://www.haomeiwen.com/subject/ojhdyrtx.html