Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:albertxu216/lmp into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
albertxu216 committed Jan 10, 2025
2 parents 58b30ff + 4229c76 commit b95bfc0
Show file tree
Hide file tree
Showing 18 changed files with 933 additions and 599 deletions.
129 changes: 44 additions & 85 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/CacheTrack.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,115 +6,74 @@

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_HASH);
__uint(max_entries, 1024);
__type(key, u64); // 使用inode作为key
__type(value, struct event_CacheTrack); //存储事件结构体
} data_map SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");


//事件会在脏 inode 开始进行写回时触发
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();
ino_t inode;
char comm[16];
struct event_CacheTrack event_info ={};
char name[32];
// 获取当前进程的命令名称
bpf_get_current_comm(&comm, sizeof(comm));

event_info.ino = ctx->ino;
// 将 comm 字符串复制到 event_info.comm
__builtin_memcpy(event_info.comm, comm, sizeof(comm));

event_info.ino = inode = 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);
bpf_map_update_elem(&data_map,&inode,&event_info,BPF_ANY);
return 0;
}

// 事件会在每个 inode 进行单独写回时触发
SEC("tracepoint/writeback/writeback_single_inode")
int trace_writeback_single_inode(struct trace_event_raw_writeback_single_inode_template *ctx){
ino_t inode = ctx->ino;
u64 timestamp_conmplete = bpf_ktime_get_ns();
struct event_CacheTrack *event_info;

//从map中获取该inode对应的事件信息
event_info = bpf_map_lookup_elem(&data_map,&inode);
if(!event_info){
bpf_printk("failed to found event_info\n");
return 0;
}
//更新inode写回完成的信息
event_info->wrote = ctx->wrote; //已写回的字节数
event_info->nr_to_write = ctx->nr_to_write; //待写回的字节数
event_info->writeback_index = ctx->writeback_index; //表示写回操作的索引或序号
event_info->time_complete = timestamp_conmplete;

// 将事件信息提交到 ring buffer
struct event_CacheTrack *ring_event = bpf_ringbuf_reserve(&rb, sizeof(struct event_CacheTrack), 0);
if (!ring_event)
if (!ring_event) {
bpf_printk("Failed to reserve space in ring buffer for inode %llu\n", inode);
return 0;
}

__builtin_memcpy(ring_event, &event_info, sizeof(event_info));

bpf_printk("event_info_ino:%d\n",event_info.ino);

// 将事件信息从 map 拷贝到 ring buffer
__builtin_memcpy(ring_event, event_info, sizeof(struct event_CacheTrack));
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;

// }
}
111 changes: 72 additions & 39 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/open.bpf.c
Original file line number Diff line number Diff line change
@@ -1,71 +1,104 @@
#define BPF_NO_GLOBAL_DATA
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "fs_watcher.h"

#define TASK_COMM_LEN 100
#define path_size 256
char LICENSE[] SEC("license") = "GPL";

#define O_CREAT 0x0200 // 手动定义 O_CREAT 标志的常量值
#define O_WRONLY 01 /* open for writing only */

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, char[TASK_COMM_LEN]);
__type(value, struct event_open);
} data SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} 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;
struct event_open e = {};
pid_t pid = bpf_get_current_pid_tgid() >> 32;
e.pid = pid;
e.dfd = ctx->args[0];// 目录文件描述符
bpf_probe_read_user_str(e.filename, sizeof(e.filename), (const char *)ctx->args[1]); // 文件路径
e.flags = ctx->args[2]; // 打开标志

// 如果包含 O_CREAT 标志,则标记为文件创建
if (e.flags & O_CREAT || (e.flags & O_WRONLY) ) {
e.is_created = true;
} else {
e.is_created = false;
}

bpf_map_update_elem(&data,&pid,&e,BPF_ANY);
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);
// 跟踪文件描述符分配过程
SEC("kprobe/get_unused_fd_flags")
int kprobe_get_unused_fd_flags(struct pt_regs *ctx){
pid_t pid = bpf_get_current_pid_tgid() >> 32;
struct event_open *e = bpf_map_lookup_elem(&data,&pid);
if(!e){
bpf_printk("get_unused_fd_flags is failed to found fd\n");
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]));
//获取分配的文件描述符
e->fd = PT_REGS_RC(ctx);

bpf_printk("path name: %s,pid:%d,ppid:%d\n", e->path_name_, pid, ppid);
bpf_map_update_elem(&data,&pid,e,BPF_ANY);
return 0;
}

struct fdtable *fdt = BPF_CORE_READ(task, files, fdt);
if (fdt == NULL) {
bpf_printk("fdt\n");
bpf_ringbuf_discard(e, 0);
// 跟踪 openat 系统调用的退出
SEC("tracepoint/syscalls/sys_exit_openat")
int do_syscall_exit(struct trace_event_raw_sys_exit *ctx)
{
pid_t pid = bpf_get_current_pid_tgid() >> 32;
struct event_open *e = bpf_map_lookup_elem(&data,&pid);
if(!e){
bpf_printk("sys_exit_openat is failed to found fd\n");
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);

e->ret = ctx->ret;

// 分配 ringbuf 空间
struct event_open *new_e = bpf_ringbuf_reserve(&rb, sizeof(*new_e), 0);
if (!new_e) {
return 0; // 如果分配失败,提前返回
}

//复制数据
new_e->dfd = e->dfd;
new_e->flags = e->flags;
new_e->fd = e->fd;
new_e->ret =e->ret;
new_e->is_created = e->is_created;
new_e->pid = e->pid;

// 手动读取文件路径,确保不超过最大长度,并添加 '\0' 结束符
int filename_len = 0;
while (filename_len < sizeof(new_e->filename) - 1) {
char c = 0;
// 读取路径中的每个字符
bpf_probe_read(&c, sizeof(c), e->filename + filename_len);
if (c == '\0') break; // 如果遇到 null 字符就停止读取
new_e->filename[filename_len++] = c;
}
// 确保字符串以 '\0' 结束
new_e->filename[filename_len] = '\0';
bpf_printk("Opening file: %s, pid: %d, flags: %d\n", new_e->filename, pid, e->flags);

bpf_ringbuf_submit(new_e, 0);
return 0;
}

char LICENSE[] SEC("license") = "GPL";
21 changes: 14 additions & 7 deletions MagicEyes/src/backend/fs/fs_watcher/include/fs_watcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#define TASK_COMM_LEN 16

struct event_open {
int pid_;
char path_name_[path_size];
int n_;
char comm[TASK_COMM_LEN];
pid_t pid;
int dfd;
char filename[path_size];
int flags;
int fd; // 文件描述符
int ret; // 系统调用返回值
bool is_created; // 标记文件是否创建
};

/*read*/
Expand Down Expand Up @@ -50,16 +53,20 @@ struct event_block_rq_issue {

/*CacheTrack*/
struct event_CacheTrack{
pid_t pid;
char comm[16];
long long time; //耗时
// char name[32]; // 设备名称
ino_t ino; // inode 号
unsigned long state; // inode 状态
unsigned long flags; // inode 标志
long int nr_to_write; // 待写回字节数
long unsigned int writeback_index; //写回操作的索引或序号
long unsigned int wrote; //已写回的字节数
long long time_complete; // 写回开始时间
};

/*send pid to ebpf*/
struct dist_args {
pid_t pid;
};
#endif /* __MEM_WATCHER_H */
#endif /* __MEM_WATCHER_H */

Loading

0 comments on commit b95bfc0

Please sign in to comment.