8 votes

Comment puis-je avoir deux fichiers avec le même nom dans un répertoire lorsqu'il est monté avec NFS ?

J'ai un test d'application C++ qui crée 10 000 fichiers dans un répertoire monté par NFS, mais mon test a récemment échoué une fois en raison d'un fichier apparaissant deux fois avec le même nom dans ce répertoire avec tous les autres 10 000 fichiers. Ce problème peut être observé sur Linux Centos v4 ou v5 où le répertoire est monté sur NFS, mais pas sur la machine hôte où réside le disque.

Comment est-il possible d'avoir deux fichiers portant le même nom dans le même répertoire ?

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

Exécuter le script Perl suggéré dans une des réponses ci-dessous :

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

donne :

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

L'impression avec les valeurs inode (-i) montre que les deux copies ont la même entrée inode (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*

Il semblerait que l'entrée du répertoire soit corrompue d'une manière ou d'une autre.

Mon application aurait-elle pu légitimement créer cette situation ou s'agit-il d'un bug du système d'exploitation ? Y a-t-il quelque chose que je puisse faire pour me protéger contre cela dans mon programme qui crée les fichiers ?

Je pense qu'il y a une sorte de bogue dans le logiciel de montage NFS. De même, le fait d'effectuer un " umount " puis un " mount " sur le lecteur NFS qui présente le problème ne le résout pas, l'entrée répétée subsiste après le remontage.


Mise à jour 1 : J'ai rencontré ce problème une deuxième fois, quelques heures plus tard, et ce qui est vraiment étrange, c'est que cela s'est produit sur le même fichier, testfile03373 bien qu'il ait obtenu un inode différent cette fois, 213352984, pour les fichiers doublés. J'ajouterai également que le fichier est créé sur la machine Centos 5 où le disque est hébergé, il est donc créé localement et s'affiche correctement localement, mais toutes les autres machines qui le montent par NFS voient l'entrée doublée.


Mise à jour 2 : J'ai monté le lecteur sur une machine Centos v6 et j'ai trouvé ce qui suit dans le fichier /var/log/messages après l'avoir listé et avoir vu la double entrée à cet endroit :

[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

De plus, j'ai découvert que renommer le fichier fait disparaître la double entrée, mais le renommer à nouveau la fait réapparaître en double, ou alternativement, il suffit de toucher un nouveau fichier avec le nom testfile03373 provoque l'apparition d'une double entrée, mais cela ne se produit que dans les deux répertoires où cette double entrée a été vue.

8voto

kubanczyk Points 13302

Un ami m'a aidé à retrouver la trace de ce problème et a découvert qu'il s'agissait d'un bogue tel qu'enregistré dans Bugzilla 38572 pour le noyau Linux ici . Le bogue est censé être corrigé dans la version 3.0.0 du noyau, mais il est présent au moins dans la version 2.6.38.

Le problème est que l'appel RPC ReadDIR() du serveur renvoie des résultats incorrects. Cela se produit pour les raisons suivantes :

Lorsque le client lit un répertoire, il spécifie une taille maximale pour le tampon et met à zéro un cookie. Si le répertoire est trop grand, la réponse indique que la réponse n'est que partielle et met à jour le cookie. Le client peut alors réexécuter le RPC avec le cookie mis à jour pour obtenir le prochain morceau de données. (Les données sont des ensembles de poignées et de noms de fichiers. Dans le cas de ReadDirPlus(), il y a également des données stat/inode/vnode). La documentation n'indique pas que c'est un bogue avec ReadDirPlus(), mais c'est probablement le cas ici aussi.

Le problème réel est que le dernier fichier dans chaque chunk (nom, tuple handle) est parfois retourné comme premier fichier dans le prochain chunk.

Il y a une mauvaise interaction avec les systèmes de fichiers sous-jacents. Ext4 présente cela, XFS non.

C'est pourquoi le problème apparaît dans certaines situations mais pas dans d'autres et se produit rarement dans les petits répertoires. Comme indiqué dans la description de la question, les fichiers présentent le même numéro d'inode et les noms sont identiques (non corrompus). Comme le noyau Linux appelle les opérations vnode pour les opérations sous-jacentes telles que open(), etc., les routines sous-jacentes du système de fichiers décident de ce qui se passe. Dans ce cas, le client NFS3 traduit simplement l'opération vnode en un RPC si les informations requises ne sont pas dans son cache d'attributs. Cela entraîne une confusion car le client pense que le serveur ne peut pas faire cela.

6voto

LawrenceC Points 70381

Le disque est un disque monté NFS. Lorsque je vais sur l'ordinateur hôte qui publie le disque, le fichier n'est répertorié qu'une seule fois.

Probablement un bogue, un problème ou une condition de course avec NFS.

Il est possible d'avoir deux fichiers portant le même nom si vous modifiez directement les structures du système de fichiers à l'aide d'un éditeur hexagonal. Cependant, je ne suis pas sûr de ce qui se passerait si vous essayiez de supprimer ou d'ouvrir les fichiers. Je ne suis pas sûr des outils qui existent sous Linux pour accéder à un fichier par le numéro d'inode (qui ne peut pas être dupliqué) mais cela pourrait fonctionner.

Les noms de fichiers en double sont quelque chose fsck serait susceptible d'attraper et d'essayer de réparer.

Assurez-vous qu'aucun des fichiers ne comporte d'espaces de fin de ligne différents.

4voto

Bob Points 58080

Il est possible que vous ayez un caractère non imprimable caché ou un espace dans l'un des noms de fichiers. Vous pouvez le vérifier en fournissant la valeur -b option pour ls par exemple :

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\

Notez le \ signifiant l'espace à la fin de ce nom de fichier.

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

Comme alternative (bien que la méthode ci-dessus devrait fonctionner), vous pouvez faire passer la sortie par ce script perl script pour remplacer tout ce qui n'est pas un caractère ASCII imprimable par son code hexadécimal. Par exemple, un espace devient \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");}'

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X