![FreeBSD 手册页中关于 mount_nullfs 的声明“getcwd 函数正常工作”的含义是什么?](https://linux22.com/image/128380/FreeBSD%20%E6%89%8B%E5%86%8C%E9%A1%B5%E4%B8%AD%E5%85%B3%E4%BA%8E%20mount_nullfs%20%E7%9A%84%E5%A3%B0%E6%98%8E%E2%80%9Cgetcwd%20%E5%87%BD%E6%95%B0%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C%E2%80%9D%E7%9A%84%E5%90%AB%E4%B9%89%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
在 FreeBSD 中,man mount_nullfs
指出:
文件系统的虚拟副本和符号链接之间的主要区别是这
getcwd(3)
功能正常工作在虚拟副本中,并且其他文件系统可以安装在虚拟副本上而不影响原始文件系统。虚拟副本的不同设备号由以下命令返回stat(2)
但在其他方面却与原作没有什么区别。
这一段的完整含义/含义是什么?
答案1
文件系统的虚拟副本和符号链接之间的主要区别是功能
getcwd(3)
正常工作在虚拟副本中,
getcwd
符号链接目录的行为是一个相当著名的陷阱,记录在高级 Unix 编程例如(参见这个问题引用):当涉及符号链接时,它们不是对称的chdir
。getcwd
人们可能期望更改目录,使用chdir
,到给定目录,然后检索当前目录,使用getcwd
,将返回相同的值;但当进程使用包含符号链接的路径更改目录时,情况并非如此 -getcwd
返回取消引用所有符号链接后获得的路径。当将目录更改为父目录时,当包含符号链接的路径和取消引用的路径具有不同数量的组件时,这可能会产生意想不到的后果。
并且其他文件系统可以安装在虚拟副本上而不影响原始文件系统。
继续斯蒂芬的例子,您可以在 的子目录上挂载另一个文件系统/tmp/b
而不影响/some/dir
,而在 的子目录上挂载文件系统/tmp/a
也会使其显示在 下/some/dir
。
返回虚拟副本的不同设备号
stat(2)
,但在其他方面它与原始设备没有区别。
这意味着stat
在副本或其下的任何文件上运行将返回与原始设备相比不同的设备号,但这是唯一的区别;除此之外,stat("/tmp/b/c", &buf)
并stat("/some/dir/c", &buf)
会返回相同的信息。
答案2
我认为他们的意思是 if/tmp/a
是一个符号链接/some/dir
并且/tmp/b
是一个 nullfs 挂载/some/dir
,
- 之后
chdir("/tmp/a")
,getcwd()
返回/some/dir
。 - 之后
chdir("/tmp/b")
,getcwd()
返回/tmp/b
。
前者并不那么重要不正确。只是符号链接和 nullfs 挂载有两种不同的语义。
符号链接是指向大多数系统调用(包括chdir()
)所遵循的另一个文件的指针,而 nullfs 挂载使整个目录树在不同的路径下可用(与 Linux 类似的绑定挂载功能或某些其他系统中的目录硬链接相反) ,那里的文件显示为不同的文件)。
符号链接处理可能会打破某些人的期望(就像getcwd()
这里的那样),但是 nullfs 挂载(或 Linux 上的 binfs 保险丝文件系统或某些联合文件系统)可能会打破其他人的期望,就像事实[ /tmp/b/x -ef /some/dir/x ]
会返回 false,即使它们下面是相同的文件,或者fuser /tmp/b/x
即使有进程通过/some/dir/x
路径打开它也不会返回任何内容。
Linux 绑定挂载(不会使文件看起来不同)可能会打破其他人的期望,例如find -xdev
/du -x
遍历挂载点、链接计数为 1 的同一文件的两个链接(它还允许循环在文件系统中创建;FreeBSD 的 nullfs 可以防止这种情况发生)。
硬链接(使文件出现在不同路径下的最古老的技术)也可能会打破某些用户的期望(例如,当您从目录中取消链接文件时,您期望它不再可用)。
所以我不会说一个是更多正确的比这里的另一个。