Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3649685
  • 博文数量: 880
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 6155
  • 用 户 组: 普通用户
  • 注册时间: 2016-11-11 09:12
个人简介

To be a better coder

文章分类

全部博文(880)

文章存档

2022年(5)

2021年(60)

2020年(175)

2019年(207)

2018年(210)

2017年(142)

2016年(81)

分类: LINUX

2017-06-13 18:01:51

原文地址:Linux 命名空间(一) 作者:datao0907

linux中,命名空间主要提供一种轻量级的资源虚拟,可以从不同方面来查看系统的全局属性,不同命名空间可以互相不干扰,为进程的一部分嗯。例如:同一个进程pid,可以被多个进程共享使用,可以查看同一用户的所有资源消费情况等等。

总体定义

定义如下:

  1. struct nsproxy {
  2. atomit_t count;//指向同一个nsproxy的进程个数
  3. struct uts_namespace *uts_ns;//运行的内核
  4. struct ipc_namespace *ipc_ns;//进程通信ipc
  5. struct mnt_namespace *pid_ns;//文件系统
  6. struct user_namespace *user_ns;//用户的资源限制信息
  7. struct net *net_ns;//网络
  8. }

在创建进程(fork,clone系统调用)时,需要设置一些标志来指明命名空间的创建与否

  1. #define CLONE_NEWUTS 0x04000000
  2. #define CLONE_NEWIPC    0x08000000
  3. #define CLONE_NEWUSER 0x10000000
  4. #define CLONE_NEWPID 0x20000000
  5. #define CLONE_NEWNET 0x40000000

同时在每个任务的定义中也包含命名空间的相关域:

  1. struct task_struct{
  2.     …..
  3.     //指针形式,这样可以被多个进程共享,修改一个命名空间,其它进程就可见了
  4.     struct nsproxy *nsproxy;
  5.     …....
  6. }

值得注意的是,命名空间需要在编译其间进行选择,如果没有指明,则所有的属性都是全局的,即只存在一个命名空间,全局命名空间为init_proxy,指向每个子系统的对象:

  1. struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
  2. #define INIT_NSPROXY(nsproxy) {
  3.     .pid_ns     =     &init_pid_ns,    \
  4.     .count    =     ATOMIC_INIT(1), \
  5.     .uts_ns    =    &init_uts_ns,     \
  6.     .mnt_ns    =     NULL,         \
  7.     INIT_NET_NS(net_ns),             \
  8.     INIT_IPC_NS(ipc_ns),             \
  9.     .user_ns    =     &init_user_ns,     \
  10.  }

相对应的系统调用有unshare,可以将父子进程的命名空间进行分开或共享。

UTS命名空间

定义如下:

  1. struct uts_namespace {
  2.     struct kref kref;//使用计数
  3.     struct new_utsname name;
  4. }
  5. struct new_utsname
  6. {
  7.     char sysname[65];//系统名称
  8.     char nodename[65];//主机名
  9.     char release[65];//内核版本号
  10.     char version[65];//内核版本日期
  11.     char machine[65];//体系结构
  12.     char domainname[65];
  13. }

测试结果如下:

  1. sys:Linux
  2. node:ubuntu-laptop
  3. release:2.6.32-33-generic
  4. version:#68-Ubuntu SMP Fri Jun 17 16:25:19 UTC 2011
  5. machine:i686
  6. domain:(none)

init进程初始化时,utsname赋值如下:

  1. struct uts_namespace init_uts_ns     =     {
  2.     .kref      = {
  3.         .refcount         = ATOMIC_INIT(2),
  4.     },
  5.     .name = {
  6.         .sysname        = UTS_SYSNAME,
  7.         .nodename        = UTS_NODENAME,
  8.         .release        = UTS_RELEASE,
  9.         .version         = UTS_VERSION,
  10.         .machine        = UTS_MACHINE,
  11.         .domainname    = UTS_DOMAINNAME,
  12.     },
  13. }

这些宏常量定义在内核的各个地方, 有些通过编译内核形成的,如UTS_RElEASE,定义在文件

中。有些域可以进行修改,但是有些域不能修改,如UTS_SYSNAME只能是Linux,UTS_NODENAME则可以进行修改。

阅读(1504) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~