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


8

J'ai un test d'application C ++ qui crée 10 000 fichiers dans un répertoire monté 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 10 000 autres fichiers. Cela peut être vu sur Linux Centos v4 ou v5 où le répertoire est monté NFS, mais pas sur la machine hôte où réside le disque.

Comment est-il même possible d'avoir deux fichiers du 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 l'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 d'inode (-i) montre que les deux copies ont la même entrée d'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 de répertoire soit en quelque sorte corrompue.

Mon application aurait-elle pu légitimement créer cette situation ou s'agit-il d'un bug dans le 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. Également 'umount' puis 'mount' du lecteur NFS qui a le problème ne le résout pas, l'entrée répétée reste après le remontage.


Mise à jour 1: j'ai maintenant 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 cette fois un inode différent, 213352984, pour les fichiers doublés. J'ajouterai également que le fichier est créé sur la machine Centos 5 sur laquelle le disque est hébergé, donc il est créé localement et affiché correctement localement, mais toutes les autres machines que NFS le monte voient l'entrée doublée.


Mise à jour 2: j'ai monté le lecteur sur une machine Centos v6 et j'ai trouvé les éléments suivants /var/log/messagesaprès avoir répertorié et vu la double entrée:

[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 trouvé que renommer le fichier fait disparaître la double entrée, mais le renommer en arrière la fait réapparaître doublé, ou alternativement, en touchant simplement un nouveau fichier avec le nom testfile03373, une double entrée apparaît, mais cela ne se produit que dans le deux répertoires où cette double entrée a été vue.


AFAIK, il est impossible que deux fichiers portant le même nom et l'extension coexistent dans le même répertoire dans n'importe quel système de fichiers. Vous pouvez utiliser un mécanisme d'exception dans votre programme pour éviter l'échec, autre que cela ...
Doktoro Reichard

Quel système de fichiers utilisez-vous?
Doktoro Reichard

Sont-ils exactement les mêmes? Par exemple, aucun espace de début ou de fin? pas de caractères UTF-16, ...
Hennes

Quels autres tests puis-je effectuer pour confirmer qu'ils sont exactement les mêmes?
WilliamKF

On dirait que vous avez appris à faire un tour final autour d'une vérification de la santé mentale du système d'exploitation.
Fiasco Labs du

Réponses:


8

Un ami m'a aidé à retrouver cela et a trouvé que c'était un bogue enregistré dans Bugzilla 38572 pour le noyau Linux ici . Le bogue est censé être corrigé dans la version 3.0.0 du noyau, mais 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 en raison des éléments suivants:

Lorsque le client lit un répertoire, il spécifie une taille maximale de tampon et met à zéro un cookie. Si le répertoire est trop volumineux, la réponse indique que la réponse n'est que partielle et met à jour le cookie. Ensuite, le client peut réexécuter le RPC avec le cookie mis à jour pour obtenir le prochain bloc de données. (Les données sont des ensembles de descripteurs et de noms de fichiers. Dans le cas de ReadDirPlus (), il existe également des données stat / inode / vnode.) La documentation n'indique pas qu'il s'agit d'un bogue avec ReadDirPlus (), mais il y en a probablement un ainsi que.

Le problème réel est que le dernier fichier de chaque bloc (nom, tuple de poignée) est parfois renvoyé en tant que premier fichier du bloc suivant.

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 sur de petits répertoires. Comme indiqué dans la description de la question, les fichiers affichent 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 RPC si les informations requises ne se trouvent pas dans son cache d'attributs. Cela crée de la confusion car le client pense que le serveur ne peut pas le faire.


Cela m'arrive aussi, avec le noyau 3.18.17-13.el6.x86_64 (CentOS 6) .Je suis sûr que c'est un bogue du système NFS sous-jacent du NAS QNAP TS-212 sur lequel le répertoire est monté, peut quelqu'un confirme?
godzillante

6

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

Probablement un bug, un problème ou une condition de concurrence avec NFS.

Il est possible d'avoir deux fichiers du même nom si vous éditez directement les structures du système de fichiers à l'aide d'un éditeur hexadécimal. Cependant, je ne sais pas ce qui se passerait si vous essayez de supprimer ou d'ouvrir les fichiers. Je ne sais pas quels outils existent sous Linux pour accéder à un fichier par numéro d'inode (qui ne peut pas être dupliqué) mais cela peut fonctionner.

Les noms de fichiers en double sont fscksusceptibles d'attraper et d'essayer de corriger.

Assurez-vous cependant qu'aucun des fichiers n'a des espaces de fin différents.


J'allais suggérer que la quantité d'écriture sur le système de fichiers a finalement cassé quelque chose et a permis l'existence de deux fichiers identiques.
Doktoro Reichard

L'exécution fsckn'a trouvé aucun problème. Redémarrage des machines hôtes et clientes, le problème reste affiché.
WilliamKF

J'aurais dû être plus clair - fsckne fonctionnera probablement que sur le système de fichiers local, pas sur un système monté par NFS. Vous aurez probablement besoin de mettre à jour / patcher vos paquets nfs et éventuellement votre noyau. Comme le mentionne @somequixotic, votre CentOS est ancien et les problèmes que vous rencontrez peuvent avoir été résolus dans les futures mises à jour.
LawrenceC

4

Il est possible que vous ayez un caractère non imprimable caché ou un espace dans l'un des noms de fichiers. Vous pouvez vérifier avec en fournissant l' -boption 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 ce qui précède devrait fonctionner), vous pouvez diriger la sortie via ce script perl 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");
}

Usage:

ls -la | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.