为什么我无法从同一文件系统上的“mount --bind”目录创建指向文件的“硬链接”?

为什么我无法从同一文件系统上的“mount --bind”目录创建指向文件的“硬链接”?

原始问题

我在一个文件系统上有一个文件:/data/src/file

我想将其硬链接到:/home/user/proj/src/file

/home在一个磁盘上,并且/data在另一个磁盘上,所以我收到错误:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

好的,所以我了解到我无法跨设备进行硬链接。说得通。

手头的问题

所以我想我会喜欢并绑定安装文件系统src上的文件夹:/data

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

为什么这仍然不起作用?

解决方法

我知道我的设置是正确的,因为只要我位于“真实”/data目录而不是绑定目录中,我就可以建立硬链接。

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

一些系统信息

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

笔记:我手动更改了文件和目录名称以使情况更清晰,因此命令读数中可能有一两个拼写错误。

答案1

令人失望的是缺乏评论代码。自从绑定挂载在 v2.4 中实现以来,就好像没有人认为它有用一样。当然,您需要做的就是替换.mnt->mnt_sb它所说的地方.mnt......

因为它为您提供了子树周围的安全边界。

PS:这已经讨论过很多次了,但为了避免搜索:考虑例如 mount --bind /tmp /tmp;现在你遇到了这样一种情况,即用户无法创建到其他地方没有根文件系统的链接,即使他们具有可写的 /tmp 。类似的技术适用于其他隔离需求 - 基本上,您可以将重命名/链接限制到给定的子树。 IOW,这是一个故意的功能。请注意,您可以将一堆树绑定到 chroot 中并获得可预测的限制,无论一年后这些内容在主树中如何重新排列,等等。

--阿尔维罗

线程下面有一个具体的例子

每当我们让 mount -r --bind 正常工作时(我用它来将必要的共享库的副本放置在 chroot 监狱中,同时允许页面缓存共享),此功能就会破坏安全性。

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

虽然保护应该足够了,但我宁愿避免让囚犯链接 /jail/lib/libfoo.so (写入返回 EROFS)到 /jail/usr/log ,因为它可能是可写的。

答案2

您无法进行跨设备链接的原因是因为您引入了歧义。文件的目录条目包含(在简单系统中)相关文件的索引节点号。硬链接(只是另一个目录条目)也必须包含相同的 i 节点号。这很好,但 i 节点编号仅在单个文件系统中是唯一的(它们通常是从 1 开始的密集集)。

您的绑定安装无法解决该问题。是的,它构建了一种结构的“虚构”,但它没有做的是重新编号一个文件系统上的所有 i 节点,以确保它们在相关文件系统中都是唯一的!那太愚蠢了。

这个限制在 UNIX 系统上一直存在。符号链接的发明部分是为了解决这个问题。我知道它们在功能上并不完全相同,但通常都很好。

尝试符号链接吗? ( ln -s)

相关内容