在linux中,命名空间主要提供一种轻量级的资源虚拟,可以从不同方面来查看系统的全局属性,不同命名空间可以互相不干扰,为进程的一部分嗯。例如:同一个进程pid,可以被多个进程共享使用,可以查看同一用户的所有资源消费情况等等。
总体定义
定义如下:
- struct nsproxy {
-
atomit_t count;//指向同一个nsproxy的进程个数
-
struct uts_namespace *uts_ns;//运行的内核
-
struct ipc_namespace *ipc_ns;//进程通信ipc
-
struct mnt_namespace *pid_ns;//文件系统
-
struct user_namespace *user_ns;//用户的资源限制信息
-
struct net *net_ns;//网络
-
}
在创建进程(fork,clone系统调用)时,需要设置一些标志来指明命名空间的创建与否
- #define CLONE_NEWUTS 0x04000000
-
#define CLONE_NEWIPC 0x08000000
-
#define CLONE_NEWUSER 0x10000000
-
#define CLONE_NEWPID 0x20000000
-
#define CLONE_NEWNET 0x40000000
同时在每个任务的定义中也包含命名空间的相关域:
- struct task_struct{
-
…..
-
//指针形式,这样可以被多个进程共享,修改一个命名空间,其它进程就可见了
-
struct nsproxy *nsproxy;
-
…....
-
}
值得注意的是,命名空间需要在编译其间进行选择,如果没有指明,则所有的属性都是全局的,即只存在一个命名空间,全局命名空间为init_proxy,指向每个子系统的对象:
- struct nsproxy init_nsproxy = INIT_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), \
-
.user_ns = &init_user_ns, \
-
}
相对应的系统调用有unshare,可以将父子进程的命名空间进行分开或共享。
UTS命名空间
定义如下:
- struct uts_namespace {
-
struct kref kref;//使用计数
-
struct new_utsname name;
-
}
-
struct new_utsname
-
{
-
char sysname[65];//系统名称
-
char nodename[65];//主机名
-
char release[65];//内核版本号
-
char version[65];//内核版本日期
-
char machine[65];//体系结构
-
char domainname[65];
-
}
测试结果如下:
- sys:Linux
-
node:ubuntu-laptop
-
release:2.6.32-33-generic
-
version:#68-Ubuntu SMP Fri Jun 17 16:25:19 UTC 2011
-
machine:i686
-
domain:(none)
init进程初始化时,utsname赋值如下:
- 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,
-
},
-
}
这些宏常量定义在内核的各个地方,
有些通过编译内核形成的,如UTS_RElEASE,定义在文件
中。有些域可以进行修改,但是有些域不能修改,如UTS_SYSNAME只能是Linux,而UTS_NODENAME则可以进行修改。
阅读(1686) | 评论(0) | 转发(0) |