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_MODIFY
reloj inotify en el archivo. Writer escribe 1000 bytes en el archivo, en una sola write()
llamada. Reader obtiene el evento inotify y llama fstat
al archivo. ¿Qué ve Reader?
¿Hay alguna garantía de que Reader recuperará al menos 1000
st_size
en el archivo? De mis experimentos, parece que no.¿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, sar
muestra 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 stat
y 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.
Respuestas:
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 lawrite
llamada 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:
stat
y luego llamaread
o viceversa, puede ocurrir algo intermedio. Si sigue agregando al archivo, llamarstat
primero garantiza que podrá leer hasta ahora, pero es posible que se hayan escrito más datos cuando el lector llameread
, incluso si aún no ha recibido la notificación de notificación.write
no 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.write
Sin 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 lawrite
llamada. Si observa un archivo parcialmente escrito, significa quewrite
devuelve menos que su argumento de tamaño.Las herramientas útiles para investigar lo que está pasando incluyen:
strace -tt
fuente