¿Inotify activa una notificación cuando se inicia una escritura o cuando se completa?

12

Imagine dos procesos, un lector y un escritor, que se comunican a través de un archivo normal en un ext3 fs. Reader tiene un IN_MODIFYreloj inotify en el archivo. Writer escribe 1000 bytes en el archivo, en una sola write()llamada. Reader obtiene el evento inotify y llama fstatal archivo. ¿Qué ve Reader?

  1. ¿Hay alguna garantía de que Reader recuperará al menos 1000 st_sizeen el archivo? De mis experimentos, parece que no.

  2. ¿Hay alguna garantía de que Reader pueda realmente read()1000 bytes?

Esto está sucediendo en una caja de E / S seriamente vinculada. Por ejemplo, sarmuestra un tiempo de espera de aproximadamente 1 segundo. En mi caso, el Lector en realidad está esperando 10 segundos DESPUÉS de recibir el evento inotify antes de llamar staty obtener resultados demasiado pequeños.

Lo que esperaba era que el evento inotify no se entregaría hasta que el archivo estuviera listo. Lo que sospecho que realmente está sucediendo es que el evento inotify se dispara DURANTE la write()llamada en el Escritor, y los datos están realmente disponibles para otros procesos en el sistema siempre que estén listos. En este caso, 10 segundos no es tiempo suficiente.

Supongo que solo estoy buscando confirmación de que el kernel realmente implemente inotify de la manera que supongo. Además, si hay alguna opción, posiblemente, para alterar este comportamiento.

Finalmente, ¿cuál es el punto de inotificar, dado este comportamiento? De todos modos, se reduce a sondear el archivo / directorio, después de obtener el evento, hasta que los datos estén realmente disponibles. Bien podría estar haciendo eso todo el tiempo, y olvidarse de inotify.

*** EDITAR ** * * Bien, como sucede a menudo, el comportamiento que estoy viendo realmente tiene sentido, ahora que entiendo lo que realmente estoy haciendo. ^ _ ^

De hecho, estoy respondiendo a un evento IN_CREATE en el directorio en el que vive el archivo. Así que en realidad estoy estadizando () el archivo en respuesta a la creación del archivo, no necesariamente el evento IN_MODIFY, que puede llegar más tarde.

Voy a cambiar mi código para que, una vez que obtenga el evento IN_CREATE, me suscriba a IN_MODIFY en el archivo mismo, y en realidad no intentaré leer el archivo hasta que obtenga el evento IN_MODIFY. Me doy cuenta de que hay una pequeña ventana en la que puedo perder una escritura en el archivo, pero esto es aceptable para mi aplicación, porque en el peor de los casos, el archivo se cerrará después de un número máximo de segundos.

Todd liberado
fuente
Podría usar una tubería en lugar de un archivo. Ver hombre mknod
daniel kullmann
Necesitamos usar un archivo regular para tener un búfer de múltiples terabytes entre los dos procesos. También para preservar los datos en el búfer durante el reinicio.
Todd liberado el

Respuestas:

5

Por lo que veo en la fuente del núcleo , inotify solo se activa después de que se completa una escritura (es decir, su suposición es incorrecta). Después de que se activa la notificación, solo suceden dos cosas más sys_write, la función que implementa la writellamada al sistema: establecer algunos parámetros del planificador y actualizar la posición en el descriptor de archivo. Este código ha sido similar desde 2.6.14 . Cuando se activa la notificación, el archivo ya tiene su nuevo tamaño.

Verifique las cosas que pueden salir mal:

  • Tal vez el lector está recibiendo notificaciones antiguas, de la escritura anterior.
  • Si el lector llama staty luego llama reado viceversa, puede ocurrir algo intermedio. Si sigue agregando al archivo, llamar statprimero garantiza que podrá leer hasta ahora, pero es posible que se hayan escrito más datos cuando el lector llame read, incluso si aún no ha recibido la notificación de notificación.
  • El hecho de que el escritor llame writeno significa que el núcleo escribirá el número de caracteres solicitado. Hay muy pocas circunstancias en las que las escrituras atómicas estén garantizadas hasta cualquier tamaño. writeSin embargo, cada llamada está garantizada atómica: en algún momento los datos aún no se escriben, y de repente se han escrito n bytes, donde n es el valor de retorno de la writellamada. Si observa un archivo parcialmente escrito, significa que writedevuelve menos que su argumento de tamaño.

Las herramientas útiles para investigar lo que está pasando incluyen:

  • strace -tt
  • el subsistema auditado
Gilles 'SO- deja de ser malvado'
fuente
Gracias por las ideas. Acabo de revisar el código, y de hecho solo estoy verificando -1 como el valor de retorno de escritura para el caso de error. Entonces, puede ser que no estoy obteniendo el valor de retorno de la escritura que indica que todos los datos fueron escritos. Sin embargo, cuando miro el archivo después del hecho, sé que todos los "1000" bytes fueron escritos, porque el archivo está en buena forma, es decir, consta de registros completos y coherentes. Entonces, el primer registro no se está escribiendo parcialmente.
Todd Freed