我正在编写一个内核模块来监视一些系统调用,如果调用成功,这些系统调用希望将函数参数返回到用户域(通过netlink套接字)。

jprobe.kp.symbol_name = "rename";
jprobe.entry = rename_handler;

kretprobe.kp.symbol_name = "rename";
kretprobe.handler = rename_ret_handler;

static rename_obj_t _g_cur_rename = NULL;

static void _rename_handler(const char *oldpath, const char *newpath)
{
    _g_cur_rename = create_rename(oldpath, newpath);
    jprobe_return();
}

static void _rename_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
    /* Send only if successful */
    if (regs_return_value(regs) == 0) {
        add_send_queue(_g_cur_rename);
    }
    return 0;
}

我担心在jprobe之后,另一个重命名的syscall可能会抢占[1]当前的名称,而我将发送不正确的返回码和参数。
jprobe: rename(a, b)
    jprobe rename(c, d)
    kretprobe
kretprobe

编辑:本文[2]指出在kprobe处理程序期间禁用了中断。但这是否意味着在整个链(jprobe-> kprobe-> kretprobe)中禁用中断,或者仅对单个kprobe禁用中断?
  • https://unix.stackexchange.com/questions/186355/few-questions-about-system-calls-and-kernel-modules-kernel-services-in-parallel
  • https://lwn.net/Articles/132196/
  • 最佳答案

    每次jprobe调用都禁止中断:不是整个序列都禁止。

    您期望应用程序处理这些调用的时间是多少?有多种方法,具体取决于您期望传入调用的​​速度。最简单的方法是实现一个内存中的rename_obj_t对象的静态数组,然后使用内核asm include中的atomic_add指向下一个条目(修改数组的大小)。

    这样,您每次都将返回唯一的静态引用,只要计数器在处理返回的值之前不回绕即可。保证atomic_add拥有正确的内存屏障,因此您不必担心诸如缓存一致性之类的问题。

    10-04 13:47