Skip to content

Commit

Permalink
add fs_watcher to MagicEyes
Browse files Browse the repository at this point in the history
Signed-off-by: shangfan <45649554+sf1999817@users.noreply.github.com>
  • Loading branch information
sf1999817 committed Oct 15, 2024
1 parent 05a715f commit 1fce494
Show file tree
Hide file tree
Showing 8 changed files with 890 additions and 76 deletions.
120 changes: 120 additions & 0 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/CacheTrack.bpf.c
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 MagicEyes/src/backend/fs/fs_watcher/bpf/block_rq_issue.bpf.c
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 MagicEyes/src/backend/fs/fs_watcher/bpf/disk_io_visit.bpf.c
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;
}
102 changes: 55 additions & 47 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/open.bpf.c
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";
Loading

0 comments on commit 1fce494

Please sign in to comment.