find_task_by_vpidを追ってみる
Rev.3を表示中。最新版はこちら。
サンプルでお世話になっているfind_task_by_vpidを追ってみました。これはプロセスIDからtask_structを取得するものです。task_structにはstruct pid_link pids[PIDTYPE_MAX]が紐づいていて、この配列の添え字にそって、| PIDTYPE_PID | プロセスID |
| PIDTYPE_TGID | スレッドグループID |
| PIDTYPE_PGID | プロセスグループID |
| PIDTYPE_SID | セッションID |
全プロセスIDをリストしているpid_hashから、まずpid構造体を取得します。pid構造体にはこのpidを使用しているtaskがリストされており、これからtask_strucを取得するというものでした。
流れは以下の通りです。(kernel/pid.c)
find_task_by_vpid
find_task_by_pid_type_ns
find_pid_ns
pid_task
PIDTYPE_PIDでfind_task_by_pid_type_nsをコール
struct task_struct *find_task_by_vpid(pid_t vnr)
{
return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
current->nsproxy->pid_ns);
}
find_pid_nsで該当pidを取得し、pid_taskでtask_structを取得。
struct task_struct *find_task_by_pid_type_ns(int type, int nr,
struct pid_namespace *ns)
{
return pid_task(find_pid_ns(nr, ns), type);
}
pid_hashテーブルからプロセスIDとプロセスIDネームスペースの一致するpid を取得
struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
{
struct hlist_node *elem;
struct upid *pnr;
hlist_for_each_entry_rcu(pnr, elem,
&pid_hash[pid_hashfn(nr, ns)], pid_chain)
if (pnr->nr == nr && pnr->ns == ns)
return container_of(pnr, struct pid,
numbers[ns->level]);
return NULL;
}
pid が属するtask_structを取得
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(pid->tasks[type].first);
if (first)
result = hlist_entry(first, struct task_struct, pids[(type)].node);
}
return result;
}
プロセスIDおよびそのネームスペースからハッシュ値を計算
#define pid_hashfn(nr, ns) \
hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)





