今天遇到个不常见的问题:在往内核装载 bpf 程序时,bpf verifier 报告错误:
1
|
failed to load bpf with bitmap size 8: failed to load bpf obj and bpf maps: field Acl: program acl: load program: no space left on device: 578: R0=map_value(id=0,off=0,ks=8,vs=64,imm=0) R1_w=map_ptr(id=0,off=0,ks=4,vs=4,imm=0) R2_w=fp-4 R3_w=invP1 R4=invP(id=69 (3524 line(s) omitted)
|
觉得奇怪的地方是,bpf verifier 怎么会报告空间不足的错误呢?
bpf verifier
好吧,直接搜索 verifier.c
源代码,看看有哪些地方会返回 -ENOSPC
。
Emm,有且仅有一个地方:
1
2
3
4
5
6
7
8
|
// $KERNEL/kernel/bpf/verifier.c
if (log->level && bpf_verifier_log_full(log))
ret = -ENOSPC;
if (log->level && !log->ubuf) {
ret = -EFAULT;
goto err_release_maps;
}
|
这段代码的意思是,用于保存 bpf verifier 日志的地方满了,无法保存更多的 bpf
verifier 日志了。
解决办法
解决办法有 2 个:
- 提供更大的 bpf verifier 日志空间。
- 不去获取 bpf verifier 日志。
使用 cilium/ebpf 的时候,通过以下选项来控制 bpf verifier 日志。
1
2
3
4
5
6
7
|
opts := ebpf.CollectionOptions{
Programs: ebpf.ProgramOptions{
LogLevel: ebpf.LogLevelBranch|ebpf.LogLevelInstruction,
LogSize: ebpf.DefaultVerifierLogSize*10,
LogDisabled: false,
},
}
|
解决办法 1 就是调大 LogSize
,解决办法 2 就是将 LogDisabled
设置为 true
。