kernel:通过pid查找task_struct的有效方法?

zer*_*lus 7 kernel process

是否有一种有效的方法来查找task_struct指定的pid,而无需遍历task_struct列表?

jør*_*sen 12

使用以下哪一项有什么问题?

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);
Run Code Online (Sandbox Code Playgroud)

  • 你能告诉我 vpid 中 v 的含义吗? (3认同)
  • v 表示虚拟。它在 include/linux/sched.h 中进行了解释。看起来它之所以如此命名是因为“容器”的事情。(https://lwn.net/Articles/168093/) (2认同)

mdd*_*mdd 12

如果要查找task_struct模块find_task_by_vpid(pid_t nr)等,则不会起作用,因为不会导出这些功能.

在模块中,您可以使用以下函数:

pid_task(find_vpid(pid), PIDTYPE_PID);
Run Code Online (Sandbox Code Playgroud)

  • 很好 - 这就是我正在寻找的功能!:) (2认同)

sha*_*ora 7

有一种更好的方法可以从模块获取task_struct 的实例。始终尝试使用包装函数/帮助例程,因为它们的设计方式是,如果驱动程序程序员遗漏了某些内容,内核可以自行处理。例如 - 错误处理、条件检查等。

/* Use below API and you will get a pointer of (struct task_struct *) */

taskp = get_pid_task(pid, PIDTYPE_PID);
Run Code Online (Sandbox Code Playgroud)

并获取 pid_t 类型的 PID。你需要使用下面的API -

find_get_pid(pid_no);
Run Code Online (Sandbox Code Playgroud)

在调用这些 API 时,您不需要使用“ rcu_read_lock() ”和“ rcu_read_unlock() ”,因为“ get_pid_task() ”在调用“ pid_task() ”之前内部调用 rcu_read_lock(),rcu_read_unlock()并正确处理并发。这就是为什么我上面说总是使用这种包装器。

下面是 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);
Run Code Online (Sandbox Code Playgroud)

在内核模块中,您也可以通过以下方式使用包装函数 -

taskp = get_pid_task(find_get_pid(PID),PIDTYPE_PID);
Run Code Online (Sandbox Code Playgroud)

PS:有关 API 的更多信息,您可以查看 kernel/pid.c