在 FreeBSD 中,man mount_nullfs
声明:
文件系统的虚拟副本和符号链接之间的主要区别在于功能在虚拟副本中
getcwd(3)
正常工作,并且其他文件系统可以安装在虚拟副本上而不影响原始文件。为虚拟副本返回了一个不同的设备编号stat(2)
,但在其他方面它与原始设备没有区别。
本段的全部含义/含义是什么?
在 FreeBSD 中,man mount_nullfs
声明:
文件系统的虚拟副本和符号链接之间的主要区别在于功能在虚拟副本中
getcwd(3)
正常工作,并且其他文件系统可以安装在虚拟副本上而不影响原始文件。为虚拟副本返回了一个不同的设备编号stat(2)
,但在其他方面它与原始设备没有区别。
本段的全部含义/含义是什么?
getcwd
对符号链接目录的行为是一个相当著名的陷阱,例如在Advanced Unix Programming中记录(请参阅this SO question for a quote):chdir
并且getcwd
在涉及符号链接时不是对称的。人们可能期望使用 将目录更改chdir
为给定目录,然后使用 检索当前目录getcwd
将返回相同的值;但当进程使用包含符号链接的路径更改目录时,情况并非如此——getcwd
返回取消引用所有符号链接后获得的路径。当包含符号链接的路径和取消引用的路径具有不同数量的组件时,这可能会在将目录更改为父目录时产生意想不到的后果。继续 Stéphane 的示例
/tmp/b
,您可以在不影响的子目录上挂载另一个文件系统/some/dir
,而在子目录下挂载文件系统/tmp/a
也会使其显示在下/some/dir
。这意味着
stat
在副本或其下的任何文件上运行将返回与原始设备号不同的设备号,但这是唯一的区别;除此之外,stat("/tmp/b/c", &buf)
并且stat("/some/dir/c", &buf)
会返回相同的信息。我认为他们的意思是 if
/tmp/a
是一个符号链接/some/dir
并且/tmp/b
是一个 nullfs mount of/some/dir
,chdir("/tmp/a")
,getcwd()
返回/some/dir
。chdir("/tmp/b")
,getcwd()
返回/tmp/b
。前者不正确,倒也不算多。只是符号链接和 nullfs 挂载有两种不同的语义。
符号链接是指向另一个文件的指针,大多数系统调用(
chdir()
包括,那里的文件显示为不同的文件)。符号链接处理可能会破坏某些人的期望(就像
getcwd()
这里的那样),但是 nullfs 挂载(或 Linux 上的 bindfs fuse 文件系统或某些联合文件系统)可能会破坏其他人的期望,例如[ /tmp/b/x -ef /some/dir/x ]
即使它们是下面的同一个文件,事实也会返回 false,或者fuser /tmp/b/x
即使有进程通过/some/dir/x
路径打开它也不会返回任何内容。Linux 绑定挂载(不会使文件看起来不同)可能会打破其他人的期望,例如
find -xdev
/du -x
遍历挂载点,链接计数为 1 的两个指向同一文件的链接(它还允许循环在文件系统中创建;FreeBSD 的 nullfs 可以防止这种情况发生)。硬链接(使文件出现在不同路径下的最古老的技术)也会打破一些用户的期望(例如,当您从目录中取消链接文件时,您希望它不再可用)。
所以我不会说一个比另一个更正确。