我正在阅读 mount & clone手册页。我想阐明 CLONE_NEWNS 如何影响子进程的文件系统 View 。
(文件层次结构)
让我们将此树视为目录层次结构。假设 5 和 6 是父进程中的挂载点。我在另一个 question 中阐明了挂载点.
所以我的理解是:5 和 6 是挂载点意味着 mount
命令之前用于在 5 和 6 处“挂载”文件系统(目录层次结构)(这意味着必须有目录5 和 6 岁以下的树)。
来自 mount
手册页:
A mount namespace is the set of filesystem mounts that are visible to a process.
来自 clone
手册页:
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.
还有:
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 不同的目录并影响父进程可见的内容?
谢谢。
最佳答案
一个进程的“挂载命名空间”就是它看到的一组挂载文件系统。一旦您从拥有一个全局挂载命名空间的传统情况转变为拥有每个进程挂载命名空间,您必须决定在使用 clone()
创建子进程时要做什么。
传统上,挂载或卸载文件系统会改变所有进程看到的文件系统:有一个全局挂载命名空间,所有进程都看到,如果进行了任何更改(例如使用 mount
命令) 所有进程都会立即看到该更改,无论它们与 mount
命令的关系如何。
有了每个进程的挂载命名空间,子进程现在可以拥有与其父进程不同的挂载命名空间。现在问题来了:
子项对挂载命名空间所做的更改是否应该传播回父项?
显然,此功能必须至少得到支持,而且实际上必须是默认功能。否则,启动 mount
命令本身不会产生任何变化(因为父 shell 看到的文件系统不会受到影响)。
同样清楚的是,这种必要的传播也必须有可能被抑制,否则我们永远无法创建一个其挂载命名空间与其父进程不同的子进程,我们又拥有一个全局挂载命名空间(init
看到的文件系统)。
因此,我们必须决定在使用 clone()
创建子进程时,子进程是否从父进程获取有关已挂载文件系统的数据副本,它可以在不影响父进程的情况下更改这些数据, 或者获取指向与父级相同的数据结构的指针,它可以更改(更改传播回来所必需的,就像从 shell 启动 mount
时一样)。
如果 CLONE_NEWNS
标志被传递给 clone()
,子进程将获得其父进程已挂载文件系统数据的副本,它可以在不影响父挂载命名空间的情况下进行更改。否则,它会得到一个指向父级挂载数据结构的指针,其中子级所做的更改将被父级看到(因此 mount
命令本身可以工作)。
Now if I use clone with CLONE_NEWNS to create a child process, does this mean that child will get an exact copy of the mount points in the tree (5 & 6) and still be able to access the rest of the original tree ?
是的。在调用 clone()
后,它会看到与其父级完全相同的树。
Does it also mean that the child could mount 5 & 6 at its will, without effecting what's mounted at 5 or 6 in its parent process's mount namespace.
是的。由于您已经使用了 CLONE_NEWNS
, child 可以从 5 卸载一个设备并在那里安装另一个设备,并且只有它(和它的 child )可以看到更改。在这种情况下,没有其他进程可以看到 child 所做的更改。
If yes, does it also mean that child could mount / unmount a different directory than 5 or 6 and effect what's visible to the parent process ?
没有。如果您使用了 CLONE_NEWNS
,则对子项所做的更改无法传播回父项。
如果您没有使用CLONE_NEWNS
,那么子节点会收到一个指向与其父节点相同的挂载命名空间数据的指针,并且子节点所做的任何更改都会被共享这些数据结构的任何进程看到,包括父进程。 (当使用 fork()
创建新的 child 时也是如此。)
关于Linux - 了解挂载命名空间和克隆 CLONE_NEWNS 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22889241/