Eu tenho um teste de aplicativo C ++ que cria 10.000 arquivos em um diretório montado pelo NFS, mas meu teste falhou recentemente uma vez devido a um arquivo aparecer duas vezes com o mesmo nome nesse diretório com todos os outros 10.000 arquivos. Isso pode ser visto no Linux Centos v4 ou v5, onde o diretório está montado pelo NFS, mas não na máquina host em que o disco reside.
Como é possível ter dois arquivos com o mesmo nome no mesmo diretório?
[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*
Executando o script Perl sugerido em uma das respostas abaixo:
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*
A impressão com os valores de inode (-i) mostra que as duas cópias têm a mesma entrada de 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*
Parece que a entrada do diretório está corrompida de alguma forma.
Meu aplicativo poderia ter criado legitimamente essa situação ou isso é um bug no sistema operacional? Existe algo que eu possa fazer para me proteger contra isso no meu programa que cria os arquivos?
Estou pensando que há algum tipo de bug no software de montagem NFS. Além disso, 'umount' e, em seguida, 'mount' da unidade NFS com o problema não resolvem, a entrada repetida permanece após a remontagem.
Atualização 1: Eu já peguei esse problema uma segunda vez, algumas horas depois, e o mais estranho é que aconteceu exatamente no mesmo arquivo testfile03373
, embora desta vez tenha um inode diferente, 213352984, para os arquivos duplicados. Também acrescentarei que o arquivo está sendo criado na máquina Centos 5 em que o disco está sendo hospedado e, portanto, está sendo criado localmente e mostrando a correção localmente, mas todas as outras máquinas montadas pelo NFS estão vendo a entrada duplicada.
Atualização 2: montei a unidade em uma máquina Centos v6 e encontrei o seguinte /var/log/messages
após listar e ver a entrada dupla 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
Além disso, descobri que renomear o arquivo faz com que a entrada dupla desapareça, mas renomeá-lo novamente faz com que reapareça duas vezes ou, alternativamente, apenas tocar em um novo arquivo com o nome testfile03373
faz com que uma entrada dupla apareça, mas isso só acontece no diretório dois diretórios em que essa entrada dupla foi vista.
fonte
Respostas:
Um amigo me ajudou a rastrear isso e descobriu que este é um bug, conforme registrado no Bugzilla 38572 para o kernel Linux aqui . O bug está supostamente corrigido na versão 3.0.0 do kernel, mas presente pelo menos na versão 2.6.38.
O problema é que a chamada RPC ReadDIR () do servidor retorna resultados incorretos. Isso ocorre devido ao seguinte:
Quando o cliente lê um diretório, ele especifica um tamanho máximo de buffer e zera um cookie. Se o diretório for muito grande, a resposta indica que a resposta é apenas parcial e atualiza o cookie. Em seguida, o cliente pode reexecutar o RPC com o cookie atualizado para obter o próximo pedaço de dados. (Os dados são conjuntos de identificadores e nomes de arquivos. No caso de ReadDirPlus (), também existem dados stat / inode / vnode.) A documentação não indica que esse é um erro do ReadDirPlus (), mas provavelmente existe também.
O problema real é que o último arquivo em cada pedaço (nome, manipula tupla) às vezes é retornado como o primeiro arquivo no próximo pedaço.
Há uma interação ruim com os sistemas de arquivos subjacentes. O Ext4 exibe isso, o XFS não.
É por isso que o problema aparece em algumas situações, mas não em outras, e raramente ocorre em diretórios pequenos. Como visto na descrição da pergunta, os arquivos mostram o mesmo número de inode e os nomes são idênticos (não corrompidos). Como o kernel do Linux chama as operações vnode para operações subjacentes, como open () etc., as rotinas subjacentes do sistema de arquivos decidem o que acontece. Nesse caso, o cliente NFS3 apenas converte a operação vnode em um RPC se as informações necessárias não estiverem em seu cache de atributos. Isso gera confusão, pois o cliente acredita que o servidor não pode fazer isso.
fonte
Provavelmente um bug, problema ou condição de corrida no NFS.
É possível ter dois arquivos com o mesmo nome se você editar diretamente as estruturas do sistema de arquivos usando um editor hexadecimal. No entanto, não tenho certeza do que aconteceria se você tentar excluir ou abrir os arquivos. Não sei ao certo quais ferramentas existem no Linux para acessar um arquivo pelo número do inode (que não pode ser duplicado), mas isso pode funcionar.
Nomes de arquivos duplicados são algo
fsck
que provavelmente capturaria e tentaria corrigir.Certifique-se de que nenhum dos arquivos tenha espaços à direita diferentes.
fonte
fsck
não encontrou problemas. Reiniciou as máquinas host e cliente, o problema ainda mostra.fsck
provavelmente só funcionará no sistema de arquivos local, não em um NFS montado. Você provavelmente precisará atualizar / corrigir seus pacotes nfs e possivelmente seu kernel. Como o @somequixotic menciona, seu CentOS é antigo e os problemas que você está tendo podem ter sido resolvidos em futuras atualizações.Há uma chance de você ter um caractere não imprimível ou espaço em branco oculto em um dos nomes de arquivo. Você pode verificar com a
-b
opção dels
, por exemplo:Observe o
\
significado do espaço no final desse nome de arquivo.Como alternativa (embora o acima mencionado deva funcionar), você pode canalizar a saída através deste script perl para substituir qualquer coisa que não seja um caractere ASCII imprimível pelo seu código hexadecimal. Por exemplo, um espaço se torna
\x20
.Uso:
fonte