linux中的namespace

     本文将就namespace这个知识点,进行简单的归纳总结,力求通俗易通。在资料汇总的过程中,参考了许多网上的博客资料,在文章尾部给出相关链接。

     namespace,命名空间,从名字上看,应该是类似于包含许多名字的空间,打个比方,三年一班的小明和三年二班的小明,虽说他们名字是一样的,但是所在班级不一样,那么,在全年级排行榜上面,即使出现两个名字一样的小明,也会通过各自的学号来区分。对于学校来说,每个班级就相当于是一个命名空间,这个空间的名称是班级号。班级号用于描述逻辑上的学生分组信息,至于什么学生分配到1班,什么学生分配到2班,那就由学校层面来统一调度。大致应该就是这么个意思,恩。

C++中的命名空间

     命名空间这个概念不仅仅在kernel中有使用,在其他语言中也有所体现。例如在C++中,标准C++库中所包含的所有内容(包括常量、变量、结构、类和函数)都被定义在命名空间std中。我们可以定义有名命名空间,也可以定义无名命名空间,命名空间可以嵌套定义,

   1:  有名的命名空间:
   2:   
   3:         namespace 命名空间名 {
   4:   
   5:                声明序列可选
   6:   
   7:         }
   8:   
   9:  无名的命名空间:
  10:   
  11:         namespace {
  12:   
  13:                声明序列可选
  14:   
  15:         }
  16:   

    在C++中,如果代码的最前面没有使用 using namespace std 的话,对于输入输出流,就必须指定所在的命名空间(std::cout <<),否则编译器会找不到他们的具体实现。可以这么说,命名空间是对全局作用域的细分。

Linux中的namespace

    在Linux系统中,可以同时存在多用户多进程,那么对他们的运行协调管理,通过进程调度和进度管理可以解决,但是,整体资源是有限的,怎么把有限的资源(进程号、通信资源、网络资源等等)合理分配给各个用户所在的进程?Linux中提出了namespace机制,这是一种轻量级的虚拟化形式。再次之前,Linux中很多资源是全局管理的,例如,系统中所有进程,都是通过PID来标识的,就像每个学生的学号一样,在整个学校范围内,肯定是唯一标识这个学生的。用户的ID管理,各个用户通过全局为UID来标识,每个学校的校长也只有有一个,它的UID为0,权利最大,可以对学校内全部老师和学生发起命令。每个学生可以看到其他学生的活动,但是无权把他们赶出学校,这是可以理解的。这种集中统一的管理方式,很适合大规模人群的管理。

    随着大数据、虚拟化的兴起,Linux为了提供更加精细的资源分配管理机制,给出了namespace机制解决方法。

命名空间建立系统的不同视图, 对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为0),其他进程的PID依次递增,A和B空间都有PID为0的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。

    Linux中有chroot的系统调用,该方法将进程限制到文件系统的某一部分,是一种简单的命名空间机制。

    在task_struct结构体中,有struct nsproxy *nsproxy 这个成员变量,

   1:  /*
   2:   * A structure to contain pointers to all per-process
   3:   * namespaces - fs (mount), uts, network, sysvipc, etc.
   4:   *
   5:   * ‘count‘ is the number of tasks holding a reference.
   6:   * The count for each namespace, then, will be the number
   7:   * of nsproxies pointing to it, not the number of tasks.
   8:   *
   9:   * The nsproxy is shared by tasks which share all namespaces.
  10:   * As soon as a single namespace is cloned or unshared, the
  11:   * nsproxy is copied.
  12:   */
  13:  struct nsproxy {
  14:      atomic_t count;
  15:      spinlock_t nslock;
  16:      struct uts_namespace *uts_ns;
  17:      struct ipc_namespace *ipc_ns;
  18:      struct mnt_namespace *mnt_ns;
  19:      struct pid_namespace *pid_ns;
  20:  };

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

uts_ns:UTS为Unix Timesharing System的简称,包含内存名称、版本、底层体系结构等信息。

ipc_ns:保存所有与进程间通讯(IPC)有关的信息。

mnt_ns: 当前装载的文件系统

pid_ns: 有关进程ID的信息

在高级版本上,还有net_ns的网络信息,user_ns的资源配额的信息等。

下面以uts命名空间为例子,介绍如何创建用户空间。

从上面的框架图可以看出,所谓的子空间,就是父进程fork一个子进程出来,然后子进程与父进程不共享某些资源,那么,就可以说,这个子进程在它自己的那个命名空间内。

要达到这种效果,就必须对fork的行为进行精确控制,内核提供的如下参数来设置:

UTS命名空间没有层次结构,所有信息都汇集到如下结构:

,kref是引用计数器,用于跟踪内核中有多少地方使用uts_namespace的实例。它提供的属性信息如下:

,从名字上,可以得知uts包含系统名称、版本号、机器名称等等。使用uname -a可以查看这些信息。

系统初始默认值保持在init/version.c 中的init_uts_ns全局变量中,在系统初始化task时,配置init_task。

用户可以在fork时,传入CLONE_NEWUTS标准,创建新的UTS命名空间。执行此操作,会生成先前uts_namespace的一份副本,当前进程内部的nsproxy指向此副本,然后就可以修改了。父子进程对nx_prosy的修改不会相互影响。

    由于最初的父命名空间需要掌握所有子命名空间的所有pid信息,所有,在各级层次的命名空间的fork中,pid的分配是需要统一协调控制,对于各级子命名空间中的task_struct来说,同一个pid在不同命名空间看到的是不一样的。 

   同一个进程可以属于多个namespace,多个进程可以使用同一个namespace,

参考链接:

C++中的namespace

PID namespace浅分析

PID namespcae浅分析 续

Linux内核的namespace机制分析

Technorati 标签: namespace 内核

时间: 2024-12-26 21:59:56

linux中的namespace的相关文章

linux中的strings命令简介2

摘自:http://blog.csdn.net/stpeace/article/details/46641069 linux中的strings命令简介 之前我们聊过linux strings的用法和用途, 但据我了解, 还有部分朋友并不常用strings, 这是个不好的习惯. 所以, 本文继续啰嗦一下strings命令. 在软件开发中, 我们经常需要修改代码, 并生成静态库.动态库或者可执行文件, 有时候, 工程太大, 那怎样确定自己改动的代码正确编译到库中去了呢? 用strings命令吧!  

在Linux中运行Nancy应用程序

最近在研究如何将.NET应用程序移植到非Windows操作系统中运行,逐渐会写一些文章出来.目前还没有太深的研究,所以这些文章大多主要是记录我的一些实验. 这篇文章记录了我如何利用NancyFx编写一个自托管(Self-host)的应用程序,并且将其发布到Linux系统中. 什么是NancyFx? 简单地说,这真是一个神奇的框架.它给自己的定义是:lightweigh web framework for .NET.不用不知道,一用吓一跳哈 http://nancyfx.org/ 与微软官方的AS

linux中内存泄漏的检测(四)记录泄漏的大小

<linux中内存泄漏的检测(三)定制化的new/delete>讲到,利用C++的函数重载的特性,使C++的代码,也能方便地为new/delete加上用于检测内存泄漏的统计代码.然而,也因此引入的新的问题. 目前的统计方式仅仅统计申请/释放内存的次数,并没有统计每次申请/释放内存的大小. 这种方法对于C来说是够用了,因为在C中申请和释放的大小是相同的,而在C++中就不一定了. 考虑以下两种情况: (1)申请了子类的空间却只释放了父类的空间 father *pF = new son; delet

如何在 Linux 中安装微软的 .NET Core SDK | Linux 中国

本分步操作指南文章解释了如何在 Linux 中安装 .NET Core SDK 以及如何使用 .NET 开发出第一个应用程序.-- Sk致谢译自 | ostechnix.com 作者 | Sk译者 | LCTT / runningwater .NET Core 是微软提供的免费.跨平台和开源的开发框架,可以构建桌面应用程序.移动端应用程序.网络应用程序.物联网应用程序和游戏应用程序等.如果你是 Windows 平台下的 dotnet 开发人员的话,使用 .NET core 可以很轻松就设置好任何

linux中常用时间和字符串之间相互转化

在Linux中经常会遇到时间和字符串相互转化的情形,有两个函数专门对应相应的转化. 1.时间转字符串函数strftime 函数原型:size_t strftime(char *s,size_t maxsize,char *format,conststruct tm *timeptr) strftime函数对timeptr指向的tm结构所代表的时间和日期进行格式编排,其结果放在字符串s中.该字符串的长度被设置为(最少)maxsize个字符.格式字符串format用来对写入字符串的字符进行控制,它包

详解 linux中的grub

grub是什么: grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后, 内核会根据grub配置文件中的配置,找到根分区所使用的文件系统对应的驱动,通过根分区文件系统 对应的驱动,挂载根分区,从而达到启动操作系统的目的. 在了解grub以前,请先大体上了解一下centos5/6的启动过程,然后再理解grub就更容易了, 还记的我们以前总结过的centos5系统启动流程吗,如下图,此处我们重点讨论下图红框中的步骤. centos5/6中使用grub作为bootl

Linux中的crontab命令用法

Crontab 在linux中,crontab的用来设置定期执行指定的命令,我们可以用它来指定一些需要重复的事情,Linux系统的用户只需将想要定期要执行的命令序列加到crontab文件中,操作系统即会按用户配置的时间执行这些命令序列.向crontab文件里添加指令之前,需要检查下crontab服务是否已启动和是否开机自动启动: [查看状态] Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的 可以使用service crond status进行查看状态,下图是我在ce

centos linux中怎么查看和修改计算机名/etc/sysconfig/network

centos linux中怎么查看和修改计算机名 查看计算机名:在终端输入hostname 修改的话 hostname +计算机名(重启后失效)要永久修改的话要修改配置文件/etc/sysconfig/network修改hostname=你要改的名字

Linux中的select,poll,epoll模型

Linux中的 select,poll,epoll 都是IO多路复用的机制. select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作.select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一.select的一个缺点在于单个进程能够监视的文件描