首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux -了解挂载名称空间和克隆CLONE_NEWNS标志

Linux -了解挂载名称空间和克隆CLONE_NEWNS标志
EN

Stack Overflow用户
提问于 2014-04-06 10:19:18
回答 2查看 14.7K关注 0票数 25

我正在阅读mount & clone手册页。我想澄清一下CLONE_NEWNS对子进程的文件系统视图有何影响。

(文件层次结构)

让我们将此树视为目录层次结构。假设5和6是父进程中的挂载点。我澄清了另一个question中的挂载点。

因此,我的理解是:5和6是挂载点,这意味着之前使用mount命令在5和6处“挂载”文件系统(目录层次结构)(这意味着在5和6下也必须有目录树)。

mount手册页:

代码语言:javascript
复制
 A mount namespace is the set of filesystem mounts that are visible to a process. 

clone手册页:

代码语言:javascript
复制
Every process lives in a mount namespace.  The namespace of a process is the data 
(the set of mounts) describing the file hierarchy as seen by that process.  After 
a fork(2) or clone() where the CLONE_NEWNS flag is not set, the child lives in the 
same mount namespace as the parent.

另外:

代码语言:javascript
复制
After a clone() where the CLONE_NEWNS flag is set, the cloned child is started in a 
new mount namespace, initialized with a copy of the namespace of the parent.

现在,如果我使用clone()CLONE_NEWNS来创建子进程,这是否意味着该子进程将获得树中挂载点的精确副本(5 & 6),并且仍然能够访问原始树的其余部分?这是否也意味着子进程可以随意挂载5和6,而不会影响其父进程的挂载命名空间中挂载的5或6。

如果是,这是否也意味着子进程可以挂载/卸载不同于5或6的目录,并影响父进程可见的内容?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-06 10:45:12

进程的“挂载名称空间”就是它所看到的一组挂载的文件系统。一旦您从拥有一个全局挂载名称空间的传统情况转变为具有每个进程的挂载名称空间,您必须决定在使用clone()创建子进程时要做什么。

传统上,挂载或卸载文件系统会更改所有进程看到的文件系统:只有一个全局挂载名称空间,所有进程都会看到,如果进行任何更改(例如,使用mount命令),所有进程都会立即看到更改,而不管它们与mount命令的关系如何。

使用每个进程的挂载名称空间,子进程现在可以具有与其父进程不同的挂载名称空间。现在出现的问题是:

子进程对装载命名空间所做的更改是否应传播回父进程?

显然,这一功能至少必须得到支持,实际上,可能必须是默认的。否则,启动mount命令本身不会产生任何更改(因为父shell看到的文件系统不会受到影响)。

同样清楚的是,还必须能够抑制这种必要的传播,否则我们永远不能创建其挂载名称空间与其父进程不同的子进程,并且我们将再次拥有一个全局挂载名称空间(init看到的文件系统)。

因此,在使用clone()创建子进程时,我们必须决定子进程是从父进程获取自己的已安装文件系统的数据副本(它可以在不影响父进程的情况下进行更改),还是获取指向父进程的相同数据结构的指针(当您从shell启动mount时,更改是传播回来所必需的)。

如果将CLONE_NEWNS标志传递给clone(),则子进程将获得其父进程的已挂载文件系统数据的副本,它可以在不影响父进程的挂载名称空间的情况下对其进行更改。否则,它将获得一个指向父进程的挂载数据结构的指针,父进程将看到该子进程所做的更改(这样mount命令本身就可以工作)。

现在,如果我使用带CLONE_NEWNS的克隆创建子进程,这是否意味着该子进程将获得树中装载点的精确副本(5 & 6),并且仍然能够访问原始树的其余部分?

是。在调用clone()之后,它会看到与其父对象完全相同的树。

还意味着子进程可以随意挂载5和6,而不会影响其父进程的挂载命名空间中挂载在5或6处的内容。

是。因为您已经使用了CLONE_NEWNS,所以子进程可以从5卸载一个设备,然后在那里挂载另一个设备,并且只有它(及其子进程)可以看到更改。在这种情况下,没有其他进程可以看到该子进程所做的更改。

如果是,这是否也意味着子进程可以挂载/卸载不同于5或6的目录,并影响父进程可见的内容?

不是的。如果您使用过CLONE_NEWNS,则在子进程中所做的更改不能传播回父进程。

如果您没有使用过CLONE_NEWNS,那么子进程将收到一个指向与其父进程相同的挂载名称空间数据的指针,并且子进程所做的任何更改都将被共享这些数据结构的任何进程看到,包括父进程。(使用fork()创建新的子项时也是如此。)

票数 28
EN

Stack Overflow用户

发布于 2014-10-28 16:16:34

我没有足够的名誉点来添加评论,所以添加这条评论作为回答。这只是Emmet答案的补充。

如果创建进程时设置了CLONE_NEWNS标志,则它只能挂载那些设置了FS_USERNS_MOUNT标志的文件系统。并且几乎所有基于磁盘的文件系统都不设置该标志(由于安全原因)。在do_new_mount中,有这样的检查:

代码语言:javascript
复制
        if (user_ns != &init_user_ns) {
            if (!(type->fs_flags & FS_USERNS_MOUNT)) {
                    put_filesystem(type);
                    return -EPERM;
            }

如果我说错了,请纠正我

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22889241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档