【问题标题】:Is there any kill_proc() replacement for proprietary Linux kernel drivers?是否有任何 kill_proc() 替代专有 Linux 内核驱动程序?
【发布时间】:2013-04-21 04:31:32
【问题描述】:

我正在将 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() 来获取结构 pid*。此外,这些函数没有设置 rcu_read_lock() 并且它们还为组标志传递了一个 FALSE 值(而 kill_proc 最终使用了一个 TRUE 值) - 所以可能会有一些细微的差异。

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

【问题讨论】:

    标签: linux signals driver kill-process


    【解决方案1】:

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

    似乎唯一的导出函数提供了 与 kill_proc() 相同的语义是 kill_pid()。我们不能使用 GPL find_vpid() 函数来获取所需的 struct pid*, 但是如果我们可以得到 struct task_struct*,那么我们可以得到 来自那里的 struct pid* 为: 任务->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 是否永远没有 PIDTYPE_PID 条目 在pids数组中?如果是这样,检查 NULL 是否足够?
    3. 我是使用内核的新手,还有其他的吗 提出改进建议?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-05
      • 2015-12-31
      • 2013-09-13
      • 2018-06-02
      • 2011-02-10
      • 2017-03-02
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多