BPF虚拟文件系统是干什么的,以及它的作用
BPF最基本的的特征是基于文件描述符的映射,这意味着,当文件描述符关闭之后,这个map中的其他信息都会丢失。BPF的map是用于很短暂的隔离程序,他们不会share信息。随着时间的发展,开发人员需要保存Map中的信息,即使是相关的文件描述符已经关闭了。kenerl4.4引入了两个syscall,允许bpf程序从虚拟文件系统固定和获取map。固定到此文件系统的Maps和BPF程序将在创建它们的程序终止后仍然保留在内存中。
BPF默认的虚拟文件路径是在/sys/fs/bpf下,陪你可以使用下面的命令挂载虚拟文件系统
mount -t bpf /sys/fs/bpf /sys/fs/bpf
持久化BPF objects在文件系统中被定义为path,你可以随意指定你的path。有两种BPF Objects你可以在文件系统中保存。bpf的Maps和完整的bpf程序。他们都被标识为一个文件描述符,这些对象只能被bpf系统调用来处理。你是不能使用open等来处理的。
BPF_PIN_FD是去保存bpf对象到文件系统的指令。当这个指令成功时,你将能在/sys/fs/bpf下面看到你创建的path.如果失败了,返回一个负数,同时设置了全局的错误变量:errno。
BPF_OBJ_GET是去获取BPF对象的指令。(前提是之前被Pinned到filesysteme中的)。这个命令使用文件路径去load对象。成功返回文件描述符,失败返回负数,同时设置了全局的错误变量:errno。
#include <errno.h>
#include <linux/bpf.h>
#include <stdio.h>
#include <string.h>
#include "bpf_load.h"
#include "bpf_util.h"
#include "libbpf.h"
static const char *file_path = "/sys/fs/bpf/my_array";
int main(int argc, char **argv) {
int key, value, fd, added, pinned;
fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(int), 100, 0);
if (fd < 0) {
printf("Failed to create map: %d (%s)\n", fd, strerror(errno));
return -1;
}
key = 1, value = 1234;
added = bpf_map_update_elem(fd, &key, &value, BPF_ANY);
if (added < 0) {
printf("Failed to update map: %d (%s)\n", added, strerror(errno));
return -1;
}
pinned = bpf_obj_pin(fd, file_path);
if (pinned < 0) {
printf("Failed to pin map to the file system: %d (%s)\n", pinned,
strerror(errno));
return -1;
}
return 0;
}
首先,我们创建了一个hash-table的map,然后更新了一个元素进去。然后使用bpf_obj_pin去保存map在这个文件系统中。你可以看到/sys/fs/bpf/my_array.然后你就可以使用其他的程序去获取这个map的值,即使是上面的save已经退出了。
能够将BPF对象保存在文件系统中,这为更有趣的应用程序打开了大门。 您的数据和程序不再绑定到单个执行线程。 信息可以由不同的应用程序共享,并且BPF程序甚至可以在创建它们的应用程序终止后运行。 如果没有BPF文件系统,这将为他们提供额外的级别或可用性