专有Linux内核驱动程序是否有kill_proc()替代品?

专有Linux内核驱动程序是否有kill_proc()替代品?,linux,signals,driver,kill-process,Linux,Signals,Driver,Kill Process,我正在将4个专有(读:非GPL)Linux内核驱动程序(我没有编写)从RHEL 5.x移植到RHEL 6.x(2.6.32内核)。驱动程序都使用kill_proc()来发送用户空间“session”的信号,但是这个函数已经从最近的内核中删除了(在2.6.18和2.6.32之间)。这个问题在这里和其他地方我已经被问过很多次了,我已经搜索过很多次了,但是在很多建议的解决方案中,没有一个是有效的,原因是函数不再被导出,或者只需要一个GPL函数(见下文)。有人知道一个可以为专有驱动程序工作的解决方案吗

我正在将4个专有(读:非GPL)Linux内核驱动程序(我没有编写)从RHEL 5.x移植到RHEL 6.x(2.6.32内核)。驱动程序都使用kill_proc()来发送用户空间“session”的信号,但是这个函数已经从最近的内核中删除了(在2.6.18和2.6.32之间)。这个问题在这里和其他地方我已经被问过很多次了,我已经搜索过很多次了,但是在很多建议的解决方案中,没有一个是有效的,原因是函数不再被导出,或者只需要一个GPL函数(见下文)。有人知道一个可以为专有驱动程序工作的解决方案吗

给定:kill_proc(pid,sig,1)

我发现最简单的解决方案是使用:kill_proc_info(sig,SEND_sig_PRIV,pid);但是,kill_proc_信息不再导出,因此无法使用

建议使用kill_pid_info()(在设置rcu read_lock()后,kill_proc_info()调用此函数。kill_pid_info()需要一个结构pid*,因此我可以使用:kill_pid_info(sig,SEND_sig PRIV,find_vpid(pid));但是find_vpid()仅导出供GPL使用,这是一个专用驱动程序。是否有其他方法获取结构pid*

kill_pid_info()还设置了一个rcu_read_lock(),然后调用group_send_sig_info()。不幸的是,group_send_siginfo()没有导出,它还需要一个struct task_struct*,但所需的find_task_by_vpid()函数也没有导出

另一个建议是kill_pid(),但这也需要一个struct pid*,同样,find_vpid()函数仅为GPL导出

也有人建议使用send_sig()和send_sig_info(),但这些函数也需要一个struct task_struct*,同样,不导出按pid()查找任务,pid_task()需要(GPLd)find_vpid()来获取结构pid*。此外,这些函数不设置rcu read_lock(),它们还为组标志传递一个假值(而kill_proc最终使用了一个真值)-因此可能存在一些细微的差异


这就是我所能找到的。有人对我的案子有什么建议吗?提前谢谢。

因为没有人回答我的问题,我一直在 读了很多内核代码,我想我发现了一个 解决方案

似乎唯一提供 与kill_proc()相同的语义是kill_pid()。我们不能使用 GPL findvpid()函数以获取所需的结构pid*, 但是如果我们可以得到struct task_struct*,那么我们就可以得到 其中的结构pid*为: 任务->PID[PIDTYPE\U PID].PID

由于不再导出通过vpid()查找任务,因此 找到任务的唯一方法是浏览整个过程 正在查找的任务列表。因此,建议的解决方案是:

int my_kill_proc(pid_t pid, int sig) {
    int error = -ESRCH;           /* default return value */
    struct task_struct* p;
    struct task_struct* t = NULL; 
    struct pid* pspid;
    rcu_read_lock();
    p = &init_task;               /* start at init */
    do {
        if (p->pid == pid) {      /* does the pid (not tgid) match? */
            t = p;    
            break;
        }
        p = next_task(p);         /* "this isn't the task you're looking for" */
    } while (p != &init_task);    /* stop when we get back to init */
    if (t != NULL) {
        pspid = t->pids[PIDTYPE_PID].pid;
        if (pspid != NULL) error = kill_pid(pspid,sig,1);
    }
    rcu_read_unlock();
    return error;
}
我知道搜索整个任务列表要花很多时间,而不是 而不是使用哈希表,但这就是我所拥有的。一些担忧/问题 我有:

  • rcu read_lock()是否足以满足此要求?是否可以 最好改用preempt_disable()之类的方法
  • struct任务_struct是否可以没有PIDTYPE _PID条目 在pids数组中?如果是,检查NULL是否足够
  • 我不熟悉内核,还有其他的吗 有什么更好的建议吗

  • 由于没有人回答我的问题,我一直 读了很多内核代码,我想我发现了一个 解决方案

    似乎唯一提供 与kill_proc()相同的语义是kill_pid()。我们不能使用 GPL findvpid()函数以获取所需的结构pid*, 但是如果我们可以得到struct task_struct*,那么我们就可以得到 其中的结构pid*为: 任务->PID[PIDTYPE\U PID].PID

    由于不再导出通过vpid()查找任务,因此 找到任务的唯一方法是浏览整个过程 正在查找的任务列表。因此,建议的解决方案是:

    int my_kill_proc(pid_t pid, int sig) {
        int error = -ESRCH;           /* default return value */
        struct task_struct* p;
        struct task_struct* t = NULL; 
        struct pid* pspid;
        rcu_read_lock();
        p = &init_task;               /* start at init */
        do {
            if (p->pid == pid) {      /* does the pid (not tgid) match? */
                t = p;    
                break;
            }
            p = next_task(p);         /* "this isn't the task you're looking for" */
        } while (p != &init_task);    /* stop when we get back to init */
        if (t != NULL) {
            pspid = t->pids[PIDTYPE_PID].pid;
            if (pspid != NULL) error = kill_pid(pspid,sig,1);
        }
        rcu_read_unlock();
        return error;
    }
    
    我知道搜索整个任务列表要花很多时间,而不是 而不是使用哈希表,但这就是我所拥有的。一些担忧/问题 我有:

  • rcu read_lock()是否足以满足此要求?是否可以 最好改用preempt_disable()之类的方法
  • struct任务_struct是否可以没有PIDTYPE _PID条目 在pids数组中?如果是,检查NULL是否足够
  • 我不熟悉内核,还有其他的吗 有什么更好的建议吗