Linux kernel ebpf:关闭bpf对象和链接实例

Linux kernel ebpf:关闭bpf对象和链接实例,linux-kernel,bpf,ebpf,Linux Kernel,Bpf,Ebpf,因此,我研究了samples/bpf/*示例,并在最近使用libbpf的代码中发现了以下模式: struct bpf_link *links[PROGS_NUM] = { NULL, }; struct bpf_program *prog; struct bpf_object *obj; int i = 0; obj = bpf_object__open_file(filename, NULL); bpf_object__load(obj); bpf_object__for_each_prog

因此,我研究了
samples/bpf/*
示例,并在最近使用
libbpf
的代码中发现了以下模式:

struct bpf_link *links[PROGS_NUM] = { NULL, };
struct bpf_program *prog;
struct bpf_object *obj;
int i = 0;

obj = bpf_object__open_file(filename, NULL);
bpf_object__load(obj);
bpf_object__for_each_program(prog, obj) {
   links[i] = bpf_program__attach(prog);
   i++;
}

现在,在附加程序之后,关闭
bpf
对象实例是否可以,例如
bpf\u object\u\u close(obj)
或者
obj
链接必须存在,并且只要在内核中加载程序就可以访问?

我还没有运行特定的测试来回答您的问题,但根据我的理解:“这取决于”,特别是程序类型。您可能可以关闭
obj
,但如果同时关闭
链接
,则当用户空间加载程序终止时,跟踪eBPF程序可能会分离并卸载

eBPF程序生命周期 一旦加载,只要eBPF程序的引用计数器保持严格的正数,它就会保留在内核中。有许多“句柄”可以保存对程序的引用:

  • 将程序附加到挂钩(如TC筛选器或内核探测)会增加计数器
  • 加载程序或向加载的程序请求文件描述符时从内核返回的文件描述符也包含引用
  • eBPF虚拟文件系统中的固定路径也执行相同的操作
  • BPF\u MAP\u TYPE\u PROG\u数组中引用一个程序(用于尾部调用)也包含一个引用
当所有这些句柄都消失时——当程序被分离时,加载它的用户应用程序终止,并且它没有被固定到bpffs上,然后程序被卸载

eBPF链接 所以我们说,附加一个程序会增加它的引用计数器,这意味着只要程序被附加,它就会保持加载状态。例如,对于TC筛选器或XDP程序,这使事情变得更容易,因为用户应用程序可以附加程序并安全终止-程序保持附加和加载状态。对于跟踪,附加探测通常通过调用
perf\u event\u open()
,检索文件描述符(与加载eBPF程序时得到的文件描述符不同),并使用它附加
ioctl()
。当这个文件描述符 是关闭的,程序是分离的[注:这是我对附加探测的基本理解,可能我遗漏了什么,可能还有其他解决方案]。因此,当用户应用程序终止时,两个文件描述符(load和attach)都将关闭,同时分离和卸载程序。固定程序可防止卸载,但不会分离(因此程序加载到内核中,但从未运行)

作为一种解决方法,引入了eBPF链接,以便为附加程序提供更好的用户体验,使其更容易保持连接,并更一致地管理附加/分离。
struct bpf_链接
引用附加程序时获得的文件描述符。当用户应用程序终止时,可以固定链接以保持持久性,从而确保探测保持活动状态

obj
链接
在您的情况下,如果关闭
obj
链接
,会发生什么

obj
是一个(指向a的指针)
struct bpf_对象
,其内部由libbpf对用户隐藏。它是从一个对象文件构建的,并在加载该对象文件中包含的eBPF程序时更新。它包含指向
struct bpf_program
对象的指针,其中包含
实例
,最后是加载程序时获得的文件描述符。如果我们关闭它们(通过
bpf_object\uu close()
,调用
bpf_object\uu unload()````,然后反过来
bpf_program\uu unload()
),则用于保存程序的句柄将消失。这不是一个问题,只要其他引用保存在其他地方——例如,如果附加了程序。所以我认为关闭obj应该是安全的

如果我们同时关闭
链接
,我们也将失去锁定链接的可能性。进程仍然保存
perf\u event\u open()
中的文件描述符,但它将在退出时将其关闭。如果eBPF程序是跟踪程序,它将立即被分离和卸载。如果它是一个网络程序,它应该保持连接

因此,这完全取决于您的程序类型以及您是否希望程序继续运行。对于跟踪和监视用例,固定的eBPF链接允许您在用户空间加载器应用程序退出时继续探测。因此,在删除这些链接之前,可能需要再次检查您是否不再需要它们:)