Jak mogę mieć dwa pliki o tej samej nazwie w katalogu po podłączeniu do NFS?

8

Mam test aplikacji C ++, który tworzy 10 000 plików w katalogu zamontowanym w systemie plików NFS, ale mój test niedawno się nie udał, ponieważ jeden plik pojawił się dwa razy o tej samej nazwie w tym katalogu z wszystkimi pozostałymi 10 000 plików. Można to zobaczyć na Linux Centos v4 lub v5, gdzie katalog jest podłączony do NFS, ale nie na komputerze hosta, na którym znajduje się dysk.

Jak można w ogóle mieć dwa pliki o tej samej nazwie w tym samym katalogu?

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

Uruchomienie skryptu Perl sugerowane w jednej z poniższych odpowiedzi:

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

daje:

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

Drukowanie z wartościami i-węzła (-i) pokazuje, że dwie kopie mają ten sam wpis i-węzła (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*

Wygląda na to, że wpis w katalogu jest jakoś uszkodzony.

Czy moja aplikacja mogła zgodnie z prawem stworzyć tę sytuację, czy jest to błąd w systemie operacyjnym? Czy mogę coś zrobić, aby zabezpieczyć się przed tym w moim programie, który tworzy pliki?

Myślę, że w oprogramowaniu do montażu NFS jest jakiś błąd. Również „umount”, a następnie „mount” dysku NFS, który ma problem, nie rozwiązuje go, powtarzający się wpis pozostaje po ponownym zamontowaniu.


Aktualizacja 1: Znalazłem ten problem po raz drugi, kilka godzin później, i naprawdę dziwne jest to, że wydarzyło się to dokładnie w tym samym pliku testfile03373, chociaż tym razem otrzymało inną i-węzeł, 213352984, dla plików podwójnych. Dodam też, że plik jest tworzony na komputerze Centos 5, na którym dysk jest hostowany, więc jest tworzony lokalnie i pokazuje się poprawnie lokalnie, ale wszystkie inne maszyny, które go zamontowały, widzą podwójny wpis.


Aktualizacja 2: Zamontowałem dysk na maszynie Centos v6 i znalazłem następujące informacje /var/log/messagespo wyświetleniu listy i zobaczeniu tam podwójnego wpisu:

[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

Ponadto odkryłem, że zmiana nazwy pliku powoduje zniknięcie podwójnego wpisu, ale zmiana nazwy powoduje jego ponowne pojawienie się podwójnie lub, alternatywnie, po prostu dotknięcie nowego pliku o nazwie testfile03373powoduje wyświetlenie podwójnego wpisu, ale zdarza się to tylko w dwa katalogi, w których widać ten podwójny wpis.

WilliamKF
źródło
AFAIK, niemożliwe jest współistnienie dwóch plików o tej samej nazwie i rozszerzeniu w tym samym katalogu w dowolnym systemie plików. Możesz użyć mechanizmu wyjątku w swoim programie, aby zapobiec awarii, innym niż to ...
Doktoro Reichard
Z jakiego systemu plików korzystasz?
Doktoro Reichard
Czy są dokładnie takie same? Np. Brak początkowych lub końcowych białych znaków? brak znaków UTF-16, ...
Hennes
Jakie inne testy mogę wykonać, aby potwierdzić, że są dokładnie takie same?
WilliamKF,
Wygląda na to, że nauczyłeś się, jak przeprowadzić bieg końcowy wokół ważnej kontroli poprawności systemu operacyjnego.
Fiasco Labs

Odpowiedzi:

8

Znajomy pomógł mi to wyśledzić i stwierdził, że jest to błąd zarejestrowany w Bugzilli 38572 dla jądra Linux tutaj . Błąd został rzekomo naprawiony w wersji 3.0.0 jądra, ale występuje przynajmniej w wersji 2.6.38.

Problem polega na tym, że wywołanie RPC ReadDIR () serwera zwraca nieprawidłowe wyniki. Dzieje się tak z powodu:

Gdy klient czyta katalog, określa maksymalny rozmiar bufora i zeruje ciasteczko. Jeśli katalog jest zbyt duży, odpowiedź wskazuje, że odpowiedź jest tylko częściowa i aktualizuje plik cookie. Następnie klient może ponownie wykonać RPC ze zaktualizowanym plikiem cookie, aby uzyskać kolejną porcję danych. (Dane to zestawy uchwytów i nazw plików. W przypadku ReadDirPlus () istnieją również dane stat / inode / vnode). Dokumentacja nie wskazuje, że jest to błąd w ReadDirPlus (), ale prawdopodobnie tam jest także.

Rzeczywistym problemem jest to, że ostatni plik w każdej porcji (nazwa, krotka uchwytu) jest czasami zwracany jako pierwszy plik w kolejnej porcji.

Zła interakcja z bazowymi systemami plików. Ext4 wykazuje to, XFS nie.

Dlatego problem pojawia się w niektórych sytuacjach, ale nie w innych, i rzadko występuje w małych katalogach. Jak widać w opisie pytania, pliki mają ten sam numer i-węzła, a nazwy są identyczne (nie są uszkodzone). Ponieważ jądro Linux wywołuje operacje vnode dla podstawowych operacji, takich jak open () itp., Podstawowe procedury systemu plików decydują o tym, co się stanie. W takim przypadku klient NFS3 po prostu tłumaczy operację vnode na RPC, jeśli wymaganych informacji nie ma w pamięci podręcznej atrybutów. Prowadzi to do zamieszania, ponieważ klient uważa, że ​​serwer nie może tego zrobić.

WilliamKF
źródło
Zdarza mi się to także z jądrem 3.18.17-13.el6.x86_64 (CentOS 6). Jestem pewien, że to błąd podstawowego systemu NFS serwera QNAP TS-212 NAS, na którym jest zamontowany katalog, może ktoś potwierdzi?
godzillante
6

Dysk jest dyskiem zamontowanym w systemie plików NFS. Kiedy przechodzę do komputera hosta, który publikuje dysk, plik jest wymieniony tylko raz.

Prawdopodobnie błąd, problem lub stan wyścigu w NFS.

Możliwe jest posiadanie dwóch plików o tej samej nazwie, jeśli bezpośrednio edytujesz struktury systemu plików za pomocą edytora szesnastkowego. Nie jestem jednak pewien, co by się stało, gdybyś spróbował usunąć lub otworzyć pliki. Nie jestem pewien, jakie narzędzia istnieją w systemie Linux, aby uzyskać dostęp do pliku według numeru i-węzła (którego nie można powielić), ale to może działać.

Zduplikowane nazwy plików to coś, fsckco prawdopodobnie złapie i spróbuje naprawić.

Upewnij się jednak, że żaden z plików nie ma różnych końcowych spacji.

LawrenceC
źródło
Chciałem zasugerować, że ilość zapisu w systemie plików ostatecznie coś zepsuła i pozwoliła na istnienie dwóch identycznych plików.
Doktoro Reichard
Podczas pracy fscknie znaleziono problemów. Po ponownym uruchomieniu komputera hosta i klienta problem nadal występuje.
WilliamKF,
Powinienem był wyrazić się lepiej - fsckprawdopodobnie będzie działał tylko na lokalnym systemie plików, a nie na systemie plików NFS. Prawdopodobnie będziesz musiał zaktualizować / załatać pakiety nfs i ewentualnie jądro. Jak wspomina @somequixotic, twój CentOS jest stary, a problemy, które masz, mogły zostać rozwiązane w przyszłych aktualizacjach.
LawrenceC
4

Istnieje szansa, że ​​w jednym z nazw plików znajduje się ukryty znak niedrukowalny lub spacja. Możesz to sprawdzić, podając -bopcję lsnp .:

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\

Zwróć uwagę na \spację na końcu tej nazwy pliku.

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

Alternatywnie (chociaż powyższe powinno działać), możesz przesłać dane wyjściowe przez ten skrypt perla, aby zastąpić wszystko, co nie jest drukowalnym znakiem ASCII, jego kodem szesnastkowym. Na przykład staje się spacja \x20.

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

Stosowanie:

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