据我了解,当用户空间使用bpf_map_update_elem(int fd, void *key, void *value, __u64 flags)时,

首先,用户空间通过fd找到 map ;

其次,用户空间在用户空间中创建一个内存;

和...

我知道一点,但具体过程仍不清楚。

所以我想知道当用户空间运行API映射帮助程序时细节是什么。

最佳答案

因为您提到“用户空间”,所以我不确定您在说什么。因此,让我们从一些澄清开始。

BPF映射(或至少大多数现有类型,包括哈希映射和数组)可以通过两种方式访问​​:

  • 在用户空间中,由系统上运行的任何具有足够权限的应用程序
  • 来自内核空间,来自BPF程序

  • 在用户空间中,没有“助手”功能。与 map 的交互完全(*)通过bpf()系统调用完成(将BPF_MAP_LOOKUP_ELEMBPF_MAP_UPDATE_ELEMBPF_MAP_DELETE_ELEM命令作为第一个参数传递给syscall)。有关更多详细信息,请参见bpf(2)手册页。这是在用户空间应用程序中使用的应用程序,该应用程序将加载和管理BPF程序和 map ,例如bpftool

    在内核空间(即BPF程序)中,事情的运行方式不同,并且使用BPF的“帮助程序”之一(例如bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags))进行访问。有关现有助手的详细信息,请参见bpf-helpers(7)手册页。您可以在Cilium guide中找到有关这些帮助程序调用的详细信息,或者显然可以通过阅读内核代码(例如for array maps)来找到。它们看起来像是低级C函数调用,使用BPF寄存器传递必要的参数,然后将其从BPF程序指令调用到作为内核二进制文件一部分编译的帮助程序中。

    因此,您提到了bpf_map_update_elem()和用户空间。尽管这是内核端帮助程序的名称,但我怀疑您可能正在谈论与libbpf库提供的相同名称的函数,以提供wrapper around the bpf() system call。因此,使用此功能发生的事情非常简单。
  • 不需要从用户空间中的文件描述符中查找映射:实际上相反,文件描述符是从用户空间中的映射(从其映射ID或从/sys/fs下的固定路径中打开)打开的/bpf虚拟文件系统)。因此,将fd传递给bpf()系统调用,并由内核用作对映射的引用。
  • 我不确定您的意思,而是“用户空间在用户空间中存储了内存”。此处无需分配任何内存:此时keyvalue应该已经被填充,并且它们通过bpf() syscall传递给内核,以告知要更新的条目和值。同样的标志。
  • 一旦调用了bpf(),在内核方面发生的事情就很简单了。通常,内核check permissions会验证参数(以确保参数安全并与 map 保持一致),然后更新实际数据。对于数组映射,最终会调用array_map_update_elem()(也与内核侧的BPF帮助器一起使用,请参见上面的链接)。

  • (*)实际上,某些交互可能不需要bpf()系统调用即可完成,我相信在BPF映射中存储“全局数据”的情况下,可以将mmap()应用程序应用到内核内存中。但这超出了数组和映射的基本用法范围。

    关于c - 像 “bpf_map_update_elem”这样的bps API映射帮助程序的详细过程是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59782101/

    10-09 08:46