Bagaimana saya bisa memiliki dua file dengan nama yang sama di direktori ketika di-mount dengan NFS?

8

Saya memiliki tes aplikasi C ++ yang membuat 10.000 file dalam direktori yang dipasang NFS, tetapi pengujian saya baru-baru ini gagal satu kali karena satu file muncul dua kali dengan nama yang sama di direktori itu dengan semua 10.000 file lainnya. Ini dapat dilihat pada Linux Centos v4 atau v5 di mana direktori tersebut dipasang NFS, tetapi tidak pada mesin host di mana disk berada.

Bagaimana mungkin memiliki dua file dengan nama yang sama di direktori yang sama?

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

Menjalankan skrip Perl yang disarankan dalam salah satu jawaban di bawah:

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

memberi:

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

Mencetak dengan nilai inode (-i) menunjukkan dua salinan memiliki entri inode yang sama (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*

Tampaknya entri direktori rusak entah bagaimana.

Bisakah aplikasi saya secara sah membuat situasi ini atau ini bug di sistem operasi? Apakah ada yang bisa saya lakukan untuk melindungi ini dalam program saya yang membuat file?

Saya berpikir ada beberapa jenis bug dalam perangkat lunak pemasangan NFS. Juga 'umount' dan kemudian 'mount' dari drive NFS yang memiliki masalah tidak menyelesaikannya, entri berulang tetap setelah remount.


Pembaruan 1: Saya sekarang mendapatkan masalah ini untuk kedua kalinya, beberapa jam kemudian, dan hal yang sangat aneh terjadi pada file yang sama persis testfile03373, walaupun kali ini mendapat inode yang berbeda, 213352984, untuk file yang berlipat ganda. Saya juga akan menambahkan bahwa file sedang dibuat pada mesin Centos 5 di mana disk di-host, jadi sedang dibuat secara lokal, dan menunjukkan yang benar secara lokal, tetapi semua mesin lain yang NFS me-mountnya melihat entri yang berlipat ganda.


Pembaruan 2: Saya memasang drive pada mesin Centos v6 dan menemukan yang berikut /var/log/messagessetelah mendaftar dan melihat entri ganda di sana:

[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

Selain itu, saya menemukan bahwa mengubah nama file menyebabkan entri ganda menghilang, tetapi mengubah nama kembali menyebabkannya muncul kembali dua kali lipat, atau sebagai alternatif, hanya menyentuh file baru dengan nama testfile03373, menyebabkan entri ganda muncul, tetapi ini hanya terjadi di dua direktori tempat entri ganda ini terlihat.

WilliamKF
sumber
AFAIK, tidak mungkin untuk dua file dengan nama dan ekstensi yang sama hidup berdampingan dalam direktori yang sama dalam sistem file apa pun. Anda dapat menggunakan beberapa mekanisme pengecualian dalam program Anda untuk mencegah kegagalan, selain itu ini ...
Doktoro Reichard
Sistem file apa yang Anda gunakan?
Doktoro Reichard
Apakah mereka persis sama? Misalnya tidak ada spasi putih terdepan atau tambahan? tanpa karakter UTF-16, ...
Hennes
Tes lain apa yang dapat saya lakukan untuk mengonfirmasi bahwa semuanya persis sama?
WilliamKF
Kedengarannya seperti Anda belajar bagaimana melakukan akhir menjalankan sekitar cek kewarasan OS penting.
Fiasco Labs

Jawaban:

8

Seorang teman membantu saya melacak ini dan menemukan ini adalah bug yang tercatat di Bugzilla 38572 untuk kernel Linux di sini . Bug tersebut seharusnya diperbaiki di versi 3.0.0 dari kernel, tetapi setidaknya ada di versi 2.6.38.

Masalahnya adalah bahwa panggilan ReadDIR () RPC server mengembalikan hasil yang salah. Ini terjadi karena hal berikut:

Ketika klien membaca direktori, itu menentukan ukuran buffer maksimum dan nol cookie. Jika direktori terlalu besar, balasan menunjukkan bahwa balasan itu hanya sebagian dan memperbarui cookie. Kemudian klien dapat menjalankan kembali RPC dengan cookie yang diperbarui untuk mendapatkan potongan data berikutnya. (Data adalah kumpulan dari pegangan dan nama file. Dalam kasus ReadDirPlus (), ada juga data stat / inode / vnode.) Dokumentasi tidak menunjukkan bahwa ini adalah bug dengan ReadDirPlus (), tetapi mungkin ada demikian juga.

Masalah sebenarnya adalah bahwa file terakhir di setiap chunk (nama, handle tuple) kadang - kadang dikembalikan sebagai file pertama di chunk berikutnya.

Ada interaksi yang buruk dengan sistem file yang mendasarinya. Ext4 menunjukkan ini, XFS tidak.

Inilah sebabnya mengapa masalah muncul dalam beberapa situasi tetapi tidak dalam situasi lain dan jarang terjadi pada direktori kecil. Seperti yang terlihat pada deskripsi pertanyaan, file-file tersebut menunjukkan nomor inode yang sama dan nama-namanya identik (tidak rusak). Karena kernel Linux memanggil operasi vnode untuk operasi yang mendasarinya seperti open (), dll., Rutinitas yang mendasari sistem file memutuskan apa yang terjadi. Dalam hal ini, klien NFS3 hanya menerjemahkan operasi vnode menjadi RPC jika informasi yang diperlukan tidak ada dalam cache atributnya. Ini menyebabkan kebingungan karena klien percaya server tidak dapat melakukan ini.

WilliamKF
sumber
Itu terjadi pada saya juga, dengan kernel 3.18.17-13.el6.x86_64 (CentOS 6). Saya cukup yakin itu adalah bug dari sistem NFS yang mendasari QNAP TS-212 NAS yang mana direktori tersebut dipasang, dapat Adakah yang mengkonfirmasi?
godzillante
6

Disk adalah disk yang dipasang NFS. Ketika saya pergi ke komputer host yang menerbitkan drive, file hanya terdaftar sekali.

Mungkin kondisi bug, masalah, atau ras dengan NFS.

Dimungkinkan untuk memiliki dua file dengan nama yang sama jika Anda secara langsung mengedit struktur sistem file menggunakan hex editor. Namun saya tidak yakin apa yang akan terjadi jika Anda mencoba menghapus atau membuka file. Saya tidak yakin alat apa yang ada di Linux untuk mengakses file dengan nomor inode (yang tidak dapat diduplikasi) tetapi itu mungkin berhasil.

Nama file duplikat adalah sesuatu yang fsckkemungkinan akan ditangkap dan coba diperbaiki.

Pastikan tidak ada file yang memiliki spasi tambahan yang berbeda.

LawrenceC
sumber
Saya akan menyarankan bahwa jumlah penulisan pada filesystem pada akhirnya memecahkan sesuatu dan memungkinkan adanya dua file yang identik.
Doktoro Reichard
Berlari fscktidak menemukan masalah. Reboot kedua mesin host dan klien, masalah masih menunjukkan.
WilliamKF
Saya seharusnya lebih jelas - fsckmungkin hanya akan bekerja pada sistem file lokal, bukan yang dipasang NFS. Anda mungkin perlu meningkatkan / menambal paket nfs Anda dan mungkin kernel Anda. Seperti @somequixotic menyebutkan, CentOS Anda sudah tua dan masalah yang Anda alami mungkin telah diselesaikan dalam pembaruan di masa mendatang.
LawrenceC
4

Ada kemungkinan Anda memiliki karakter tersembunyi atau spasi kosong di salah satu nama file. Anda dapat mengecek dengan memberikan -bopsi kepada ls, misalnya:

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\

Perhatikan \penandaan spasi di akhir nama file itu.

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

Sebagai alternatif (meskipun cara di atas harus bekerja), Anda dapat menyalurkan output melalui skrip perl ini untuk mengganti apa pun yang bukan karakter ASCII yang dapat dicetak dengan kode hex-nya. Misalnya, ruang menjadi \x20.

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

Pemakaian:

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