Pin
pin 是一种技术,通过它我们可以使得 BPF 文件系统中的一个伪文件持有对 BPF 对象的引用。BPF 对象是引用计数的,这意味着如果对 BPF 对象的所有引用都消失了,内核将卸载/杀死/释放该 BPF 对象。
任何拥有 BPF 对象文件描述符的进程都可以通过将其传递到 BPF_OBJ_PIN
系统调用命令中,并提供一个在 BPF 文件系统中的有效路径来创建一个固定点,该文件系统通常挂载在 /sys/fs/bpf
。
如果您的 Linux 发行版没有自动挂载 BPF 文件系统,您可以手动执行 #!bash mount -t bpf bpffs /sys/fs/bpf
作为 root 用户,或者将其作为设置/初始化脚本的一部分。
进程可以通过调用 BPF_OBJ_GET
系统调用命令,并传递一个到固定点的有效路径来获取 BPF 对象的文件描述符。
固定通常用作在进程或应用程序之间共享或传输 BPF 对象的简便方法。具有短暂运行进程的命令行工具可以例如使用它们在多次调用上执行对象操作。长时间运行的守护进程可以使用固定来确保在重启时资源不会消失。像 iproute2
/tc
这样的工具可以代表用户加载程序,然后另一个程序之后可以修改映射。
固定可以通过使用 rm
命令行工具或 unlink
系统调用来移除。固定是短暂的,不会在系统重启后持久存在。
大多数加载库将提供用于固定和从固定中打开资源的 API。这通常是一个需要显式采取的操作。然而,对于 BTF 风格的映射,有一个属性叫做pinning
,当它被设置为宏值 LIBBPF_PIN_BY_NAME
/1
时,大多数加载库将默认尝试通过名称固定映射(有时给出一个目录的路径)。如果已经存在固定,库将打开固定而不是创建一个新的映射。如果不存在固定,库将创建一个新的映射并将其固定,使用映射的名称作为文件名。
具有 pinning
的映射定义示例:
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, __u32);
__type(value, __u64);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} pinmap SEC(".maps");