我正在将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_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值) - 因此可能存在一些细微差别。
这就是我能找到的一切。有没有人有一个适合我案件的建议?提前谢谢。
答案 0 :(得分:3)
由于我的问题没有回复,我一直都是 阅读大部分内核代码,我想我已经找到了 解。
似乎只提供了导出的功能 与kill_proc()相同的语义是kill_pid()。我们不能用 GPL find_vpid()函数获取所需的struct pid *, 但如果我们可以得到struct task_struct *,那么我们就可以得到 struct pid *从那里: 任务 - > PID的[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;
}
我知道搜索整个任务列表需要花费更多时间 而不是使用哈希表,但它是我所拥有的。一些问题/疑问 我有: