struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
根据nr和其对应的ns找到对应的task。
其使用的例子如下:
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
{
int result = -ENOENT;
struct task_struct *task;
unsigned tgid;
struct pid_namespace *ns;
tgid = name_to_int(&dentry->d_name);
if (tgid == ~0U)
goto out;
ns = dentry->d_sb->s_fs_info;
rcu_read_lock();
task = find_task_by_pid_ns(tgid, ns);
if (task)
get_task_struct(task);
rcu_read_unlock();
}
其源码分析如下:
首先这个函数调用的时候要被rcu_read_lock()/rcu_read_unlock() 保护起来.如果没有保护的话,
则RCU_LOCKDEP_WARN 会打印log find_task_by_pid_ns() needs rcu_read_lock() protection
struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
{
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
"find_task_by_pid_ns() needs rcu_read_lock() protection");
return pid_task(find_pid_ns(nr, ns), PIDTYPE_PID);
}
find_task_by_pid_ns 这个函数基本分成两步,第一步,通过形参nr和ns让find_pid_ns找到struct pid。然后
再让pid_task 根据struct pid和type返回对应的task,这里的type总共有一下几种
enum pid_type
{
PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
PIDTYPE_MAX,
/* only valid to __task_pid_nr_ns() */
__PIDTYPE_TGID
};
find_pid_ns 之前已经分析过了,这里看看pid_task的实现
struct task_struct *pid_task(struct pid *pid, enum pid_type type)
{
struct task_struct *result = NULL;
if (pid) {
struct hlist_node *first;
first = rcu_dereference_check(hlist_first_rcu(&pid->tasks[type]),
lockdep_tasklist_lock_is_held());
if (first)
result = hlist_entry(first, struct task_struct, pids[(type)].node);
}
return result;
}
这里要看看struct pid的结构才好理解
struct pid
{
atomic_t count;
unsigned int level;
/* lists of tasks that use this pid */
struct hlist_head tasks[PIDTYPE_MAX];
struct rcu_head rcu;
struct upid numbers[1];
};
struct pid的成员变量tasks ,表示用这个pid的task。这样通过PIDTYPE_PID 就可以找到task_struct 结构体中的pids[(type)].node 成员变量
最后通过hlist_entry,其定义如下:
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
也就是container_of 通过task_struct的成员变量first来找到task_struct,并作为find_task_by_pid_ns 函数最终的返回值.
进程管理API之find_task_by_pid_ns
最新推荐文章于 2022-11-03 10:47:16 发布