Android从9.0版本开始全面支持eBPF(extended Berkeley Packet Filters
), 其主要用在流量统计上, 也可以用来监控CPU/IO/内存等模块的状态.简单来说, eBPF
可以与内核的kprobe
/tracepoints
/skfilter
等模块相结合, 将eBPF的函数hook到内核事件从而监控相应的系统状态.
Android为eBPF提供了许多封装的库, 并提供了eBPF加载器bpfloader
:
bpfloader
: 位于/system/bpf/bpfloader
, 系统启动时负责加载位于/system/etc/bpf
中的eBPF目标文件libbpf_android
: 位于/system/bpf/libbpf_android
提供创建bpf容器/加载bpf目标文件的接口libbpf
: 位于/external/bcc
, 封装了bpf的系统调用, 提供如attach/dettach程序的接口libnetdbpf
: 位于/system/netd/libnetdbpf
, 实现了netd流量统计功能的函数
目前在Android(Q)上有两处eBPF的代码: 一个是/system/netd/bpf_progs/netd.c
, 主要是用于流量统计;一个是/system/bpfprogs/time_in_state.c
用于监控CPU运行频率以及上下文切换的耗时.
接下来我们就从三个部分来深入理解下Android是如何利用eBPF的:
- eBPF程序与目标文件格式
- Android eBPF加载与执行流程
- Android如何基于eBPF实现流量统计