![是否存在“ln -d”成功的文件系统?](https://linux22.com/image/84945/%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E2%80%9Cln%20-d%E2%80%9D%E6%88%90%E5%8A%9F%E7%9A%84%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%EF%BC%9F.png)
从联机帮助页来看因:
-d, -F, --directory
allow the superuser to attempt to hard link directories (note: will
probably fail due to system restrictions, even for the superuser)
是否有任何文件系统驱动程序实际上允许这样做,或者是唯一的选择mount --bind <src> <dest>
?或者这种行为在到达文件系统特定的驱动程序之前就被内核阻止了?
注意:我实际上并不打算在任何机器上执行此操作,只是好奇。
答案1
首先注意:该ln
命令没有-d
、-F
、等选项--directory
,这是一个不可移植的 GNUism。
您正在寻找的功能是通过link(1)
命令实现的。
回到你原来的问题:
在典型的 UNIX 系统上,目录上的硬链接是否可能是由文件系统驱动程序决定的。
Solaris UFS 驱动程序支持目录上的硬链接,而 ZFS 驱动程序不支持。
Solaris 上的 UFS 支持硬链接的原因是 AT&T 对这个功能感兴趣——BSD 上的 UFS 不支持硬链接目录。
ZFS 不支持硬链接目录的原因是 Jeff Bonwick 不喜欢该功能。
关于Linux,我猜测Linux会阻止在上层内核层的目录上创建硬链接的尝试。做出这种假设的原因是 Linus Torvalds 为 GIT 编写了代码,当在git clone
支持硬链接目录的平台上以 root 身份调用时,该代码会粉碎目录。
请注意,支持创建硬链接目录的文件系统还需要支持unlink(1)
以 root 身份删除非空目录。
因此,如果我们假设 Torvalds 知道 Linux 是如何工作的,并且如果 Linux 确实支持硬链接目录,那么 Torvalds 应该知道以unlink(2)
root 身份调用目录不会返回错误,而是会粉碎该目录。换句话说,Linux 不太可能允许文件系统驱动程序实现硬链接目录。
答案2
OP的问题提到mount --bind
。快速检查表明它不会修改已安装目录的链接计数。硬链接总是修改链接计数,您可以使用 来查看ls -ld
。
通常(大多数类 Unix 系统),目录的硬链接数量将是连接到该名称的目录数量,例如,
".."
(父目录)"."
(目录本身)- 子目录
如果您阅读(通常)信息更丰富的信息页面,您可能会发现其他的完成了:
Oh great, one spends hours tying to find what is wrong only to
discover,
$ info ln
On all existing implementations, you cannot make a hard link to a
directory, and hard links cannot cross filesystem boundaries. (These
restrictions are not mandated by POSIX, however.)
Therefore, kindly say everywhere you say super-user only,
instead say "few systems, super-user only".
虽然它现在是措辞
大多数系统禁止建立到目录的硬链接;在允许的地方,只有超级用户可以这样做(并且要小心,因为创建循环会给许多其他实用程序带来问题)。硬链接不能跨越文件系统边界。 (但是,POSIX 并未强制要求这些限制。)
创建(和删除)目录的硬链接是一项受限制的功能,以防止在取消链接目录时丢失文件。因为C操作系统接口的链接/取消链接操作是对称的,到目录的链接通常仅在 mkdir/rmdir 调用中完成。
请记住,GNU coreutils 的大部分内容是在 20-30 年前编写(和记录)的,当时一些真正的博物馆藏品仍在使用。如中所述关于硬链接, 原来有是没有 mkdir/rmdir 调用;目录是使用硬链接创建的(作为特权操作)。当添加系统调用来解决上述问题时,所有这些都消失了。但文档中仍然引用这些系统,而这些系统的维护者已经记不清了。受到质疑的选项是在前身中(在 20 世纪 90 年代中期与和fileutils
合并形成)。变更日志中的一些项目可能有助于阐明该功能的起源:textutils
shellutils
coreutils
Mon Jul 23 16:57:44 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
* cp.c (copy): Make +update operate silently, like +one-file-system.
* ln.c: Add -F as synonym for -d, for SunOS compatibility.
Wed Feb 21 11:13:26 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
* ln.c (error): New function.
(main, do_link): Call error instead of fprintf and exit.
(main): Recognize new -d +directory option to allow superuser to
make hard links to dirs, like the BSD ln -f option.
(do_link): Don't allow hard links to dirs (they are hard to
get rid of -- rmdir and unlink don't do it), unless -d was given.
(usage): Mention -d +directory option.
因此,您可以看到,例如,适用此功能的古董之一是 SunOS。相应的手册页说道:
OPTIONS
-f Force a hard link to a directory -- this option is only avail-
able to the super-user.
-s Create a symbolic link or links.
SYSTEM V OPTIONS
-f Force files to be linked without displaying permissions, asking
questions or reporting errors.
-F Force a hard link to a directory -- this option is only avail-
able to the super-user.
-s Create a symbolic link or links.
正如文档中所述,此功能(以及相应的选项不在 POSIX 中(请参阅基本原理部分解释了原因)。相反,该功能被转移到一个新命令(也由 GNU coreutils 提供),称为link
。命令本身的描述是模糊的;你必须阅读的描述函数调用从标准中获得任何用途。然而,除了提出有关所需特权的免责声明外,该标准并未阐明该命令的工作条件。为此,您必须使用标准之外的系统相关功能:
在大多数历史实现中,链接到目录仅限于超级用户,因为此功能可能会在文件层次结构中产生循环或以其他方式损坏文件系统。 POSIX.1-2008 的本卷通过禁止
link()
和unlink()
禁止这样做来延续这一理念。如果实现者设计了这样的扩展,其他函数也可以做到这一点。
那里是使用硬链接到超出正常数量的目录(2 个加上子目录)的系统。
OSX 使用多个硬链接到普通目录文件。它不支持这种使用ln
(请参阅手册页)。根据时间机器如何发挥魔力,它这样做是为了提供用于 Time Machine 备份工具的版本。
进一步阅读: