-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #929 from sf1999817/develop
fs_watcher: add fs_watcher to MagicEyes
- Loading branch information
Showing
8 changed files
with
890 additions
and
76 deletions.
There are no files selected for viewing
120 changes: 120 additions & 0 deletions
120
MagicEyes/src/backend/fs/fs_watcher/bpf/CacheTrack.bpf.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "fs_watcher.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
// struct { | ||
// __uint(type, BPF_MAP_TYPE_HASH); | ||
// __uint(max_entries, 1024); | ||
// __type(key, char[30] ); | ||
// __type(value,struct event_CacheTrack); | ||
// } data SEC(".maps"); | ||
|
||
// struct { | ||
// __uint(type, BPF_MAP_TYPE_HASH); | ||
// __uint(max_entries, 1024); | ||
// __type(key, u64 ); | ||
// __type(value,struct event_CacheTrack); | ||
// } unique_map SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
|
||
SEC("tracepoint/writeback/writeback_dirty_inode_start") | ||
int trace_writeback_start(struct trace_event_raw_writeback_dirty_inode_template *ctx){ | ||
pid_t pid = bpf_get_current_pid_tgid() >> 32; | ||
u64 timestamp = bpf_ktime_get_ns(); | ||
struct event_CacheTrack event_info ={}; | ||
char name[32]; | ||
|
||
event_info.ino = ctx->ino; | ||
|
||
event_info.state = ctx->state; | ||
|
||
event_info.flags = ctx->flags; | ||
|
||
event_info.time = timestamp; | ||
|
||
// bpf_probe_read(name, sizeof(name), ctx->name); // 从 ctx 复制设备名称 | ||
|
||
// 检查 name 是否为空字符串 | ||
// if (name[0] == '\0') { | ||
// return 0; | ||
// } | ||
// if(name == NULL) | ||
// return 0; | ||
|
||
// __builtin_memcpy(event_info.name, name, sizeof(name)); | ||
// bpf_printk("comm_123:%s\n",event_info.name); | ||
|
||
struct event_CacheTrack *ring_event = bpf_ringbuf_reserve(&rb, sizeof(struct event_CacheTrack), 0); | ||
if (!ring_event) | ||
return 0; | ||
|
||
__builtin_memcpy(ring_event, &event_info, sizeof(event_info)); | ||
|
||
bpf_printk("event_info_ino:%d\n",event_info.ino); | ||
|
||
bpf_ringbuf_submit(ring_event, 0); | ||
|
||
|
||
// bpf_map_update_elem(&data,name,&event_info,BPF_ANY); | ||
// bpf_map_update_elem(&unique_map,&event_info.queue_id,&event_info,BPF_ANY); | ||
return 0; | ||
} | ||
|
||
// SEC("tracepoint/writeback/writeback_written") | ||
// int trace_writeback_end(struct trace_event_raw_writeback_work_class *ctx) { | ||
// bpf_printk("2222222\n"); | ||
// u64 timestamp = bpf_ktime_get_ns(); | ||
// char name[30]; | ||
// bpf_probe_read_str(name, sizeof(name), ctx->name); // 从 ctx 复制设备名称 | ||
|
||
// if(name == NULL) | ||
// return 0; | ||
|
||
// bpf_printk("comm:%s\n",name); | ||
|
||
// struct event_CacheTrack *e = bpf_map_lookup_elem(&data,name); | ||
// if(!e){ | ||
// bpf_printk("e failed\n"); | ||
// return 0; | ||
// } | ||
|
||
|
||
// struct event_CacheTrack *q = bpf_map_lookup_elem(&unique_map,&e->queue_id); | ||
// if(!q){ | ||
// bpf_printk("q failed\n"); | ||
// return 0; | ||
// } | ||
|
||
// struct event_CacheTrack *q_event = bpf_ringbuf_reserve(&rb, sizeof(struct event_CacheTrack), 0); | ||
// if (!q_event){ | ||
// bpf_printk("Ring buffer is full!\n"); | ||
// return 0; | ||
// } | ||
|
||
// q_event->nr_pages = ctx->nr_pages; | ||
// q_event->sb_dev = ctx->sb_dev; | ||
// q_event->sync_mode = ctx->sync_mode; | ||
// q_event->for_kupdate = ctx->for_kupdate; | ||
// q_event->range_cyclic = ctx->range_cyclic; | ||
// q_event->for_background = ctx->for_background; | ||
// q_event->reason = ctx->reason; | ||
// q_event->cgroup_ino = ctx->cgroup_ino; | ||
// q_event->time = timestamp - q->start_timestamp; | ||
|
||
// bpf_printk("time:%llu\n",q_event->time); | ||
// bpf_printk("123\n"); | ||
|
||
// bpf_ringbuf_submit(q_event, 0); | ||
|
||
// return 0; | ||
|
||
// } |
69 changes: 69 additions & 0 deletions
69
MagicEyes/src/backend/fs/fs_watcher/bpf/block_rq_issue.bpf.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "fs_watcher.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, u32); // 使用进程 PID 作为键 | ||
__type(value, u64); // I/O 总大小作为值 | ||
} io_size_map SEC(".maps"); | ||
|
||
SEC("tracepoint/block/block_rq_issue") | ||
int tracepoint_block_rq_issue(struct trace_event_raw_block_rq_completion *ctx) { | ||
struct event_block_rq_issue *e; | ||
u32 pid = bpf_get_current_pid_tgid() >> 32; // 获取进程 ID | ||
u64 *size, total_size; | ||
|
||
// 分配 ringbuf 空间 | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) { | ||
return 0; // 如果分配失败,提前返回 | ||
} | ||
|
||
// 获取当前进程名 | ||
bpf_get_current_comm(e->comm, sizeof(e->comm)); | ||
|
||
// 填充事件数据 | ||
e->timestamp = bpf_ktime_get_ns(); | ||
e->dev = ctx->dev; | ||
e->sector = ctx->sector; | ||
e->nr_sectors = ctx->nr_sector; | ||
|
||
// 日志输出调试信息 | ||
bpf_printk("PID: %u, Sector: %d, nr_sectors: %d\n", pid, ctx->sector, ctx->nr_sector); | ||
|
||
// 查找或初始化该进程的 I/O 总大小 | ||
size = bpf_map_lookup_elem(&io_size_map, &pid); | ||
if (size) { | ||
total_size = *size; | ||
} else { | ||
total_size = 0; | ||
} | ||
|
||
// 计算本次 I/O 请求的大小 | ||
const u64 sector_size = 512; // 标准扇区大小 | ||
total_size += ctx->nr_sector * sector_size; | ||
|
||
// 更新 I/O 总大小 | ||
bpf_map_update_elem(&io_size_map, &pid, &total_size, BPF_ANY); | ||
|
||
e->total_io = total_size; | ||
|
||
// 日志输出当前总 I/O 大小 | ||
bpf_printk("Updated Total I/O for PID %u: %llu\n", pid, total_size); | ||
|
||
// 提交事件 | ||
bpf_ringbuf_submit(e, 0); | ||
|
||
return 0; | ||
} |
71 changes: 71 additions & 0 deletions
71
MagicEyes/src/backend/fs/fs_watcher/bpf/disk_io_visit.bpf.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "fs_watcher.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
// 定义 ringbuf,用于传输事件信息 | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
// 进程名与 I/O 计数映射 | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, char[TASK_COMM_LEN]); | ||
__type(value, u32); | ||
} io_count_map SEC(".maps"); | ||
|
||
// 这里挂载点得是这个struct trace_event_raw_block_rq_completion *ctx | ||
SEC("tracepoint/block/block_rq_complete") | ||
int tracepoint_block_visit(struct trace_event_raw_block_rq_completion *ctx) { | ||
struct event_disk_io_visit *e; | ||
u32 *count, new_count; | ||
char comm[TASK_COMM_LEN]; | ||
|
||
// 获取当前进程名 | ||
bpf_get_current_comm(comm, sizeof(comm)); | ||
|
||
// 查找或初始化该进程的I/O计数 | ||
count = bpf_map_lookup_elem(&io_count_map, comm); | ||
if (count) { | ||
new_count = *count + 1; | ||
} else { | ||
new_count = 1; | ||
} | ||
bpf_map_update_elem(&io_count_map, comm, &new_count, BPF_ANY); | ||
|
||
// 分配 ringbuf 空间 | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) { | ||
return 0; // 如果分配失败,提前返回 | ||
} | ||
|
||
// 填充事件数据 | ||
e->timestamp = bpf_ktime_get_ns(); | ||
e->blk_dev = ctx->dev; // 直接读取块设备号 | ||
e->sectors = ctx->nr_sector; // 读取操作的扇区数 | ||
|
||
// 判断读写标识符 (检查 rwbs 数组的内容) | ||
if (ctx->rwbs[0] == 'R') { | ||
e->rwbs = 1; // 1 表示读操作 | ||
} else { | ||
e->rwbs = 0; // 0 表示写操作 | ||
} | ||
|
||
// 更新 I/O 操作计数 | ||
e->count = new_count; | ||
|
||
// 复制进程名 | ||
__builtin_memcpy(e->comm, comm, sizeof(comm)); | ||
bpf_printk("comm : %s\n",e->comm); | ||
|
||
// 提交事件 | ||
bpf_ringbuf_submit(e, 0); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,71 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> //包含了BPF 辅助函数 | ||
#define BPF_NO_GLOBAL_DATA | ||
#include <vmlinux.h> | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "open.h" | ||
#include <bpf/bpf_core_read.h> | ||
#include "fs_watcher.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
#define TASK_COMM_LEN 100 | ||
#define path_size 256 | ||
|
||
// 定义哈希映射 | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 1024); | ||
__type(key, pid_t); | ||
__type(value, u64); | ||
} fdtmp SEC(".maps"); | ||
__type(value, char[TASK_COMM_LEN]); | ||
} data SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
SEC("kprobe/do_sys_openat2") | ||
int BPF_KPROBE(do_sys_openat2) | ||
{ | ||
struct fs_t fs; | ||
pid_t pid; | ||
|
||
//pid | ||
pid = bpf_get_current_pid_tgid() >> 32; | ||
fs.pid = pid; | ||
|
||
//uid | ||
fs.uid = bpf_get_current_uid_gid(); | ||
|
||
//fd,file descriptor | ||
int fd = PT_REGS_RC(ctx); | ||
if (fd >= 0) | ||
fs.fd = fd; | ||
else | ||
fs.fd= -1; | ||
|
||
//time | ||
unsigned long long ts = bpf_ktime_get_ns(); | ||
fs.ts = ts; | ||
bpf_map_update_elem(&fdtmp, &pid, &ts, BPF_ANY); | ||
|
||
//从环形缓冲区(ring buffer)中分配一块内存来存储一个名为 struct fs_t 类型的数据,并将该内存块的指针赋值给指针变量 e | ||
struct fs_t *e; | ||
} rb SEC(".maps"); // 环形缓冲区 | ||
|
||
|
||
SEC("tracepoint/syscalls/sys_enter_openat") | ||
int do_syscall_trace(struct trace_event_raw_sys_enter *ctx) | ||
{ | ||
struct event_open *e; | ||
char comm[TASK_COMM_LEN]; | ||
bpf_get_current_comm(&comm,sizeof(comm)); | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) return 0; | ||
|
||
//给变量e赋值 | ||
e->pid = fs.pid; | ||
e->uid = fs.uid; | ||
e->fd = fs.fd; | ||
e->ts = fs.ts; | ||
bpf_get_current_comm(e->comm, sizeof(e->comm)); | ||
|
||
// 成功地将其提交到用户空间进行后期处理 | ||
if (!e) | ||
return 0; | ||
|
||
char filename[path_size]; | ||
struct task_struct *task = (struct task_struct *)bpf_get_current_task(), | ||
*real_parent; | ||
if (task == NULL) { | ||
bpf_printk("task\n"); | ||
bpf_ringbuf_discard(e, 0); | ||
return 0; | ||
} | ||
int pid = bpf_get_current_pid_tgid() >> 32, tgid; | ||
|
||
bpf_map_update_elem(&data, &pid, &comm, BPF_ANY); | ||
|
||
int ppid = BPF_CORE_READ(task, real_parent, tgid); | ||
|
||
bpf_probe_read_str(e->path_name_, sizeof(e->path_name_), | ||
(void *)(ctx->args[1])); | ||
|
||
bpf_printk("path name: %s,pid:%d,ppid:%d\n", e->path_name_, pid, ppid); | ||
|
||
struct fdtable *fdt = BPF_CORE_READ(task, files, fdt); | ||
if (fdt == NULL) { | ||
bpf_printk("fdt\n"); | ||
bpf_ringbuf_discard(e, 0); | ||
return 0; | ||
} | ||
|
||
unsigned int i = 0, count = 0, n = BPF_CORE_READ(fdt, max_fds); | ||
bpf_printk("n:%d\n", n); | ||
|
||
e->n_ = n; | ||
e->pid_ = pid; | ||
|
||
bpf_ringbuf_submit(e, 0); | ||
|
||
return 0; | ||
return 0; | ||
} | ||
|
||
char LICENSE[] SEC("license") = "GPL"; |
Oops, something went wrong.