有没有一种有效的方法可以找到指定PID的task_struct,而无需迭代task_struct列表?
task_struct
bqf10yzr1#
使用以下方法之一有什么错?
extern struct task_struct *find_task_by_vpid(pid_t nr); extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns);
字符串
x8diyxa72#
如果你想从一个模块中找到task_struct,find_task_by_vpid(pid_t nr)等是不起作用的,因为这些函数没有导出。在模块中,您可以使用以下函数:
find_task_by_vpid(pid_t nr)
#include <linux/sched.h> #include <linux/pid.h> // ... struct task_struct *my_task; my_task = pid_task(find_vpid(pid), PIDTYPE_PID);
uwopmtnx3#
有一个更好的方法可以从模块中获取task_struct的示例。总是尝试使用 Package 函数/助手例程,因为它们是以这样一种方式设计的,如果驱动程序员遗漏了什么,内核可以自己处理。例如错误处理,条件检查等。
/* Use below API and you will get a pointer of (struct task_struct *) */ taskp = get_pid_task(pid, PIDTYPE_PID);
字符串要获取pid_t类型的PID,您需要使用以下API -
find_get_pid(pid_no);
型在调用这些API的时候,你不需要使用“rcu_read_lock()”和“rcu_read_unlock()”,因为“get_pid_task()”在调用“pid_task()”之前会在内部调用rcu_read_lock()、rcu_read_unlock(),并正确地处理并发。这就是为什么我上面说总是使用这种 Package 器的原因。get_pid_task()和find_get_pid()函数的代码如下:
struct task_struct *get_pid_task(struct pid *pid, enum pid_type type) { struct task_struct *result; rcu_read_lock(); result = pid_task(pid, type); if (result) get_task_struct(result); rcu_read_unlock(); return result; } EXPORT_SYMBOL_GPL(get_pid_task); struct pid *find_get_pid(pid_t nr) { struct pid *pid; rcu_read_lock(); pid = get_pid(find_vpid(nr)); rcu_read_unlock(); return pid; } EXPORT_SYMBOL_GPL(find_get_pid);
型在内核模块中,你也可以通过以下方式使用 Package 器函数:
taskp = get_pid_task(find_get_pid(PID),PIDTYPE_PID);
型PS:有关API的更多信息,您可以查看kernel/pid. c
juzqafwq4#
没有人提到**pid_task()函数和从它得到的指针应该在RCU临界区内使用**(因为它使用了RCU保护的数据结构),否则可能会出现释放后使用BUG。在Linux内核源代码中有很多使用pid_task()的情况(例如,在posix_timer_event()中)。举例来说:
pid_task()
posix_timer_event()
rcu_read_lock(); /* search through the global namespace */ task = pid_task(find_pid_ns(pid_num, &init_pid_ns), PIDTYPE_PID); if (task) printk(KERN_INFO "1. pid: %d, state: %#lx\n", pid_num, task->state); /* valid task dereference */ rcu_read_unlock(); /* after it returns - task pointer becomes invalid! */ if (task) printk(KERN_INFO "2. pid: %d, state: %#lx\n", pid_num, task->state); /* may be successful, * but is buggy (task dereference is INVALID!) */
字符串从Kernel.org了解更多关于RCU API的信息P.S.你也可以使用特殊的API函数,如rcu_read_lock()下的find_task_by_pid_ns()和find_task_by_vpid()。第一个是搜索特定的命名空间:
rcu_read_lock()
find_task_by_pid_ns()
find_task_by_vpid()
task = find_task_by_pid_ns(pid_num, &init_pid_ns); /* e.g. init namespace */
型第二个是通过current任务的命名空间进行搜索。
current
4条答案
按热度按时间bqf10yzr1#
使用以下方法之一有什么错?
字符串
x8diyxa72#
如果你想从一个模块中找到
task_struct
,find_task_by_vpid(pid_t nr)
等是不起作用的,因为这些函数没有导出。在模块中,您可以使用以下函数:
字符串
uwopmtnx3#
有一个更好的方法可以从模块中获取task_struct的示例。总是尝试使用 Package 函数/助手例程,因为它们是以这样一种方式设计的,如果驱动程序员遗漏了什么,内核可以自己处理。例如错误处理,条件检查等。
字符串
要获取pid_t类型的PID,您需要使用以下API -
型
在调用这些API的时候,你不需要使用“rcu_read_lock()”和“rcu_read_unlock()”,因为“get_pid_task()”在调用“pid_task()”之前会在内部调用rcu_read_lock()、rcu_read_unlock(),并正确地处理并发。这就是为什么我上面说总是使用这种 Package 器的原因。
get_pid_task()和find_get_pid()函数的代码如下:
型
在内核模块中,你也可以通过以下方式使用 Package 器函数:
型
PS:有关API的更多信息,您可以查看kernel/pid. c
juzqafwq4#
没有人提到**
pid_task()
函数和从它得到的指针应该在RCU临界区内使用**(因为它使用了RCU保护的数据结构),否则可能会出现释放后使用BUG。在Linux内核源代码中有很多使用
pid_task()
的情况(例如,在posix_timer_event()
中)。举例来说:
字符串
从Kernel.org了解更多关于RCU API的信息
P.S.你也可以使用特殊的API函数,如
rcu_read_lock()
下的find_task_by_pid_ns()
和find_task_by_vpid()
。第一个是搜索特定的命名空间:
型
第二个是通过
current
任务的命名空间进行搜索。