NFSでマウントした場合、ディレクトリに同じ名前の2つのファイルを含めるにはどうすればよいですか?


8

NFSマウントされたディレクトリに10,000ファイルを作成するC ++アプリケーションテストがありますが、他のすべての10,000ファイルと同じディレクトリに同じ名前で1つのファイルが2回表示されるため、最近1回失敗しました。これは、ディレクトリがNFSマウントされているLinux Centos v4またはv5で確認できますが、ディスクが存在するホストマシンでは確認できません。

同じディレクトリに同じ名前の2つのファイルを持つことはどうして可能ですか?

[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*

以下の回答の1つで提案されているPerlスクリプトを実行します。

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

与える:

-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*

iノード(-i)値を使用して印刷すると、2つのコピーが同じiノードエントリを持っていることが示されます(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*

どうやらディレクトリエントリが壊れているようです。

アプリケーションがこの状況を合法的に作成した可能性がありますか、それともオペレーティングシステムのバグですか?ファイルを作成するプログラムでこれを防ぐためにできることはありますか?

NFSマウントソフトウェアに何らかのバグがあると思います。また、問題のあるNFSドライブを「umount」してから「mount」しても解決されず、再マウント後も繰り返されるエントリが残ります。


更新1:数時間後、この問題testfile03373に再度遭遇しました。本当に奇妙なのは、まったく同じファイルで発生したことですが、今回は213352984のように、二重化されたファイルに対して別のiノードが取得されました。また、ファイルがディスクがホストされているCentos 5マシンで作成されているため、ローカルで作成され、ローカルで正しいことが示されていますが、NFSでマウントされている他のすべてのマシンでは、エントリが2重になっています。


更新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

さらに、ファイルの名前を変更すると二重エントリが消えますが、名前を元に戻すと二重に表示されます。または、名前がの新しいファイルに触れるだけでtestfile03373二重エントリが表示されますが、これはこの二重エントリが表示されている2つのディレクトリ。


私の知る限り、同じファイル名で同じ拡張子の2つのファイルが同じディレクトリに共存することは不可能です。プログラムでいくつかの例外メカニズムを使用して、失敗を防ぐことができます。これ以外のことは...
Doktoro Reichard

どのファイルシステムを使用していますか?
Doktoro Reichard

それらはまったく同じですか?たとえば、先頭または末尾の空白はありませんか?UTF-16文字なし、...
Hennes

まったく同じであることを確認するために、他にどのようなテストを実行できますか?
WilliamKF 2013

重要なOSの健全性チェックを回避する方法を学習したようですね。
Fiasco Labs

回答:


8

友人がこれを追跡するのを手伝ってくれたところ、これがバグ38572に記録されているLinuxカーネルのバグであることがわかりまし。このバグはカーネルのバージョン3.0.0で修正されていると思われますが、少なくともバージョン2.6.38には存在します。

問題は、サーバーのReadDIR()RPC呼び出しが誤った結果を返すことです。これは、次のことが原因で発生します。

クライアントがディレクトリを読み取るとき、最大バッファーサイズを指定し、Cookieをゼロにします。ディレクトリが大きすぎる場合、応答は応答が部分的であることを示し、Cookieを更新します。次に、クライアントは更新されたCookieを使用してRPCを再実行し、次のデータのチャンクを取得できます。(データはファイルハンドルと名前のセットです。ReadDirPlus()の場合は、stat / inode / vnodeデータもあります。)ドキュメントには、これがReadDirPlus()のバグであることは示されていませんが、おそらくそこにあります。同様に。

実際の問題は、各チャンクの最後のファイル(名前、ハンドルタプル)が次のチャンクの最初のファイルとして返されることあるということです。

基礎となるファイルシステムとの不適切な相互作用があります。Ext4はこれを示しますが、XFSは示しません。

このため、問題が発生する場合と発生しない場合があり、小さなディレクトリではほとんど発生しません。質問の説明にあるように、ファイルは同じiノード番号を示し、名前は同じです(破損していない)。Linuxカーネルはopen()などの基本的な操作のためにvnode操作を呼び出すので、ファイルシステムの基本的なルーチンが何が起こるかを決定します。この場合、必要な情報が属性キャッシュにない場合、NFS3クライアントはvnode操作をRPCに変換するだけです。サーバーがこれを行うことができないとクライアントが信じているので、これは混乱につながります。


カーネル3.18.17-13.el6.x86_64(CentOS 6)でも同じです。ディレクトリがマウントされているQNAP TS-212 NASの基盤となるNFSシステムのバグだと確信しています。誰かが確認しますか?
godzillante 2015

6

ディスクはNFSマウントされたディスクです。ドライブを公開するホストコンピューターにアクセスすると、ファイルは1回しか表示されません。

おそらくNFSのバグ、問題、または競合状態です。

16進エディタを使用してファイルシステム構造を直接編集すると、同じ名前の2つのファイルが存在する可能性があります。ただし、ファイルを削除または開こうとするとどうなるかわかりません。Linuxにiノード番号(複製できない)でファイルにアクセスするためのツールが存在するかどうかはわかりませんが、動作する可能性があります。

重複するファイル名は、fsckキャッチして修正しようとするものです。

ただし、ファイルの末尾に異なるスペースがないことを確認してください。


私は、ファイルシステムへの書き込みの量が最終的に何かを壊し、2つの同一のファイルの存在を許可したことを示唆していました。
Doktoro Reichard

実行してfsckも問題は見つかりませんでした。ホストマシンとクライアントマシンの両方を再起動したが、まだ問題が表示される。
WilliamKF 2013

私はもっ​​と明確だったはずです- fsckおそらくローカルファイルシステムでのみ機能し、NFSマウントされたファイルシステムでは機能しません。おそらく、nfsパッケージおよびおそらくカーネルをアップグレード/パッチする必要があります。@somequixoticが言及しているように、CentOSは古く、発生している問題は将来のアップデートで解決される可能性があります。
LawrenceC

4

ファイル名の1つに非表示の非表示文字または空白がある可能性があります。に-bオプションを提供することで確認できますls。例:

user@server:~/test$ ls -lab
total 8
drwxr-xr-x 2 user user 4096 Sep  3 12:20 .
drwx------ 8 user user 4096 Sep  3 12:20 ..
-rw-r--r-- 1 user user    0 Sep  3 12:19 hello
-rw-r--r-- 1 user user    0 Sep  3 12:19 hello\

\そのファイル名の末尾のスペースを示すことに注意してください。

   -b, --escape
          print C-style escapes for nongraphic characters

別の方法として(上記は機能するはずですが)、出力をこのperlスクリプトにパイプして、印刷可能なASCII文字ではないものを16進コードに置き換えることができます。たとえば、スペースはになり\x20ます。

while (<>) {
    chomp();
    while (/(.)/g) {
        $c = $1;
        if ($c=~/[!-~]/) {
            print("$c");
        } else {
            printf("\\x%.2x", ord($c));
        }
    }
    print("\n");
}

使用法:

ls -la | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.