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

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

Imagine dos procesos, un lector y un escritor, comunicándose a través de un archivo normal en un ext3 fs. El lector tiene una IN_MODIFYvigilancia inotify en el archivo. Writer escribe 1000 bytes en el archivo, en una sola write()llamada. El lector obtiene el evento inotify y solicita fstatel archivo. ¿Qué ve el lector?

  1. ¿Existe alguna garantía de que Reader recuperará al menos 1000 por st_sizeel archivo? Según mis experimentos, parece que no.

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

Esto está sucediendo en una caja seriamente limitada de E/S. Por ejemplo, sarmuestra tiempos 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 entregara hasta que el archivo estuviera listo. Lo que sospecho que realmente está sucediendo es que el evento inotify se activa DURANTE la write()llamada en el Writer, y los datos están realmente disponibles para otros procesos en el sistema cuando estén listos. En este caso, 10 segundos no es tiempo suficiente.

Supongo que solo estoy buscando confirmación de que el kernel realmente implementa inotify de la manera que supongo. Además, ¿hay alguna opción para modificar este comportamiento?

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

***EDITAR**** Bien, como suele suceder, 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 se encuentra el archivo. Así que en realidad estoy stat()'ando el archivo en respuesta a la creación del archivo, no necesariamente al 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 no intente 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.

Respuesta1

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

Compruebe si hay cosas que puedan salir mal:

  • Quizás el lector esté recibiendo notificaciones antiguas de la escritura anterior.
  • Si el lector llama staty luego llama reado viceversa, algo podría suceder en el medio. Si continúa agregando archivos al archivo, llamar statprimero garantiza que podrá leer hasta ese punto, pero es posible que se hayan escrito más datos cuando el lector llama 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á la cantidad solicitada de caracteres. Hay muy pocas circunstancias en las que las escrituras atómicas estén garantizadas hasta cualquier tamaño. Sin embargo, se garantiza que cada writellamada es atómica: en algún momento los datos aún no están escritos y, de repente,norteSe han escrito bytes, dondenortees el valor de retorno de la writellamada. Si observa un archivo parcialmente escrito, significa que writedevolvió un argumento de tamaño menor que su tamaño.

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

  • strace -tt
  • el subsistema auditado

información relacionada