使用 NFS 挂载时,如何在目录中包含两个同名文件?

Wil*_*mKF 8 centos deduplication filesystems nfs

我有一个 C++ 应用程序测试,它在 NFS 挂载目录中创建了 10,000 个文件,但我的测试最近失败了一次,因为一个文件在该目录中与所有其他 10,000 个文件以相同的名称出现了两次。这可以在安装了 NFS 目录的 Linux Centos v4 或 v5 上看到,但不能在磁盘所在的主机上看到。

怎么可能在同一个目录中有两个同名的文件?

[centos4x32 destination] ls -al ./testfile03373
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
[centos4x32 destination] ls -al ./testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
[centos4x32 destination] ls -al *testfile03373
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
[centos4x32 destination] ls -alb test*file03373
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
Run Code Online (Sandbox Code Playgroud)

运行以下答案之一中建议的 Perl 脚本:

ls -la *03373* | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
Run Code Online (Sandbox Code Playgroud)

给出:

-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
Run Code Online (Sandbox Code Playgroud)

使用 inode (-i) 值打印显示两个副本具有相同的 inode 条目 (36733444):

[h3-centos4x32 destination] ls -alib te*stfile03373
36733444 -rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
36733444 -rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
Run Code Online (Sandbox Code Playgroud)

目录条目似乎以某种方式损坏了。

我的应用程序是否合法地创建了这种情况,或者这是操作系统中的错误?在创建文件的程序中,我可以采取什么措施来防止这种情况发生?

我认为 NFS 挂载软件中存在某种错误。同样'umount'然后'mount'有问题的NFS驱动器也不能解决它,重新安装后重复的条目仍然存在。


更新 1:我现在第二次遇到这个问题,几个小时后,真正奇怪的是它发生在完全相同的文件上testfile03373,尽管这次它有一个不同的 inode,213352984,用于加倍的文件。我还要补充一点,该文件是在托管磁盘的 Centos 5 机器上创建的,因此它是在本地创建的,并且在本地显示正确,但是 NFS 挂载它的所有其他机器都看到了双重条目。


更新 2:我将驱动器安装在 Centos v6 机器上,并/var/log/messages在列出并看到那里的双重条目后发现以下内容:

[root@c6x64 double3373file]# ls -laiB testfile03373* ; tail -3 /var/log/messages
36733444 -rwx------. 1 user root 3373 Sep  3 03:23 testfile03373
36733444 -rwx------. 1 user root 3373 Sep  3 03:23 testfile03373
...
Sep  4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor.  The file: testfile03373 has duplicate cookie 7675190874049154909
Sep  4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor.  The file: testfile03373 has duplicate cookie 7675190874049154909
Run Code Online (Sandbox Code Playgroud)

此外,我发现重命名文件会导致双条目消失,但将其重命名会使其重新出现双倍,或者只是触摸名称为 的新文件testfile03373,会导致出现双条目,但这仅发生在已看到此双重条目的两个目录。

Wil*_*mKF 8

一位朋友帮我追踪了这个问题,发现这是一个错误,记录在Bugzilla 38572 中,适用于此处的 Linux 内核。该错误应该在内核的 3.0.0 版中修复,但至少在 2.6.38 版中存在。

问题是服务器的 ReadDIR() RPC 调用返回不正确的结果。发生这种情况的原因如下:

当客户端读取目录时,它指定最大缓冲区大小并将 cookie 清零。如果目录太大,则回复表明回复只是部分并更新cookie。然后客户端可以使用更新的 cookie 重新执行 RPC 以获取下一个数据块。(数据是文件句柄和名称的集合。在 ReadDirPlus() 的情况下,还有 stat/inode/vnode 数据。)文档并未表明这是 ReadDirPlus() 的错误,但它可能存在以及。

实际问题是每个块中的最后一个文件(名称,句柄元组)有时会作为下一个块中的第一个文件返回。

与底层文件系统存在不良交互。Ext4 展示了这一点,而 XFS 没有。

这就是为什么在某些情况下会出现问题而在其他情况下不会出现问题并且很少出现在小目录上的原因。如问题描述中所示,文件显示相同的 inode 编号并且名称相同(未损坏)。由于 Linux 内核为 open() 等底层操作调用 vnode 操作,因此文件系统的底层例程决定发生什么。在这种情况下,如果所需信息不在其属性缓存中,NFS3 客户端只会将 vnode 操作转换为 RPC。这会导致混淆,因为客户端认为服务器无法执行此操作。


Law*_*ceC 6

该磁盘是 NFS 挂载磁盘。当我转到发布驱动器的主机时,该文件只列出一次。

可能是 NFS 的错误、问题或竞争条件。

如果您使用十六进制编辑器直接编辑文件系统结构,则可能有两个同名文件。但是,我不确定如果您尝试删除或打开文件会发生什么。我不确定 Linux 上有哪些工具可以通过 inode 编号(不能复制)访问文件,但这可能有效。

重复的文件名fsck可能会被捕获并尝试修复。

确保所有文件都没有不同的尾随空格。