linux内核中如何通过pid得到 struct pid

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;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值