前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >搭建centos7 ebpf编译环境

搭建centos7 ebpf编译环境

原创
作者头像
cdh
修改2024-01-04 14:17:35
5720
修改2024-01-04 14:17:35
举报
文章被收录于专栏:笔记+笔记+

系统环境:

# uname -r

3.10.0-1160.99.1.el7.x86_64

# cat /etc/centos-release

CentOS Linux release 7.6.1810 (Core)

1. gcc版本升级

代码语言:c
复制
#sudo yum install centos-release-scl -y
#sudo yum install devtoolset-7 -y
#sudo yum install devtoolset-8 -y

安装的是 devtoolset-7 和 devtoolset-8, 安装完成后全部文件在/opt/rh目录下:

代码语言:c
复制
# ls /opt/rh/
devtoolset-7  devtoolset-8

在所登录的会话生效高版本gcc:

代码语言:c
复制
# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

# source /opt/rh/devtoolset-8/enable
# gcc --version
gcc (GCC) 8.3.1 20190311 (Red Hat 8.3.1-3)

添加到登录自启动脚本,避免每次登录需要手工执行source /opt/rh/devtoolset-8/enable
echo "source /opt/rh/devtoolset-8/enable" >> ~/.bash_profile

2. cmake升级

代码语言:c
复制
#wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0.tar.gz
#tar -zxvf cmake-3.20.0.tar.gz
#source /opt/rh/devtoolset-8/enable
#cd cmake-3.20.0
#./bootstrap 
#make 
#make install
重新登录新的会话查看cmake版本:
#cmake --version
cmake version 3.20.0

3. llvm升级:

代码语言:c
复制

#git clone https://github.com/llvm/llvm-project.git
#cd llvm-project
#mkdir llvm-build
#cd llvm-build
#source /opt/rh/devtoolset-8/enable
#cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -G "Unix Makefiles" ../llvm
#make 
#make install

4. 编译bcc以及libbpf-tools

代码语言:c
复制
编译bcc的过程会自动下载编译依赖的libbpf和bpftool,因此可以不需要再单独下载编译libbpf和bpftool
#git clone https://github.com/iovisor/bcc.git 
#mkdir bcc/build; cd bcc/build
#cmake ..
#make
#cd ../libbpf-tools/
#make

编译通过后执行bcc中自带的libbpf的工具比如opensnoop会报错,这个是因为bcc.git提供的libbpf-tools工具集实现时使用了BTF相关接口,依赖内核开启CONFIG_DEBUG_INFO_BTF。

代码语言:c
复制
# ./opensnoop 
libbpf: failed to find valid kernel BTF
failed to fetch necessary BTF for CO-RE: Operation not supported

5. 写一个不依赖BTF的ebpf测试程序验证centos7运行ebpf程序

代码语言:c
复制

       
# cat trace_kfree_skb.bpf.c  //内核态执行的bpf代码

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

struct args_kfree_skb {
        void *regs;
        void *skbaddr;
        void *location;
        unsigned short protocol;
};

SEC("tracepoint/skb/kfree_skb")
int tp_kfree_skb(struct args_kfree_skb *args)
{
        __u32 pid = 0;
        pid = bpf_get_current_pid_tgid();
        bpf_printk("pid:%d,hello test bpf :skbaddr:%llx,location:%llx\n", pid,args->skbaddr,args->location);
        return 1;//perf trace -e skb:kfree_skb cannot get any message if here return 0. see kernel function perf_trace_run_bpf_submit()
}
char LICENSE[] SEC("license") = "GPL";


# cat trace_kfree_skb.c    //用户态执行的bpf代码
#include <stdio.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include "trace_kfree_skb.skel.h"

static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
        return vfprintf(stderr, format, args);
}

int main(int argc, char **argv)
{
        struct trace_kfree_skb_bpf *skel;
        int err;
         
         struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
        if (setrlimit(RLIMIT_MEMLOCK, &r)) {
                perror("setrlimit(RLIMIT_MEMLOCK)");
                return 1;
        }

         libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
        /* Set up libbpf errors and debug info callback */
         libbpf_set_print(libbpf_print_fn);

        /* Open BPF application */
        skel = trace_kfree_skb_bpf__open();
        if (!skel) {
                fprintf(stderr, "Failed to open BPF skeleton\n");
                return 1;
        }

        /* Load & verify BPF programs */
        err = trace_kfree_skb_bpf__load(skel);
        if (err) {
                fprintf(stderr, "Failed to load and verify BPF skeleton\n");
                goto cleanup;
        }
        /* Attach tracepoint handler */
         err = trace_kfree_skb_bpf__attach(skel);
         if (err) {
                 fprintf(stderr, "Failed to attach BPF skeleton\n");
                 goto cleanup;
         }

        printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` or run 'bpftool prog tracelog'"
               "to see output of the BPF programs.\n");

       for (;;) {
                sleep(60);
        }

cleanup:
        trace_kfree_skb_bpf__destroy(skel);
        return 0;
}

#修改Makefile添加新增的测试代码:
bcc/libbpf-tools目录下的Makefile文件在APPS = \位置添加新的ebpf工具trace_kfree_skb:
APPS = \
        bashreadline \
        ......
        ......
        wakeuptime \
        trace_kfree_skb \
        $(BZ_APPS) \
        #
#执行make编译生成可执行文件trace_kfree_skb
# make
which: no cargo in (/opt/rh/devtoolset-8/root/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
  BPF      trace_kfree_skb.bpf.o
  GEN-SKEL trace_kfree_skb.skel.h
  CC       trace_kfree_skb.o
  BINARY   trace_kfree_skb
# ls trace_kfree_skb
trace_kfree_skb      

编译bcc的过程会自动下载编译依赖的libbpf和bpftool,因此可以不需要再单独下载编译libbpf和bpftool,
如果验证程序不是放在bcc/libbpf里一起编译,则需要再单独下载编译安装libbpf和bpftool。


验证在centos7 3.10内核正常运行ebpf程序
# uname -r
3.10.0-1160.99.1.el7.x86_64
# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core) 
# ./trace_kfree_skb 
libbpf: loading object 'trace_kfree_skb_bpf' from buffer
libbpf: elf: section(3) tracepoint/skb/kfree_skb, size 88, link 0, flags 6, type=1
libbpf: sec 'tracepoint/skb/kfree_skb': found program 'tp_kfree_skb' at insn offset 0 (0 bytes), code size 11 insns (88 bytes)
libbpf: elf: section(4) .reltracepoint/skb/kfree_skb, size 16, link 12, flags 40, type=9
libbpf: elf: section(5) .rodata, size 51, link 0, flags 2, type=1
libbpf: elf: section(6) license, size 4, link 0, flags 3, type=1
libbpf: license of trace_kfree_skb_bpf is GPL
libbpf: elf: section(7) .BTF, size 906, link 0, flags 0, type=1
libbpf: elf: section(9) .BTF.ext, size 128, link 0, flags 0, type=1
libbpf: elf: section(12) .symtab, size 144, link 1, flags 0, type=2
libbpf: looking for externs among 6 symbols...
libbpf: collected 0 externs total
libbpf: map 'trace_kf.rodata' (global data): at sec_idx 5, offset 0, flags 80.
libbpf: map 0 is "trace_kf.rodata"
libbpf: sec '.reltracepoint/skb/kfree_skb': collecting relocation for section(3) 'tracepoint/skb/kfree_skb'
libbpf: sec '.reltracepoint/skb/kfree_skb': relo #0: insn #4 against '.rodata'
libbpf: prog 'tp_kfree_skb': found data map 0 (trace_kf.rodata, sec 5, off 0) for insn 4
libbpf: map 'trace_kf.rodata': created successfully, fd=4
Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` or run 'bpftool prog tracelog'to see output of the BPF programs.

#新开一个会话执行cat /sys/kernel/debug/tracing/trace_pipe查看测试程序正常运行
       

参考:

https://bitsanddragons.wordpress.com/2022/09/19/error-cmake-3-1-or-higher-is-required-you-are-running-version-on-centos-7-x/

https://blog.csdn.net/yilun/article/details/126588552

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com