O inotify dispara uma notificação quando uma gravação é iniciada ou quando é concluída?

O inotify dispara uma notificação quando uma gravação é iniciada ou quando é concluída?

Imagine dois processos, um leitor e um gravador, comunicando-se através de um arquivo normal em um ext3 fs. O Reader tem um IN_MODIFYrelógio inotify no arquivo. O Writer grava 1000 bytes no arquivo, em uma única write()chamada. O Reader obtém o evento inotify e chama fstato arquivo. O que o leitor vê?

  1. Existe alguma garantia de que o Reader receberá pelo menos 1.000 st_sizeno arquivo? Pelas minhas experiências, parece que não.

  2. Existe alguma garantia de que o Reader possa realmente ter read()1000 bytes?

Isso está acontecendo em uma caixa com limite de E/S sério. Por exemplo, sarmostra tempos de espera de cerca de 1 segundo. No meu caso, o Reader está esperando 10 segundos DEPOIS de receber o evento inotify antes de chamar state obter resultados muito pequenos.

O que eu esperava era que o evento inotify não fosse entregue até que o arquivo estivesse pronto. O que eu suspeito que está realmente acontecendo é que o evento inotify é acionado DURANTE a write()chamada no gravador, e os dados ficam realmente disponíveis para outros processos no sistema sempre que estiverem prontos. Neste caso, 10s não é tempo suficiente.

Acho que estou apenas procurando a confirmação de que o kernel realmente implementa o inotify da maneira que estou supondo. Além disso, se houver alguma opção, possivelmente, para alterar esse comportamento?

Finalmente, qual é o sentido do inotify, dado esse comportamento? De qualquer maneira, você fica reduzido a pesquisar o arquivo/diretório, depois de obter o evento, até que os dados estejam realmente disponíveis. É melhor estar fazendo isso o tempo todo e esquecer o inotify.

***EDITAR**** Ok, como sempre acontece, o comportamento que estou vendo realmente faz sentido, agora que entendo o que realmente estou fazendo. ^_^

Na verdade, estou respondendo a um evento IN_CREATE no diretório em que o arquivo reside. Então, na verdade, estou stat()'ing o arquivo em resposta à criação do arquivo, não necessariamente o evento IN_MODIFY, que pode chegar mais tarde.

Vou alterar meu código para que, assim que obtiver o evento IN_CREATE, eu assine IN_MODIFY no próprio arquivo e não tente realmente ler o arquivo até obter o evento IN_MODIFY. Percebo que há uma pequena janela na qual posso perder uma gravação no arquivo, mas isso é aceitável para minha aplicação, pois na pior das hipóteses, o arquivo será fechado após um número máximo de segundos.

Responder1

Pelo que vejo nofonte do kernel, o inotify só é iniciado após a conclusão de uma gravação (ou seja, seu palpite está errado). Depois que a notificação é acionada, apenas mais duas coisas acontecem na sys_writefunção que implementa o writesyscall: definir alguns parâmetros do agendador e atualizar a posição no descritor de arquivo. Este código tem sido semelhante desde2.6.14. No momento em que a notificação é acionada, o arquivo já está com seu novo tamanho.

Verifique se há coisas que podem dar errado:

  • Talvez o leitor esteja recebendo notificações antigas, da escrita anterior.
  • Se o leitor ligar state depois ligar readou vice-versa, algo pode acontecer no meio. Se você continuar anexando ao arquivo, chamar statfirst garante que você conseguirá ler até aqui, mas é possível que mais dados tenham sido gravados no momento em que o leitor chamar read, mesmo que ainda não tenha recebido a notificação inotify.
  • Só porque o gravador chama writenão significa que o kernel escreverá o número solicitado de caracteres. Existem muito poucas circunstâncias em que as gravações atômicas são garantidas em qualquer tamanho. Porém, cada writechamada é atômica garantida: em algum momento os dados ainda não foram gravados e, de repente,nbytes foram escritos, ondené o valor de retorno da writechamada. Se você observar um arquivo parcialmente escrito, significa que writeretornou menos que seu argumento de tamanho.

Ferramentas úteis para investigar o que está acontecendo incluem:

  • strace -tt
  • o subsistema auditado

informação relacionada