0

我正在将 4 个专有(阅读:非 GPL)Linux 内核驱动程序(我没有编写)从 RHEL 5.x 移植到 RHEL 6.x(2.6.32 内核)。驱动程序都使用 kill_proc() 来发出用户空间“会话”的信号,但是这个函数已从更新的内核(2.6.18 和 2.6.32 之间的某个位置)中删除。我已经看到这个问题在这里和其他地方被问过很多次,并且我已经进行了相当广泛的搜索,但是在许多建议的解决方案中,由于不再导出函数或需要仅 GPL 的函数(见下文) . 有谁知道适用于专有驱动程序的解决方案?

给定:kill_proc(pid, sig, 1);

我找到的最简单的解决方案是使用: kill_proc_info(sig, SEND_SIG_PRIV, pid); 但是 kill_proc_info 不再导出,因此无法使用。

建议使用 kill_pid_info()(在设置 rcu_read_lock() 后由 kill_proc_info() 调用。kill_pid_info() 需要 struct pid* 所以我可以使用:kill_pid_info(sig, SEND_SIG_PRIV, find_vpid(pid)); 但是 find_vpid()仅导出为 GPL 使用,这是一个专有驱动程序。还有其他方法可以获取 struct 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*,同样,find_task_by_pid() 不会导出,pid_task() 需要 (GPLd) find_vpid() 来获取一个 struct pid* . 此外,这些函数没有设置 rcu_read_lock() 并且它们还为组标志传递了一个 FALSE 值(而 kill_proc 最终使用了一个 TRUE 值) - 所以可能存在一些细微的差异。

这就是我能找到的一切。有没有人有适合我的情况的建议?提前致谢。

4

1 回答 1

3

由于没有人回答我的问题,我一直在阅读很多内核代码,我想我已经找到了解决方案。

似乎唯一提供与 kill_proc() 相同语义的导出函数是 kill_pid()。我们不能使用 GPL find_vpid() 函数来获取所需的 struct pid*,但是如果我们可以获取 struct task_struct*,那么我们可以从那里获取 struct pid*:task->pids[PIDTYPE_PID].pid

由于 find_task_by_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;
}

我知道搜索整个任务列表而不是使用哈希表会花费更多时间,但这就是我所拥有的。我有一些顾虑/问题:

  1. rcu_read_lock() 是否足够?改用 preempt_disable() 之类的东西会更好吗?
  2. struct task_struct 可以在 pids 数组中没有 PIDTYPE_PID 条目吗?如果是这样,检查 NULL 是否足够?
  3. 我是使用内核的新手,是否有任何其他建议可以使它变得更好?
于 2013-05-01T16:27:04.310 回答