为什么不能重命名(或移动)挂载点?

为什么不能重命名(或移动)挂载点?

我可以移动挂载点的父目录,如下所示:

$ mkdir -p f/mnt
$ bindfs --no-allow-other f/mnt f/mnt
$ mv f g
$

但我无法重命名挂载点本身:

$ mv g/mnt g/m
mv: cannot move 'g/mnt' to 'g/m': Device or resource busy

这种区别是否存在安全性、兼容性或实现方面的原因?

我的内核版本是4.17.19-200.fc28.x86_64。

答案1

希利关于为什么这不起作用的答案是准确的。

然而,你实际上在 Linux 上移动挂载点本身。借用问题中的示例,正​​确的方法是:

mount --move g/mnt g/m

目标目录(在本例中g/m)必须是安装点的有效位置(该目录必须存在等),并且您必须以 root 权限(或 CAP_MOUNT)运行,但除此之外基本上没有任何限制。

此操作将更新所有内核管理引用该挂载点的数据结构,包括挂载表条目(在当前挂载命名空间内)、打开的文件描述符、运行程序的根目录和当前工作目录以及其他一些内容,因此在挂载点正在使用中。

需要注意的是,任何正在运行并使用路径而不是文件描述符的东西都可能无法正确处理它(例如,以这种方式移动网站的根目录可能会破坏网站,因为大多数网络服务器不会保留对所有内容的开放引用)站点的文件)。

您可能还会发现该pivot_root命令很有趣,它是移动挂载点的特殊情况(它交换两个挂载点并更新系统上所有内容的根目录和当前工作目录),并且在大多数现代 Linux 系统的启动过程中用于切换从 initramfs 到真正的根文件系统。

答案2

您无法重命名文件系统的根目录,但这正是您喜欢做的。

如果您使用底层挂载点 NFS 挂载文件系统,您可以重命名它,因为这允许您看到未覆盖的挂载点。

背景:如果将某些内容安装到文件系统中的某个条目,则会隐藏原始文件,但您需要重命名原始文件。您看到的是已安装文件系统的根目录,并且无法重命名。

答案3

是:兼容性原因影响安全性。

由于 LWN.net 忠实报道的原因,这一限制并未被故意取消。取消该限制会在某些版本的fusermount. fusermount之前已通过添加进行了改进UMOUNT_NOFOLLOW,这使其安全。然而,旧版本fusermount仍然广泛传播,足以引起人们的关注。

挂载点删除和重命名,LWN.net 2016。

据我从链接的线程中得知,补丁 1-3 允许移动挂载点。然后添加了补丁 4 来禁止它:-)。

这不是完整的证明。然而,这表明补丁 4 中的限制并不是由于内部原因执行原因。我还相信内核开发人员会提到,如果他们有任何想法的话用户期望如果允许移动挂载点就会被破坏。

然而,@schily 指出允许移动(或取消链接)安装点有点奇怪。看来是可能的以允许rename()安装点。但这仅仅是因为它被解释为重命名已安装文件系统底层的文件。

对于当前规则来说,这将是一个奇怪的例外,它rename(oldpath, newpath)要求旧路径和新路径位于同一文件系统上。否则 EXDEV 会失败。 (事实上​​他们一定是在文件系统的同一挂载上)。

我想到了 Linux 下的一个额外的小奇怪之处。如果你在底层文件上设置 Linux“不可变位”,我认为 rename() 应该被拒绝。但是,如果您检查挂载点上的不可变位,您将看不到底层文件的不可变位!我希望它能正常工作,如果您必须对其进行故障排除,那将是相当烦人的。

相关内容