Linux中与命名空间相关的内核数据结构

【摘要】本文详细讲述了在Linux内核中与命名空间概念相关的内核数据结构及其内在联系。

十、命名空间(namespace)相关数据结构

Linux内核通过数据结构之间互相的连接关系,形成了一套虚拟的命名空间的虚拟化概念。

10.1 struct pid_namespace

  • \linux-2.6.32.63\include\linux\pid_namespace.h
struct pid_namespace 
{
    struct kref kref;
    struct pidmap pidmap[PIDMAP_ENTRIES];
    int last_pid;
/*

每个PID命名空间都具有一个进程,其发挥的作用相当于全局的init进程,init的一个目的是对孤儿调用wait4,命名空间局部的init变体也必须完成该工作。child_reaper保存了指向该进程的task_struct的指针
*/
struct task_struct *child_reaper;
struct kmem_cache *pid_cachep;

/*
2. level表示当前命名空间在命名空间层次结构中的深度。初始命名空间的level为0,下一层为1,逐层递增。level较高的命名空间中的ID,对level较低的命名空间来说是可见的(即子命名空间对父命名空间可见)。从给定的level位置,内核即可推断进程会关联到多少个ID(即子命名空间中的进程需要关联从当前命名空间一直到最顶层的所有命名空间)
*/
unsigned int level;

/*
3. parent是指向父命名空间的指针
*/
	struct pid_namespace *parent;
#ifdef CONFIG_PROC_FS
    struct vfsmount *proc_mnt;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
    struct bsd_acct_struct *bacct;
#endif
};

10.2 struct pid、struct upid

  • PID的管理围绕着两个数据结构展开,struct pid是内核对PID的内部表示、struct upid则表示特定的命名空间中可见的信息。
  • \linux-2.6.32.63\include\linux\pid.h
/*
struct upid is used to get the id of the struct pid, as it is seen in particular namespace. 
Later the struct pid is found with find_pid_ns() using the int nr and struct pid_namespace *ns.
*/
struct upid {
    /* Try to keep pid_chain in the same cacheline as nr for find_vpid */
    //1. 表示ID的数值
    int nr;

    //2. 指向该ID所属的命名空间的指针
    struct pid_namespace *ns;

    /*
    3. 所有的upid实例都保存在一个散列表中,pid_chain用内核的标准方法实现了散列溢出链表
    */
    struct hlist_node pid_chain;
};

struct pid
{
    //1. 引用计数器
    atomic_t count;
    unsigned int level;
    /* 
    lists of tasks that use this pid 
    task是一个数组,每个数组项都是一个散列表头,对应于一个ID类型,因为一个ID可能用于几个进程,所有共享同一个给定ID的task_struct实例,都通过该列表连接起来,PIDTYPE_MAX表示ID类型的数目
    enum pid_type
    {
        PIDTYPE_PID,
        PIDTYPE_PGID,
        PIDTYPE_SID,
        PIDTYPE_MAX
    };
    */
    struct hlist_head tasks[PIDTYPE_MAX];
    struct rcu_head rcu;
    struct upid numbers[1];
};

下载

  • 另一幅图如下:

image-20230505235815294

  • 可以看到,内核用数据结构中的这种N:N的关系,实现了一个虚拟的层次命名空间结构。

10.3 struct nsproxy

  • \linux-2.6.32.63\include\linux\nsproxy.h
/*
A structure to contain pointers to all per-process namespaces
1. fs (mount)
2. uts
3. network
4. sysvipc
5. etc
'count' is the number of tasks holding a reference. The count for each namespace, then, will be the number of nsproxies pointing to it, not the number of tasks.
The nsproxy is shared by tasks which share all namespaces. As soon as a single namespace is cloned or unshared, the nsproxy is copied.
*/
struct nsproxy 
{
    atomic_t count;

    /*
    1. UTS(UNIX Timesharing System)命名空间包含了运行内核的名称、版本、底层体系结构类型等信息
    */
    struct uts_namespace *uts_ns;

    /*
    2. 保存在struct ipc_namespace中的所有与进程间通信(IPC)有关的信息
    */
    struct ipc_namespace *ipc_ns;

    /*
    3. 已经装载的文件系统的视图,在struct mnt_namespace中给出
    */
    struct mnt_namespace *mnt_ns;

    /*
    4. 有关进程ID的信息,由struct pid_namespace提供
    */
    struct pid_namespace *pid_ns;

    /*
    5. struct net包含所有网络相关的命名空间参数
    */
    struct net          *net_ns;
};
extern struct nsproxy init_nsproxy;

10.4 struct mnt_namespace

  • \linux-2.6.32.63\include\linux\mnt_namespace.h
struct mnt_namespace 
{
    //使用计数器,指定了使用该命名空间的进程数目
    atomic_t        count;
    //指向根目录的vfsmount实例
    struct vfsmount *    root;

    //双链表表头,保存了VFS命名空间中所有文件系统的vfsmount实例,链表元素是vfsmount的成员mnt_list
    struct list_head    list;
    wait_queue_head_t poll;
    int event;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leon_George

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值