Como posso ter dois arquivos com o mesmo nome em um diretório quando montado com o NFS?

8

Eu tenho um teste de aplicativo C ++ que cria 10.000 arquivos em um diretório NFS montado, mas meu teste falhou recentemente uma vez devido a um arquivo que aparece 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 é montado pelo NFS, mas não na máquina onde 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*

Imprimir 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.

Poderia meu aplicativo ter criado legitimamente essa situação ou isso é um bug no sistema operacional? Existe alguma coisa 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 do NFS. Também 'umount' e, em seguida, 'mount' da unidade NFS que tem o problema não a resolve, a entrada repetida permanece após a remontação.

Atualização 1: Eu agora acertei essa edição uma segunda vez, algumas horas depois, e a coisa realmente estranha é que aconteceu exatamente no mesmo arquivo, testfile03373 , embora tenha sido um inode diferente desta vez, 213352984, para os arquivos duplicados. Eu também vou acrescentar que o arquivo está sendo criado na máquina Centos 5 onde o disco está sendo hospedado, então ele está sendo criado localmente, e mostrando correto localmente, mas todas as outras máquinas que o NFS monta estão vendo a entrada duplicada. / p>

Atualização 2: montei a unidade em uma máquina Centos v6 e encontrei o seguinte em /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 faz com que reapareça duplicado ou, alternativamente, apenas tocar em um novo arquivo com o nome testfile03373 , faz com que uma entrada dupla apareça mas isso só acontece nos dois diretórios onde esta dupla entrada foi vista.

    
por WilliamKF 03.09.2013 / 16:12

3 respostas

8

Um amigo me ajudou a rastrear isso e descobriu que esse é um bug registrado no Bugzilla 38572 para o kernel Linux aqui . O bug é 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 RD 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 executar novamente o RPC com o cookie atualizado para obter o próximo bloco de dados. (Os dados são conjuntos de identificadores e nomes de arquivos. No caso de ReadDirPlus (), também há dados stat / inode / vnode.) A documentação não indica que este é um bug com ReadDirPlus (), mas provavelmente está lá também.

O problema real é que o último arquivo em cada bloco (nome, tupla de tratamento) é às vezes retornado como o primeiro arquivo no próximo bloco.

Há uma interação ruim com os sistemas de arquivos subjacentes. 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 questão, 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 leva a confusão, pois o cliente acredita que o servidor não pode fazer isso.

    
por 05.09.2013 / 01:51
6

The disk is an NFS mounted disk. When I go to the host computer that publishes the drive, the file is only listed once.

Provavelmente uma condição de bug, problema ou corrida com o 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 tenho certeza de quais ferramentas existem no Linux para acessar um arquivo por número de inode (que não pode ser duplicado), mas isso pode funcionar.

Os nomes dos arquivos duplicados são algo que fsck provavelmente detectaria e tentaria corrigir.

Certifique-se de que nenhum dos arquivos tenha espaços à direita diferentes.

    
por 03.09.2013 / 18:10
4

Existe a possibilidade de você ter um caractere oculto não imprimível ou um espaço em branco em um dos nomes de arquivo. Você pode verificar isso fornecendo a opção -b para ls , por exemplo:

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\

Observe o \ significando o espaço no final desse nome de arquivo.

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

Como alternativa (embora o acima deve 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 com seu código hexadecimal. Por exemplo, um espaço se torna \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");}'
    
por 03.09.2013 / 18:21