Come posso avere due file con lo stesso nome in una directory quando montato con NFS?


8

Ho un test dell'applicazione C ++ che crea 10.000 file in una directory montata NFS, ma il mio test recentemente non è riuscito una volta a causa di un file che appare due volte con lo stesso nome in quella directory con tutti gli altri 10.000 file. Questo può essere visto su Linux Centos v4 o v5 in cui è montata la directory NFS, ma non sul computer host in cui risiede il disco.

Come è possibile anche avere due file con lo stesso nome nella stessa directory?

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

Esecuzione dello script Perl suggerito in una delle risposte seguenti:

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

dà:

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

La stampa con i valori di inode (-i) mostra che le due copie hanno la stessa voce di 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*

Sembrerebbe che la voce della directory sia in qualche modo danneggiata.

La mia applicazione potrebbe aver legittimamente creato questa situazione o si tratta di un bug nel sistema operativo? C'è qualcosa che posso fare per proteggermi dal mio programma che crea i file?

Sto pensando che ci sia una specie di bug nel software di montaggio NFS. Anche 'umount' e quindi 'mount' dell'unità NFS che presenta il problema non lo risolvono, la voce ripetuta rimane dopo il rimontaggio.


Aggiornamento 1: ora ho riscontrato questo problema una seconda volta, poche ore dopo, e la cosa davvero strana è che è successo nello stesso file esatto testfile03373, anche se questa volta ha ottenuto un inode diverso, 213352984, per i file raddoppiati. Aggiungerò anche che il file viene creato sulla macchina Centos 5 in cui è ospitato il disco, quindi viene creato localmente e mostra correttamente localmente, ma tutte le altre macchine che NFS lo montano vedono la voce raddoppiata.


Aggiornamento 2: ho montato l'unità su una macchina Centos v6 e ho trovato quanto segue /var/log/messagesdopo l'elenco e vedendo la doppia voce lì:

[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

Inoltre, ho scoperto che rinominare il file fa scomparire la doppia voce, ma rinominandolo fa sì che riappaia raddoppiato o, in alternativa, semplicemente toccando un nuovo file con il nome testfile03373, appare una doppia voce, ma ciò accade solo nel due directory in cui è stata vista questa doppia voce.


AFAIK, è impossibile che due file con lo stesso nome e l'estensione coesistano nella stessa directory in qualsiasi file system. Potresti usare un meccanismo di eccezione nel tuo programma per prevenire guasti, oltre a questo ...
Doktoro Reichard,

Quale filesystem stai usando?
Doktoro Reichard,

Sono esattamente gli stessi? Ad esempio nessuno spazio bianco iniziale o finale? nessun carattere UTF-16, ...
Hennes,

Quali altri test posso eseguire per confermare che sono esattamente gli stessi?
WilliamKF,

Sembra che tu abbia imparato a fare una corsa finale a un controllo di integrità del sistema operativo vitale.
Fiasco Labs,

Risposte:


8

Un amico mi ha aiutato a rintracciarlo e ha scoperto che si tratta di un bug registrato in Bugzilla 38572 per il kernel Linux qui . Il bug è apparentemente corretto nella versione 3.0.0 del kernel, ma presente almeno nella versione 2.6.38.

Il problema è che la chiamata RPC ReadDIR () del server restituisce risultati errati. Ciò si verifica a causa di quanto segue:

Quando il client legge una directory, specifica una dimensione massima del buffer e azzera un cookie. Se la directory è troppo grande, la risposta indica che la risposta è solo parziale e aggiorna il cookie. Quindi il client può rieseguire l'RPC con il cookie aggiornato per ottenere la successiva porzione di dati. (I dati sono insiemi di handle e nomi di file. Nel caso di ReadDirPlus (), ci sono anche dati stat / inode / vnode.) La documentazione non indica che questo è un bug con ReadDirPlus (), ma probabilmente è lì anche.

Il vero problema è che l'ultimo file in ogni blocco (nome, handle tuple) viene talvolta restituito come primo file nel blocco successivo.

Vi è una cattiva interazione con i filesystem sottostanti. Ext4 lo mostra, XFS no.

Questo è il motivo per cui il problema appare in alcune situazioni ma non in altre e raramente si verifica in piccole directory. Come visto nella descrizione della domanda, i file mostrano lo stesso numero di inode e i nomi sono identici (non danneggiati). Poiché il kernel Linux chiama le operazioni vnode per operazioni sottostanti come open (), ecc., Le routine sottostanti del file system decidono cosa succede. In questo caso, il client NFS3 traduce semplicemente l'operazione vnode in un RPC se le informazioni richieste non sono nella sua cache degli attributi. Ciò crea confusione poiché il client ritiene che il server non possa farlo.


Sta succedendo anche a me, con il kernel 3.18.17-13.el6.x86_64 (CentOS 6). Sono abbastanza sicuro che sia un bug del sistema NFS sottostante del NAS QNAP TS-212 su cui è montata la directory, può qualcuno conferma?
Godzillante,

6

Il disco è un disco montato su NFS. Quando vado sul computer host che pubblica l'unità, il file viene elencato solo una volta.

Probabilmente un bug, un problema o una condizione di competizione con NFS.

È possibile avere due file con lo stesso nome se si modificano direttamente le strutture del filesystem utilizzando un editor esadecimale. Tuttavia, non sono sicuro di cosa succederebbe se provassi a eliminare o aprire i file. Non sono sicuro di quali strumenti esistano su Linux per accedere a un file in base al numero di inode (che non può essere duplicato) ma che potrebbe funzionare.

I nomi di file duplicati fsckpotrebbero essere individuati e tentati di risolvere.

Assicurati che nessuno dei file abbia spazi finali diversi.


Stavo per suggerire che la quantità di scrittura sul filesystem alla fine ha rotto qualcosa e ha permesso l'esistenza di due file identici.
Doktoro Reichard,

La corsa fscknon ha riscontrato problemi. Riavviato entrambi i computer host e client, il problema mostra ancora.
WilliamKF,

Avrei dovuto essere più chiaro - fsckprobabilmente funzionerà solo sul file system locale, non su un NFS montato. Probabilmente dovrai aggiornare / patchare i tuoi pacchetti nfs e possibilmente il tuo kernel. Come menziona @somequixotic, il tuo CentOS è vecchio e i problemi che potresti avere potrebbero essere stati risolti in futuri aggiornamenti.
LawrenceC,

4

È possibile che tu abbia un carattere nascosto non stampabile o uno spazio bianco in uno dei nomi dei file. Puoi verificare fornendo l' -bopzione ls, ad esempio:

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\

Nota il \significato dello spazio alla fine di quel nome file.

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

In alternativa (sebbene quanto sopra dovrebbe funzionare), è possibile reindirizzare l'output attraverso questo script perl per sostituire tutto ciò che non è un carattere ASCII stampabile con il suo codice esadecimale. Ad esempio, uno spazio diventa \x20.

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

Uso:

ls -la | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.