很多时候在写内核模块的时候,需要通过进程的pid找到对应进程的task_struct,其中首先就需要通过进程的pid找到进程的struct pid,然后
再通过struct pid找到进程的task_struct.例如,以前写过打印一个指定进程的所有虚存区就用到这。
下面就介绍实现pid到struct pid的内核函数。----------------------------------------------------------------------------------------------
1,我知道的实现函数有三个。- 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;
- }
- struct pid *find_vpid(int nr)
- {
- return find_pid_ns(nr, current->nsproxy->pid_ns);
- }
- 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;
- }
----------------------------------------------------------------------------------------------
2,三个内核函数之间的联系与区别。-------------------------------------------------------------------------------------
由图可以看出,find_pid_ns是最终的实现,find_vpid是使用find_pid_ns
实现的,find_get_pid又是由find_vpid实现的。由原代码可以看出find_vpid
和find_pid_ns是一样的,而find_get_pid和find_vpid有一点差异,就是使用find_get_pid将返回的struct pid中的字段count加1,而find_vpid没有加1。
-------------------------------------------------------------------------------------
3,find_pid_ns的实现原理。参考如下链接
原理很简单,主要使用哈希查找。内核使用哈希表组织struct pid,每创建一
个新进程,给进程的struct pid都会插入到哈希表中,这时候就需要使用进程
的进程pid和命名ns在哈希表中将相对应的struct pid索引出来,现在可以看下find_pid_ns的传入参数,也是通过nr和ns找到struct pid。在2.6.39系列内核
中,如上三个内核函数均导出了,故在模块中都可以直接使用。
--------------------------------------------------------------------------------------
阅读(496) | 评论(0) | 转发(0) |