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

9

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

  1. Existe alguma garantia de que o Reader receberá pelo menos 1000% por st_size no arquivo? De minhas experiências, parece que não.

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

Isso está acontecendo em uma caixa seriamente vinculada a E / S. Por exemplo, sar mostra um tempo de espera de cerca de 1 segundo. No meu caso, o Reader está esperando 10 segundos DEPOIS de obter o evento inotify antes de chamar stat e 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 realmente está acontecendo é que o evento inotify dispara DURANTE a chamada write() no Writer, e os dados estão realmente disponíveis para outros processos no sistema sempre que estiver pronto. Neste caso, 10s não é tempo suficiente.

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

Finalmente, qual é o ponto de inotify, dado este comportamento? Você está reduzido a pesquisar o arquivo / diretório de qualquer maneira, depois de obter o evento, até que os dados estejam realmente disponíveis. Pode muito bem estar fazendo isso o tempo todo, e esquecer o inotify.

*** EDIT ** *

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

Vou alterar meu código para que, assim que eu receber o evento IN_CREATE, eu inscreva IN_MODIFY no próprio arquivo, e não tentarei ler o arquivo até obter o evento IN_MODIFY. Eu percebo que há uma pequena janela lá em que eu posso perder uma gravação no arquivo, mas isso é aceitável para o meu aplicativo, porque no pior dos casos, o arquivo será fechado após um número máximo de segundos.

    
por Todd Freed 11.07.2012 / 17:28

1 resposta

5

Pelo que eu vejo na fonte do kernel , o inotify só dispara depois que uma gravação é concluída (ou seja, seu palpite está errado). Depois que a notificação é disparada, somente duas outras coisas acontecem em sys_write , a função que implementa o write syscall: definindo alguns parâmetros do agendador e atualizando a posição no descritor de arquivo. Este código tem sido semelhante desde 2.6.14 . No momento em que a notificação é acionada, o arquivo já tem seu novo tamanho.

Verifique as coisas que podem dar errado:

  • Talvez o leitor esteja recebendo notificações antigas, da gravação anterior.
  • Se o leitor chamar stat e depois chamar read ou vice-versa, algo pode acontecer entre eles. Se você continuar anexando ao arquivo, chamar stat primeiro garante que você será capaz de ler até aqui, mas é possível que mais dados tenham sido gravados até o momento em que o leitor chamar read , mesmo que não tenha sido feito. ainda recebeu a notificação de inotify.
  • O fato de o gravador chamar write não significa que o kernel irá escrever o número de caracteres solicitado. Há pouquíssimas circunstâncias em que as gravações atômicas são garantidas em qualquer tamanho. Cada write chamada é garantida atômica, no entanto: em algum momento os dados não são escritos ainda, e então de repente n bytes foram escritos, onde n é o retorno valor da chamada write . Se você observar um arquivo parcialmente escrito, isso significa que write retornou menos que seu argumento de tamanho.

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

  • strace -tt
  • o subsistema auditd
por 12.07.2012 / 02:19