struct pid *find_pid_ns(int nr, struct pid_namespace *ns)
用于从namespace 下的pid找到对应的pid结构体,
位置:/linux/kernel/pid.c
声明:struct pid * find_pid_ns(int nr struct pid_namespace * ns );
功能:此函数用于获取进程描述符,此进程应该满足一下约束条件。
nr: 进程号和参数nr相同。
ns: 保证进程描述的pid_namepace 和参数ns相同
其中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]; // 针对对应层级的upid,运行时会按照实际情况分配内存
};
demo:
#include<linux/pid.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<linux/pid.h>
MODULE_LICENSE("GPL");
static int __init find_pid_ns_init(void);
static void __exit find_pid_ns_exit(void);
int my_function(void *arg)
{
printk("<0>in the kernel thread fubction!\n");
return 0;
}
int __init find_pid_ns_init(void)
{
int result;
struct pid * kpid,*fpid;
printk("<0>into find_pid_ns_init.\n");
result = kernel_thread(my_function,NULL,CLONE_KERNEL);
kpid = find_get_pid(result);
fpid = find_pid_ns(kpid->numbers[kpid->level].nr, kpid->numbers[kpid->level].ns);
printk("<0>the find_pid_ns result's count is : %d\n", fpid->count.counter);
printk("<0>the find_pid_ns result's level is : %d\n", fpid->level);
printk("<0>the find_pid_ns reslut's pid is :%d\n", fpid->numbers[fpid->level].nr);
printk("<0>the kernel_thread result is:%d\n", result);
printk("<0>out find_pid_ns_init\n");
return 0;
}
void __exit find_pid_ns_exit(void)
{
printk("<0>Goodbye find_pid_ns\n");
}
module_init(find_pid_ns_init);
module_exit(find_pid_ns_exit);
源码如下:
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member)*__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
其源码分析如下:
首先根据ns和nr在pid_hash中找到对应的项,即pid_hash[pid_hashfn(nr, ns)],然后遍历pid_hash[pid_hashfn(nr, ns)]
找到其中的pid_chain,并复制给pnr,如果pnr的成员变量nr和ns分别等于形参中的nr和nr,则pnr就是我们我们要找到
最后通过pid中的成员变量upid返回pid结构体的指针,如果没有找到的话则返回null.
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;
}