Imaginez deux processus, un lecteur et un écrivain, communiquant via un fichier standard sur un ext3 fs. Le lecteur possède une IN_MODIFY
veille inotify sur le fichier. Writer écrit 1000 octets dans le fichier, en un seul write()
appel. Le lecteur obtient l'événement inotify et appelle fstat
le fichier. Que voit Reader?
Y a-t-il une garantie que Reader récupérera au moins 1000 pour
st_size
le fichier? D'après mes expériences, il ne semble pas.Y a-t-il une garantie que Reader peut réellement
read()
contenir 1 000 octets?
Cela se produit sur une boîte liée sérieusement aux E / S. Par exemple, sar
affiche un temps d'attente d'environ 1 seconde. Dans mon cas, le Reader attend en fait 10 secondes APRÈS avoir reçu l'événement inotify avant d'appeler stat
et d'obtenir des résultats trop petits.
J'avais espéré que l'événement inotify ne serait pas livré tant que le dossier ne serait pas prêt. Ce que je soupçonne réellement, c'est que l'événement inotify se déclenche PENDANT l' write()
appel dans le Writer, et les données sont réellement disponibles pour d'autres processus sur le système chaque fois qu'il se trouve être prêt. Dans ce cas, 10s n'est pas suffisant.
Je suppose que je cherche juste à confirmer que le noyau implémente réellement la façon dont je devine. De plus, s'il existe des options, éventuellement, pour modifier ce comportement?
Enfin, quel est le point d'inotifier, compte tenu de ce comportement? Vous êtes de toute façon réduit à interroger le fichier / répertoire, après avoir reçu l'événement, jusqu'à ce que les données soient réellement disponibles. Autant le faire tout le temps, et oublier l'inotification.
*** ÉDITER ** * * D'accord, comme cela arrive souvent, le comportement que je vois a du sens, maintenant que je comprends vraiment ce que je fais. ^ _ ^
Je répond en fait à un événement IN_CREATE sur le répertoire dans lequel se trouve le fichier. Je suis donc en train de stat () le fichier en réponse à la création du fichier, pas nécessairement l'événement IN_MODIFY, qui peut arriver plus tard.
Je vais changer mon code pour que, une fois que j'obtiens l'événement IN_CREATE, je m'abonne à IN_MODIFY sur le fichier lui-même, et je n'essaierai pas réellement de lire le fichier jusqu'à ce que j'obtienne l'événement IN_MODIFY. Je me rends compte qu'il y a une petite fenêtre dans laquelle je peux manquer une écriture dans le fichier, mais cela est acceptable pour mon application, car dans le pire des cas, le fichier sera fermé après un nombre maximum de secondes.
Réponses:
D'après ce que je vois dans la source du noyau , inotify ne se déclenche qu'une fois l'écriture terminée (c'est-à-dire que votre supposition est fausse). Une fois la notification déclenchée, seules deux autres choses se produisent dans
sys_write
la fonction qui implémente l'write
appel système: définir certains paramètres du planificateur et mettre à jour la position sur le descripteur de fichier. Ce code est similaire depuis 2.6.14 . Au moment où la notification se déclenche, le fichier a déjà sa nouvelle taille.Vérifiez les choses qui peuvent mal tourner:
stat
, puis appelleread
ou vice versa, quelque chose peut se produire entre les deux. Si vous continuez à ajouter au fichier, appeler enstat
premier garantit que vous pourrez lire jusque-là, mais il est possible que davantage de données aient été écrites au moment où le lecteur appelleread
, même s'il n'a pas encore reçu la notification inotify.write
n'est pas parce que l'écrivain appelle que le noyau écrira le nombre de caractères demandé. Il y a très peu de circonstances où les écritures atomiques sont garanties jusqu'à n'importe quelle taille.write
Cependant, chaque appel est garanti atomique: à un moment donné, les données ne sont pas encore écrites, puis soudainement n octets ont été écrits, où n est la valeur de retour de l'write
appel. Si vous observez un fichier partiellement écrit, cela signifie qu'il awrite
retourné moins que son argument de taille.Les outils utiles pour enquêter sur ce qui se passe incluent:
strace -tt
la source