Wie kann ich zwei Dateien mit demselben Namen in einem Verzeichnis haben, wenn ich mit NFS bereitgestellt werde?

8

Ich habe einen C ++ - Anwendungstest, bei dem 10.000 Dateien in einem von NFS bereitgestellten Verzeichnis erstellt werden. Mein Test ist jedoch kürzlich einmal fehlgeschlagen, da eine Datei zweimal mit demselben Namen in diesem Verzeichnis mit allen anderen 10.000 Dateien angezeigt wurde. Dies kann entweder unter Linux Centos v4 oder v5 angezeigt werden, wo das Verzeichnis NFS-gemountet ist, jedoch nicht auf dem Host-Computer, auf dem sich die Festplatte befindet.

Wie ist es überhaupt möglich, zwei Dateien mit demselben Namen im selben Verzeichnis zu haben?

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

Ausführen des in einer der folgenden Antworten vorgeschlagenen Perl-Skripts:

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

gibt:

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

Das Drucken mit den Inode (-i) -Werten zeigt, dass die beiden Kopien denselben Inode-Eintrag haben (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*

Es scheint, dass der Verzeichniseintrag irgendwie beschädigt ist.

Könnte meine Anwendung diese Situation legitimerweise verursacht haben oder ist dies ein Fehler im Betriebssystem? Kann ich in meinem Programm, das die Dateien erstellt, etwas dagegen tun?

Ich denke, es gibt einen Fehler in der NFS-Montagesoftware. Auch 'umount' und dann 'mount' des NFS-Laufwerks, bei dem das Problem auftritt, beheben es nicht. Der wiederholte Eintrag bleibt nach dem erneuten Bereitstellen erhalten.


Update 1: Ich habe dieses Problem jetzt ein zweites Mal, einige Stunden später, festgestellt, und das wirklich Seltsame ist, dass es in genau derselben Datei passiert ist testfile03373, obwohl es diesmal einen anderen Inode hat, 213352984, für die doppelten Dateien. Ich werde auch hinzufügen, dass die Datei auf dem Centos 5-Computer erstellt wird, auf dem die Festplatte gehostet wird. Sie wird also lokal erstellt und lokal korrekt angezeigt, aber auf allen anderen Computern, auf denen NFS sie bereitstellt, wird der doppelte Eintrag angezeigt.


Update 2: Ich habe das Laufwerk auf einem Centos v6-Computer bereitgestellt und /var/log/messagesnach dem Auflisten und Anzeigen des doppelten Eintrags Folgendes gefunden :

[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

Außerdem habe ich festgestellt, dass beim Umbenennen der Datei der doppelte Eintrag verschwindet, beim Umbenennen jedoch wieder doppelt angezeigt wird. Wenn Sie alternativ nur eine neue Datei mit dem Namen berühren testfile03373, wird ein doppelter Eintrag angezeigt. Dies geschieht jedoch nur in der zwei Verzeichnisse, in denen dieser doppelte Eintrag gesehen wurde.

WilliamKF
quelle
AFAIK, es ist unmöglich, dass zwei Dateien mit demselben Namen und derselben Erweiterung in einem Dateisystem im selben Verzeichnis gespeichert werden. Sie könnten einen Ausnahmemechanismus in Ihrem Programm verwenden, um einen Fehler zu verhindern, außer diesem ...
Doktoro Reichard
Welches Dateisystem verwenden Sie?
Doktoro Reichard
Sind sie genau gleich? ZB kein führendes oder nachfolgendes Leerzeichen? keine UTF-16 Zeichen, ...
Hennes
Welche anderen Tests kann ich durchführen, um zu bestätigen, dass sie genau gleich sind?
WilliamKF
Klingt so, als hätten Sie gelernt, wie man einen Endlauf um eine wichtige Überprüfung des Betriebssystems herum durchführt.
Fiasco Labs

Antworten:

8

Ein Freund hat mir geholfen, dies aufzuspüren, und festgestellt, dass dies ein Fehler ist, der in Bugzilla 38572 für den Linux-Kernel hier aufgezeichnet wurde . Der Fehler ist angeblich in Version 3.0.0 des Kernels behoben, aber zumindest in Version 2.6.38 vorhanden.

Das Problem ist, dass der ReadDIR () - RPC-Aufruf des Servers falsche Ergebnisse zurückgibt. Dies geschieht aus folgenden Gründen:

Wenn der Client ein Verzeichnis liest, gibt er eine maximale Puffergröße an und setzt ein Cookie auf Null. Wenn das Verzeichnis zu groß ist, zeigt die Antwort an, dass die Antwort nur teilweise ist, und aktualisiert das Cookie. Anschließend kann der Client den RPC mit dem aktualisierten Cookie erneut ausführen, um den nächsten Datenblock abzurufen. (Bei den Daten handelt es sich um Sätze von Dateihandles und -namen. Im Fall von ReadDirPlus () gibt es auch stat / inode / vnode-Daten.) In der Dokumentation wird nicht angegeben, dass dies ein Fehler bei ReadDirPlus () ist, aber wahrscheinlich vorhanden auch.

Das eigentliche Problem ist, dass die letzte Datei in jedem Block (Name, Handle-Tupel) manchmal als erste Datei im nächsten Block zurückgegeben wird.

Es besteht eine schlechte Interaktion mit den zugrunde liegenden Dateisystemen. Ext4 zeigt dies, XFS nicht.

Aus diesem Grund tritt das Problem in einigen Situationen auf, in anderen jedoch nicht und tritt selten in kleinen Verzeichnissen auf. Wie in der Fragenbeschreibung zu sehen ist, zeigen die Dateien dieselbe Inode-Nummer und die Namen sind identisch (nicht beschädigt). Da der Linux-Kernel die vnode-Operationen für zugrunde liegende Operationen wie open () usw. aufruft, entscheiden die zugrunde liegenden Routinen des Dateisystems, was passiert. In diesem Fall übersetzt der NFS3-Client die vnode-Operation nur in einen RPC, wenn sich die erforderlichen Informationen nicht in seinem Attributcache befinden. Dies führt zu Verwirrung, da der Client glaubt, dass der Server dies nicht kann.

WilliamKF
quelle
Das passiert mir auch mit Kernel 3.18.17-13.el6.x86_64 (CentOS 6). Ich bin mir ziemlich sicher, dass es ein Fehler des zugrunde liegenden NFS-Systems des QNAP TS-212 NAS ist, auf dem das Verzeichnis gemountet ist jemand bestätigen?
Godzillante
6

Die Festplatte ist eine NFS-gemountete Festplatte. Wenn ich zu dem Host-Computer gehe, der das Laufwerk veröffentlicht, wird die Datei nur einmal aufgelistet.

Wahrscheinlich ein Fehler, ein Problem oder eine Rennbedingung mit NFS.

Es ist möglich, zwei Dateien mit demselben Namen zu haben, wenn Sie die Dateisystemstrukturen direkt mit einem Hex-Editor bearbeiten. Ich bin mir jedoch nicht sicher, was passieren würde, wenn Sie versuchen, die Dateien zu löschen oder zu öffnen. Ich bin mir nicht sicher, welche Tools unter Linux für den Zugriff auf eine Datei anhand der Inode-Nummer (die nicht dupliziert werden kann) vorhanden sind, aber das funktioniert möglicherweise.

Doppelte Dateinamen sind etwas, fsckdas wahrscheinlich abfangen und zu beheben versuchen würde.

Stellen Sie jedoch sicher, dass keine der Dateien unterschiedliche Leerzeichen enthält.

LawrenceC
quelle
Ich wollte vorschlagen, dass die Menge des Schreibens auf dem Dateisystem letztendlich etwas kaputt machte und die Existenz von zwei identischen Dateien erlaubte.
Doktoro Reichard
Beim Laufen fsckwurden keine Probleme gefunden. Sowohl der Host- als auch der Client-Computer wurden neu gestartet. Das Problem wird weiterhin angezeigt.
WilliamKF
Ich hätte klarer sein sollen - fsckwird wahrscheinlich nur auf dem lokalen Dateisystem funktionieren, nicht auf einem NFS-gemounteten. Sie müssen wahrscheinlich Ihre NFS-Pakete und möglicherweise Ihren Kernel aktualisieren / patchen. Wie @somequixotic erwähnt, ist Ihr CentOS alt und die Probleme, die Sie haben, wurden möglicherweise in zukünftigen Updates behoben.
LawrenceC
4

Es besteht die Möglichkeit, dass Sie in einem der Dateinamen ein verstecktes, nicht druckbares Zeichen oder Leerzeichen haben. Sie können dies überprüfen, indem Sie die -bOption bereitstellen ls, z.

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\

Beachten Sie das \Leerzeichen am Ende dieses Dateinamens.

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

Alternativ (obwohl das oben genannte funktionieren sollte) können Sie die Ausgabe durch dieses Perl-Skript leiten, um alles, was kein druckbares ASCII-Zeichen ist, durch seinen Hex-Code zu ersetzen. Zum Beispiel wird ein Leerzeichen \x20.

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

Verwendungszweck:

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