rebanho (2) versus fcntl (2) sobre um NFS

19

A documentação do Perl 5.x afirma que sua implementação do flock (..) usará uma das seguintes chamadas nativas, iniciando em 1 e trabalhando em direção a 3 se não estiver disponível:

  1. bandido (2)
  2. fcntl (2)
  3. lockf (3)

Isso é bom. No entanto, você deve ter notado a isenção de responsabilidade de que o flock (2) não deve ser usado em um NFS. O documento sugere o uso de um sinalizador -Ud_flock para forçar o Perl a usar o flock (2). A página de manual do flock (2) (no Redhat) declara um aviso semelhante sobre os problemas do NFS.

Minha pergunta é, por que!?!? Parece que não consigo encontrar um artigo ou explicação detalhada de por que o rebanho (2) é inseguro em um NFS.

Eu escrevi vários scripts de teste em C e Perl, tanto no Redhat (onde o rebanho (2) está sendo usado) quanto no Solaris (onde o fcntl (2) está sendo usado). Corri strace / truss para garantir que o Perl estivesse usando o flock (2) e o fcntl (2), respectivamente. Não foi possível replicar nenhum problema em que um bloqueio não estivesse sendo respeitado! O que da??

Jmoney38
fonte

Respostas:

3

Recentemente, Lennart Poettering pesquisou o comportamento de bloqueio do sistema de arquivos linux, o que não mostra uma imagem particularmente otimista do bloqueio pelo NFS (especialmente o acompanhamento ao qual ele vincula a parte inferior do post).

http://0pointer.de/blog/projects/locking.html

Ivatar
fonte
11
Esse é o tipo exato de informação que eu estava procurando. Obrigado! Após várias semanas de investigação, é uma resolução muito semelhante à qual cheguei, mas é ótimo ler um artigo que confirma minhas suspeitas (e sugere outras). O link dos comentários dessa página também foi uma boa referência e um bom artigo sobre o POSIX e sua história): samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38
15

Tenho certeza de que você está analisando preocupações herdadas. Lembre-se de que o manual do Perl5 foi lançado em 1994 e que era apenas uma edição do manual do Perl4 de 1991. Naquela época, provavelmente poderia ser dito sobre o frequentemente chamado Nightmare File System que "não é o quão bem o urso dança. surpreende, mas que dança ".

O NFS2 na época de 1991 estava lentamente saindo do Sol para outras plataformas e era relativamente bruto. O modelo de segurança era praticamente inexistente (a raiz em uma máquina cliente podia ler todo o conteúdo de uma montagem NFS) e o bloqueio - via nfs.lockd - era o lado experimental. Você seria tolo em esperar que a semântica de rebanho funcione corretamente, se houver entre duas implementações supostamente interoperáveis ​​diferentes. O Coax era o Ethernet PHY dominante na época em que muitos usuários da rede nunca tiveram o desagrado de usar (o que você quer dizer com esqueceu de colocar o resistor de terminação de 50𝛀?) Se isso lhe dá uma melhor noção do estado das intranets.

Larry Wall e sua equipe tinham todos os motivos para fazer suposições pessimistas sobre a correção dos bloqueios do NFS na época, e esse é o tipo de programação defensiva que futuros jóqueis de código detestam remover porque é muito difícil provar a ausência de um defeito. removendo código antigo que é reintroduzido na interoperabilidade com um sistema legado do qual você nunca ouviu falar.

Desde então, o NFS melhorou consideravelmente e o lockd migrou com o tempo para um recurso do kernel Linux 2.6. Para uma coleção de sistemas 2003 ou superior, o bloqueio de arquivos NFS provavelmente pode ser confiável, especialmente se testado dentro do seu aplicativo nas várias plataformas em que ele está sendo executado.

Todos os itens acima foram extraídos da memória e provavelmente poderiam ser substanciados por meio de pesquisa (por exemplo, http://nfs.sourceforge.net/ ), mas a prova - como se costuma dizer - está no bloqueio, e se você não o testou , presume-se quebrado.

msw
fonte
Essa é uma ótima análise. De fato, cheguei à mesma conclusão até agora. Li a página do nfors sourceforge novamente depois que você postou o link e finalmente encontrei o que estava procurando! Aqui está uma análise aprofundada diretamente da boca do cavalo!
precisa saber é o seguinte
2
opa, eu apertei enter ... vá para nfs.sourceforge.net , seção D10 na parte inferior discute esse problema em detalhes.
precisa saber é o seguinte
3

Outro, direto das perguntas frequentes sobre Linux-NFS: nfs.sf.net

Estou tentando usar bloqueios flock () / BSD para bloquear arquivos usados ​​em vários clientes, mas os arquivos ficam corrompidos. Por quê? A. Os bloqueios flock () / BSD atuam apenas localmente nos clientes Linux NFS anteriores à 2.6.12. Use bloqueios fcntl () / POSIX para garantir que os bloqueios de arquivo sejam visíveis para outros clientes.

Aqui estão algumas maneiras de serializar o acesso a um arquivo NFS.

Use a API de bloqueio fcntl () / POSIX. Esse tipo de bloqueio fornece bloqueio de intervalo de bytes em vários clientes via protocolo NLM ou NFSv4. Use um arquivo de bloqueio separado e crie links físicos para ele. Veja a descrição na seção O_EXCL da página do manual creat (2). Vale ressaltar que até o início do kernels 2.6, o O_EXCL cria não era atômico nos clientes Linux NFS. Não use O_EXCL cria e espera comportamento atômico entre vários clientes NFS, a menos que você esteja executando um kernel mais recente que o 2.6.5.

É um problema conhecido que o Perl usa o bloqueio flock () / BSD por padrão. Isso pode interromper programas portados de outros sistemas operacionais, como o Solaris, que esperam que os bloqueios flock / BSD funcionem como bloqueios POSIX.

No Linux, o uso do bloqueio de arquivos em vez de um link físico tem o benefício adicional de verificar o cache do cliente com o servidor. Quando um bloqueio de arquivo é adquirido, o cliente limpa o cache da página desse arquivo para que quaisquer leituras subsequentes obtenham novos dados do servidor. Quando um bloqueio de arquivo é liberado, qualquer alteração no arquivo desse cliente é liberada novamente no servidor antes que o bloqueio seja liberado, para que outros clientes que aguardam o bloqueio do arquivo possam ver as alterações.

O cliente NFS na 2.6.12 fornece suporte para bloqueios flock () / BSD em arquivos NFS, emulando os bloqueios no estilo BSD em termos de bloqueios de intervalo de bytes POSIX. Outros clientes NFS que usam o mesmo mecanismo de emulação ou que usam bloqueios fcntl () / POSIX, verão os mesmos bloqueios que o cliente NFS Linux vê.

Nos sistemas de arquivos Linux locais, os bloqueios POSIX e BSD são invisíveis um para o outro. Portanto, devido a essa emulação, os aplicativos em execução em um servidor NFS Linux ainda verão os arquivos bloqueados pelos clientes NFS como bloqueados com um bloqueio fcntl () / POSIX, independentemente de o aplicativo no cliente estar usando um estilo BSD ou um POSIX- bloqueio de estilo. Se o aplicativo do servidor usar bloqueios flock () BSD, ele não verá os bloqueios usados ​​pelos clientes NFS.

Nikhil Mulley
fonte
Então, dois clientes NFS executando o kernel 3.13. * Vêem o flock () s um do outro?
Reinierpost
Se estou entendendo corretamente, a resposta é não. A menos que eu tenha perdido alguma coisa, flocknão tenha, não tenha e não trava nas montagens NFS.
Daniel Farrell
Sim, pelo menos no NFS4.
Rjh 21/0318
3

Isso está desatualizado agora. O NFS4 suporta o bloqueio dentro do protocolo (nenhum daemon lockd ou mecanismo de retorno de chamada RPC é necessário) e o flock()método do Perl funciona bem - estamos usando-o na produção.

Versões muito antigas do kernel implementadas flock(o syscall) como não operacional no NFS, e outras coisas como bloqueio de intervalo de bytes não eram adequadamente suportadas. É daí que a histeria vem.

rjh
fonte
Muito obrigado pela dica. A montagem com o NFS4 resolveu meu problema. Seguido access.redhat.com/documentation/en-us/red_hat_enterprise_linux/... para obter direito de configuração fstab.
maraspin 14/10