我正在阅读mount& clone手册页。我想澄清一下CLONE_NEWNS如何影响子进程的文件系统视图。
(文件层次结构)
让我们将此树视为目录层次结构。让我们说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在其意志中,不影响其父进程的mount命名空间中挂载在5或6的内容。
如果是,是否也意味着孩子可以挂载/卸载5或6之外的其他目录并影响父进程可见的内容?
感谢。
答案 0 :(得分:17)
进程的“mount namespace”只是它看到的挂载文件系统集。一旦您从具有一个全局装入命名空间的传统情况变为具有每个进程装载命名空间,您必须决定在使用clone()
创建子进程时要执行的操作。
传统上,安装或卸载文件系统会改变所有进程看到的文件系统:所有进程都可以看到一个全局安装命名空间,以及是否进行了任何更改(例如使用mount
命令)所有进程不管它们与mount
命令的关系如何,都会立即看到这种变化。
使用每进程挂载命名空间,子进程现在可以与其父进程具有不同的挂载命名空间。现在出现的问题是:
子项所做的mount命名空间的更改是否会传播回父级?
显然,此功能必须至少必须支持,实际上,必须是默认值。否则,启动mount
命令本身不会产生任何变化(因为父shell看到的文件系统不会受到影响)。
同样清楚的是,必须还可以抑制抑制,否则我们永远不能创建一个子进程,其mount命名空间与其父进程不同,我们再次有一个全局mount命名空间(init
所见的文件系统)。
因此,我们必须决定何时使用clone()
创建子进程,以确定子进程是否从父进程获取有关已挂载文件系统的数据的副本,它可以在不影响父进程的情况下进行更改,或获取指针与父进程相同的数据结构,它可以更改(更改传播回来所必需的,就像从shell中启动mount
一样)。
如果CLONE_NEWNS
标志传递给clone()
,则子项获取其父级已挂载文件系统数据的副本,它可以更改,而不会影响父级的mount命名空间。否则,它会获得父级挂载数据结构的指针,其中父级将看到子级所做的更改(因此mount
命令本身可以正常工作)。
现在,如果我使用克隆与CLONE_NEWNS创建子进程,这是否意味着子将获得树中的挂载点的精确副本(5& 6)并仍然能够访问原始的其余部分树?
是。在调用clone()
之后,它会看到与其父树完全相同的树。
这是否意味着孩子可以安装5& 6在其意志中,不影响其父进程的mount命名空间中挂载在5或6的内容。
是。由于您使用了CLONE_NEWNS
,因此孩子可以从5中卸载一个设备并在那里安装另一个设备,只有它(及其子设备)可以看到更改。在这种情况下,没有其他过程可以看到孩子所做的更改。
如果是,是否也意味着孩子可以挂载/卸载5或6之外的其他目录并影响父进程可见的内容?
没有。如果您使用了CLONE_NEWNS
,则子项中所做的更改无法传播回父级。
如果你没有使用CLONE_NEWNS
,那么孩子将收到一个指向与其父级相同的装载命名空间数据的指针,并且子级所做的任何更改都会被任何共享这些数据结构的进程,包括父进程。 (当使用fork()
创建新子项时也是这种情况。)
答案 1 :(得分:4)
我没有足够的声誉点来添加评论,因此请将此评论添加为答案。 它只是Emmet答案的补充。
AFAICU,如果创建了一个设置了CLONE_NEWNS标志的进程,它只能挂载那些设置了FS_USERNS_MOUNT标志的文件系统。几乎所有基于磁盘的文件系统都没有设置此标志(由于安全原因)。 在do_new_mount中,有这个检查:
if (user_ns != &init_user_ns) {
if (!(type->fs_flags & FS_USERNS_MOUNT)) {
put_filesystem(type);
return -EPERM;
}
如果我错了,请纠正我