deepin-anything 源码刨析

前言:

deepin-anything:最初是为了满足快速索引文件列表。
kprobe:内核探针,可在内核调用函数前,埋点执行自定义逻辑。
pt_args:内核探针注册接口参数2,用于获取映射的寄存器值结构体。

内核侧模块 vfs_monitor

文件列表项:

├── arg_extractor.c 		对应架构 pt_args 结构参数获取接口文件
├── arg_extractor.h
├── event.c					缓存VFS事件操作接口文件
├── event.h
├── event_merge.c			VFS事件合并操作接口,屏蔽原生linux Event对最终结果影响,del(X) + new(X) => remove del(X)
├── event_merge.h
├── Makefile
├── module.c				内核模块入口
├── vfs_change_consts.h		文件actions映射枚举
├── vfs_fsnotify.c			vfs文件变动逻辑处理主文件
├── vfs_fsnotify.h
├── vfs_genl.c				vfs_evnet入口操作文件
├── vfs_genl.h
├── vfs_kgenl.h
├── vfs_kretprobes.c		kprobe操作文件
└── vfs_kretprobes.h		

module.c

    vfs_changed_func = vfs_notify_dentry_event;	//来自 vfs_genl.c 文件变动事件操作入口
    ret = init_vfs_genl();
    if (ret)
        goto init_vfs_genl_fail;

#ifdef CONFIG_FSNOTIFY_BROADCAST
    ret = init_vfs_fsnotify(get_event_merge_entry(vfs_changed_func)); // 重定向vfs_notify_dentry_event函数指针
    if (ret)
        goto init_event_source_fail;
#else
    ret = init_vfs_kretprobes(get_event_merge_entry(vfs_changed_func)); // 重定向vfs_notify_dentry_event函数指针
    if (ret)
        goto init_event_source_fail;
#endif
  • get_event_merge_entry 获取事件合并入口函数,来自 vfs_kretprobes.c
void *get_event_merge_entry(void *vfs_changed_func)
{
    vfs_changed_entry = vfs_changed_func;

    return do_event_merge;
}
  • init_vfs_fsnotify
static struct kretprobe *vfs_krps[] = {&do_mount_krp, &sys_umount_krp, &vfs_create_krp,
    &vfs_unlink_krp, &vfs_mkdir_krp, &vfs_rmdir_krp, &vfs_symlink_krp, &vfs_link_krp,
    &vfs_rename_krp, &security_inode_create_krp
}; //所有的kprobe结构

int init_vfs_kretprobes(void *vfs_changed_func)
{
    int ret;

    ret = init_mnt_ns();
    if (ret)
        return ret;

    vfs_changed_entry = vfs_changed_func;

    ret = register_kretprobes(vfs_krps, sizeof(vfs_krps) / sizeof(void *)); // 注册kprobe流程
    if (ret < 0) {
        mpr_info("register_kretprobes failed, returned %d\n", ret);
        return ret;
    }
    mpr_info("register_kretprobes %ld ok\n", sizeof(vfs_krps) / sizeof(void *));
    
    return 0;
}
  • kprobe结构,来自 vfs_kretprobes.h
#define _DECL_CMN_KRP(fn, symbol) static struct kretprobe fn##_krp = {\
        .entry_handler  = on_##fn##_ent,\
        .handler        = on_##fn##_ret,\
        .data_size      = sizeof(struct fn##_args),\
        .maxactive      = 64,\
        .kp.symbol_name = ""#symbol"",\
    };

#define DECL_CMN_KRP(fn) _DECL_CMN_KRP(fn, fn)

该部分定义 kprobe 结构体应用于注册探针。即do_mount_krp 埋点 path_mount 如下:

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
DECL_CMN_KRP(do_mount);
#else
_DECL_CMN_KRP(do_mount, path_mount); // do_mount_krp 埋点 函数为  path_mount
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
DECL_CMN_KRP(sys_umount);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0) // 内核版本标识
_DECL_CMN_KRP(sys_umount, ksys_umount); // sys_umount_krp 埋点函数为 ksys_umount
#else
_DECL_CMN_KRP(sys_umount, path_umount);
#endif

该部分定义kprobe的函数入口与kprobe操作函数

#define DECL_VFS_KRP(fn, act, de_i) static int on_##fn##_ent(struct kretprobe_instance *ri, struct pt_regs *regs)\
    {\
        return common_vfs_ent((struct vfs_event **)&(ri->data), (struct dentry *)get_arg(regs, de_i));\
    }\
    \
    static int on_##fn##_ret(struct kretprobe_instance *ri, struct pt_regs *regs)\
    {\
        return common_vfs_ret((struct vfs_event **)&(ri->data), regs, act);\
    }\
    \
    static struct kretprobe fn##_krp = {\
        .entry_handler  = on_##fn##_ent,\
        .handler        = on_##fn##_ret,\
        .data_size      = sizeof(struct vfs_event *),\
        .maxactive      = 64,\
        .kp.symbol_name = ""#fn"",\
    };

宏调用如下

DECL_VFS_KRP(vfs_create, ACT_NEW_FILE, 3); // 参数1为埋点符号,参数2文件操作,参数3获取参数寄存器 return regs->dx;
DECL_VFS_KRP(vfs_unlink, ACT_DEL_FILE, 3);
DECL_VFS_KRP(vfs_mkdir, ACT_NEW_FOLDER, 3);
DECL_VFS_KRP(vfs_rmdir, ACT_DEL_FOLDER, 3);
DECL_VFS_KRP(vfs_symlink, ACT_NEW_SYMLINK, 3);
DECL_VFS_KRP(security_inode_create, ACT_NEW_FILE, 2); // return regs->si;

vfs_changed_entry 函数绑定到 do_event_merge,init_vfs_kretprobes函数中:

vfs_changed_entry = vfs_changed_func;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值