2.命名空间实现机制
1.创建方式
(1) 在用fork或clone系统调用创建新进程时,有特定的选项可以控制是与父进程共享命名空间,还是建立新的命名空间。 (2) unshare系统调用将进程的某些部分从父进程分离,其中也包括命名空间。更多信息请参见手册页unshare(2)。 在进程已经使用上述的两种机制之一从父进程命名空间分离后,从该进程的角度来看,改变全局属性不会传播到父进程命名空间,而父进程的修改也不会传播到子进程,至少对于简单的量是这样。而对于文件系统来说,情况就比较复杂,其中的共享机制非常强大,带来了大量的可能性,具体的情况会在第8章讨论。
2.实现机制
命名空间的实现需要两个部分:
1.每个子系统的命名空间结构,将此前所有的全局组件包装到命名空间中;
命名空间的结构是不一样的:
struct nsproxy {atomic_t count;struct uts_namespace *uts_ns;struct ipc_namespace *ipc_ns;struct mnt_namespace *mnt_ns;struct pid_namespace *pid_ns;struct net *net_ns;
};
而各结构中:
UTS命名空间包含了运行内核的名称、版本、底层体系结构类型等信息。UTS是UNIX Timesharing System的简称UTS命名空间几乎不需要特别的处理,因为它只需要简单量,没有层次组织。所有相关信息都汇集到下列结构的一个实例中:
struct uts_namespace {struct kref kref;//计数器,内核有多少个地方引用了uts_namespace这个结构的实例struct new_utsname name;
};
struct new_utsname {//用户命令工具uname输出的就是这个信息char sysname[65];char nodename[65];char release[65];char version[65];char machine[65];char domainname[65];
};
Version.c (init)
struct uts_namespace init_uts_ns = {.kref = {.refcount = ATOMIC_INIT(2),},.name = {.sysname = UTS_SYSNAME,.nodename = UTS_NODENAME,.release = UTS_RELEASE,.version = UTS_VERSION,.machine = UTS_MACHINE,.domainname = UTS_DOMAINNAME,},
};
EXPORT_SYMBOL_GPL(init_uts_ns);
<pre name="code" class="objc">Uts.h (include\linux)
#ifndef UTS_SYSNAME
#define UTS_SYSNAME "Linux"
#endif#ifndef UTS_NODENAME
#define UTS_NODENAME "(none)" /* set by sethostname() */
#endif#ifndef UTS_DOMAINNAME
#define UTS_DOMAINNAME "(none)" /* set by setdomainname() */
#endif
——————————————————————
struct ipc_namespace { //进程间通信的各方式,信号量,消息队列等atomic_t count;struct ipc_ids ids[3];int sem_ctls[4];int used_sems;int msg_ctlmax;int msg_ctlmnb;int msg_ctlmni;atomic_t msg_bytes;atomic_t msg_hdrs;int auto_msgmni;size_t shm_ctlmax;size_t shm_ctlall;int shm_ctlmni;int shm_tot;struct notifier_block ipcns_nb;/* The kern_mount of the mqueuefs sb. We take a ref on it */struct vfsmount *mq_mnt;/* # queues in this ns, protected by mq_lock */unsigned int mq_queues_count;/* next fields are set through sysctl */unsigned int mq_queues_max; /* initialized to DFLT_QUEUESMAX */unsigned int mq_msg_max; /* initialized to DFLT_MSGMAX */unsigned int mq_msgsize_max; /* initialized to DFLT_MSGSIZEMAX */};extern struct ipc_namespace init_ipc_ns;
————————————————————
已经装载的文件系统的视图,在struct mnt_namespace中给出。
struct mnt_namespace {atomic_t count;struct vfsmount * root;struct list_head list;wait_queue_head_t poll;int event;
};
———————
有关进程ID的信息,由struct pid_namespace提供。
struct pid_namespace {struct kref kref;struct pidmap pidmap[PIDMAP_ENTRIES];int last_pid;struct task_struct *child_reaper;struct kmem_cache *pid_cachep;unsigned int level;struct pid_namespace *parent;
#ifdef CONFIG_PROC_FSstruct vfsmount *proc_mnt;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCTstruct bsd_acct_struct *bacct;
#endif
};
extern struct pid_namespace init_pid_ns;
——————————
struct net_ns包含所有网络相关的命名空间参数。读者在第12章中会看到,为使网络相关的内核代码能够完全感知命名空间,还有许多工作需要完成。这个结构很庞大。
2.将给定进程关联到所属各个命名空间的机制。
子系统此前的全局属性现在封装到命名空间中,每个进程关联到一个选定的命名空间。每个可以感知命名空间的内核子系统都必须提供一个数据结构,将所有通过命名空间形式提供的对象集中起来。struct nsproxy用于汇集指向特定于子系统的命名空间包装器的指针
在创建新进程时可使用clone/fork建立一个新的命名空间,必须提供控制该行为的适当的标志。每个命名空间都有一个对应的标志:
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
#define CLONE_NEWIPC 0x08000000 /* New ipcs */
#define CLONE_NEWUSER 0x10000000 /* New user namespace */
#define CLONE_NEWPID 0x20000000 /* New pid namespace */
#define CLONE_NEWNET 0x40000000 /* New network namespace */
因为使用了指针,多个进程可以共享一组子命名空间。这样,修改给定的命名空间,对所有属于该命名空间的进程都是可见的。 请注意,对命名空间的支持必须在编译时启用,而且必须逐一指定需要支持的命名空间。但对命名空间的一般性支持总是会编译到内核中。 这使得内核不管有无命名空间,都不必使用不同的代码。除非指定不同的选项,否则每个进程都会关联到一个默认命名空间,这样可感知命名空间的代码总是可以使用。但如果内核编译时没有指定对具体命名空间的支持,默认命名空间的作用则类似于不启用命名空间,所有的属性都相当于全局的。 init_nsproxy定义了初始的全局命名空间,其中维护了指向各子系统初始的命名空间对象的指针:
Nsproxy.c (kernel)
struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
Init_task.h (include\linux)
extern struct nsproxy init_nsproxy;
#define INIT_NSPROXY(nsproxy) { \.pid_ns = &init_pid_ns, \.count = ATOMIC_INIT(1), \.uts_ns = &init_uts_ns, \.mnt_ns = NULL, \INIT_NET_NS(net_ns) \INIT_IPC_NS(ipc_ns) \
}
3.用户命名空间
struct user_namespace {struct kref kref;struct hlist_head uidhash_table[UIDHASH_SZ];struct user_struct *creator;struct work_struct destroyer;
};extern struct user_namespace init_user_ns;
如前所述,kref是一个引用计数器,用于跟踪多少地方需要使用user_namespace实例。对命名空间中的每个用户,都有一个struct user_struct的实例负责记录其资源消耗,各个实例可通过散列表uidhash_table访问。
对我们来说user_struct的精确定义是无关紧要的。只要知道该结构维护了一些统计数据(如进程和打开文件的数目)就足够了。我们更感兴趣的问题是:每个用户命名空间对其用户资源使用的统计,与其他命名空间完全无关,对root用户的统计也是如此。这是因为在克隆一个用户命名空间时,为当前用户和root都创建了新的user_struct实例
http://book.51cto.com/art/201005/200881.htm
2.命名空间实现机制相关推荐
- linux 命名空间Namespace机制【转】
原文:http://blog.csdn.net/preterhuman_peak/article/details/40857117 Linux Namespaces机制提供一种资源隔离方案.PID,I ...
- php中命名空间和use
php中命名空间和use 总结 php中的namespace就有点像java中package包的概念 php中的use的概念就是用别人的命名空间中的类 php中的include enquire是引入文 ...
- Linux内核的namespace机制分析
1. Linux内核namespace机制 Linux Namespaces机制提供一种资源隔离方案.PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace.每 ...
- C++命名空间 namespace的作用和使用解析
一. 为什么需要命名空间(问题提出) 命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中 常见的同名冲突. 在 C语言中定义了3个层次的作用域,即文件(编译单元).函数和复合语 ...
- 使用Delphi命名空间
Delphi XE5教程8:使用Delphi命名空间 // Project file declarations...//项目文件声明-program MyCompany.ProjectX.Progra ...
- C++第一话---->初识C++及命名空间
本文重点: 1.C++是如何诞生的 2.C++的应用领域 3.怎么学好C++ 4.C++版本的"Hello World" 5.命名空间 一.C++的诞生背景: C语言是一门面向 ...
- Linux的命名空间详解--Linux进程的管理与调度(二)
原文链接:https://blog.csdn.net/gatieme/article/details/51383322 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Lin ...
- Docker的安全机制
Docker的安全很大程度依赖于Linux系统自身的安全,在使用中主要考虑的是一下几个方面的内容: 1.Linux内核的命名空间(namespace)机制提供的容器隔离安全: 2.Li ...
- VS解决方案、命名空间和项目的关系
这里写自定义目录标题 第一篇:解决方案.命名空间和项目的关系 一.解决方案.项目.程序集.命名空间 初学者很容易把这些概念搞混淆.先说说项目(Project),通俗的说,一个项目可以就是你开 发的一个 ...
最新文章
- 安装varish作为缓存和代理
- 自制树莓派“防松鼠神器”在Reddit火了,13行代码就能让AI替你护食,成本300+元...
- shiro的QuickStart
- ubuntu服务器环境测试wss
- 【MySQL】存储过程中,怎么把多个select结果,合并成一个结果集返回?
- 清空邮件队列中的邮件
- 国内旅游业务全面复苏 携程后疫情时代如何深耕旅游市场?
- python(48):re.split 多分隔符
- 毕啸南专栏 | 对话王小川:搜狗不是谁的“变量”,是行业主要玩家
- 我的第一个python web开发框架(4)——数据库结构设计与创建
- 2.scrapy 的使用
- java就业培训教程 笔记
- 方舟单机/管理员生物指令代码大全
- 安静的秋千 ,晚上不睡早晨不起精彩回帖汇总
- C# 基础学习第四天
- android apk上架流程,Android apk上架国内应用市场流程
- 软帝C++1001班9月带班情况
- Modbus 通讯协议 (RTU传输模式)
- LSTM案例——动态和可解释的ICU死亡风险预测
- npm 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
热门文章
- 阿里P8架构师首推Netty实战,实战篇+面试篇,将知识点一网打尽
- 【JS】学习记录【页面打印】
- JProfiler 安装使用教程
- 第10次Scrum会议(10/22)【欢迎来怼】
- ps2021神经ai滤镜无法使用,ps2021神经滤镜出现错误
- [有道翻译]Deep Unfolding Network for Image Super-Resolution部分翻译
- 扇贝编程python广告演员_扇贝编程-人人能学会的python课 az App Store-ban
- iis服务器里网站无法访问,IIS服务器网站无法访问解决方法(图文).doc
- 云南一脸通行业解决方案、钉钉智慧食堂、智慧餐厅、智慧工地解决方案
- Oracle聚簇因子(Clustering factor,CF)