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/messages
po 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 testfile03373
powoduje wyświetlenie podwójnego wpisu, ale zdarza się to tylko w dwa katalogi, w których widać ten podwójny wpis.
źródło
Odpowiedzi:
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ć.
źródło
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ś,
fsck
co prawdopodobnie złapie i spróbuje naprawić.Upewnij się jednak, że żaden z plików nie ma różnych końcowych spacji.
źródło
fsck
nie znaleziono problemów. Po ponownym uruchomieniu komputera hosta i klienta problem nadal występuje.fsck
prawdopodobnie 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.Istnieje szansa, że w jednym z nazw plików znajduje się ukryty znak niedrukowalny lub spacja. Możesz to sprawdzić, podając
-b
opcjęls
np .:Zwróć uwagę na
\
spację na końcu tej nazwy pliku.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
.Stosowanie:
źródło