NeuTracer 教程
主页
  • 背景介绍
  • 项目架构
  • 数据收集
  • 服务端
  • 异常检测
项目测试
主页
  • 背景介绍
  • 项目架构
  • 数据收集
  • 服务端
  • 异常检测
项目测试
  • 详细介绍

    • 背景介绍
    • 项目架构
    • 数据收集
    • 服务端
    • 异常检测

I/O模块 eBPF 部分

bio_snoop.bpf.c 用于跟踪和分析 Linux 内核中的块 I/O 操作,捕获磁盘读写操作的详细信息,包括延迟、吞吐量、读写模式和设备使用情况。该模块使用 eBPF 技术直接在内核空间捕获块 I/O 事件block/block_rq_issue和block/block_rq_complete ,实现低开销的 I/O 监控。支持设备识别、读写分类、请求大小分析、进程关联和高效数据传输,通过环形缓冲区向用户态程序传输事件数据。

模块使用三个核心数据结构来管理和传输 I/O 事件信息:请求标识符(req_key_t)包含设备主次编号和扇区号用于唯一标识 I/O 请求,请求信息(start_req_t)存储请求发起时的时间戳、大小、类型标志和进程名,I/O 事件(bio_event)是传递到用户空间的完整事件结构,包含延迟、传输字节数、读写标志、设备编号和时间戳等信息。

struct req_key_t {
    __u32 dev_major;
    __u32 dev_minor;
    __u64 sector;
};

struct start_req_t {
    __u64 ts;
    __u32 bytes;
    char rwbs[RWBS_LEN];
    char comm[TASK_COMM_LEN];
};

struct bio_event {
    __u32 pid;         // 进程 ID
    char comm[TASK_COMM_LEN]; // 进程名
    __u64 delta_us;    // I/O 延迟(微秒)
    __u64 bytes;       // 传输字节数
    __u8 rwflag;       // 读写标志:0=读,1=写
    __u8 major;        // 设备主编号
    __u8 minor;        // 设备次编号
    __u64 timestamp;   // 时间戳
    __u64 io_count;    // 当前设备的 I/O 计数
};

由于vmlinux.h 文件缺少部分结构体,我们翻阅了源码补充了这些结构体。以下是关键数据结构的定义:

struct block_rq_issue_ctx {
    // 公共头部
    unsigned short common_type;
    unsigned char common_flags;
    unsigned char common_preempt_count;
    int common_pid;
    
    __u32 dev;           // offset: 8
    __u64 sector;        // offset: 16
    __u32 nr_sector;     // offset: 24
    __u32 bytes;         // offset: 28
     char rwbs[RWBS_LEN]; // offset: 32 
    char comm[TASK_COMM_LEN]; // offset: 40 
    __u32 cmd_loc;       // offset: 56 
};

struct block_rq_complete_ctx {
    // 公共头部
    unsigned short common_type;
    unsigned char common_flags;
    unsigned char common_preempt_count;
    int common_pid;
    
    __u32 dev;
    __u64 sector;
    unsigned int nr_sector;
    int error;
    char rwbs[RWBS_LEN]; 
    __u32 cmd_loc;
};

I/O 请求跟踪流程分为两个关键阶段。在请求发起阶段(block_rq_issue),代码捕获请求,包括设备、扇区、大小等信息,记录请求开始时间,并将相关信息存储到 start 映射中。在请求完成阶段(block_rq_complete),系统查找对应的请求记录,计算准确的延迟时间,更新设备 I/O 计数,最后创建完整事件并发送到环形缓冲区供用户空间程序处理。