Löst inotify eine Benachrichtigung aus, wenn ein Schreibvorgang gestartet oder abgeschlossen wird?

Löst inotify eine Benachrichtigung aus, wenn ein Schreibvorgang gestartet oder abgeschlossen wird?

Stellen Sie sich zwei Prozesse vor, einen Leser und einen Schreiber, die über eine normale Datei auf einem Ext3-Dateisystem kommunizieren. Der Leser überwacht die Datei mit einem Inotify-Ereignis IN_MODIFY. Der Schreiber schreibt in einem einzigen Aufruf 1000 Bytes in die Datei write(). Der Leser erhält das Inotify-Ereignis und ruft fstatdie Datei auf. Was sieht der Leser?

  1. st_sizeGibt es eine Garantie, dass Reader mindestens 1000 für die Datei zurückgibt ? Meinen Experimenten zufolge scheint dies nicht der Fall zu sein.

  2. Gibt es eine Garantie, dass der Reader tatsächlich read()1000 Bytes verarbeiten kann?

Dies geschieht bei einer stark I/O-gebundenen Box. Zeigt beispielsweise sareine Wartezeit von etwa 1 Sekunde. In meinem Fall wartet der Reader tatsächlich 10 Sekunden, NACHDEM das inotify-Ereignis eintrifft, bevor er aufruft stat, und erhält zu kleine Ergebnisse.

Ich hatte gehofft, dass das Inotify-Ereignis erst dann ausgelöst wird, wenn die Datei fertig ist. Ich vermute jedoch, dass das Inotify-Ereignis WÄHREND des write()Aufrufs im Writer ausgelöst wird und die Daten tatsächlich für andere Prozesse im System verfügbar sind, sobald sie fertig sind. In diesem Fall reichen 10 Sekunden nicht aus.

Ich denke, ich suche nur nach einer Bestätigung, dass der Kernel inotify tatsächlich so implementiert, wie ich es vermute. Und ob es möglicherweise Optionen gibt, dieses Verhalten zu ändern?

Und schließlich: Was ist der Sinn von inotify angesichts dieses Verhaltens? Sie müssen die Datei/das Verzeichnis sowieso abfragen, nachdem Sie das Ereignis erhalten haben, bis die Daten tatsächlich verfügbar sind. Das können Sie genauso gut die ganze Zeit tun und inotify vergessen.

***BEARBEITEN**** Okay, wie so oft macht das Verhalten, das ich beobachte, tatsächlich Sinn, jetzt wo ich verstehe, was ich wirklich tue. ^_^

Eigentlich reagiere ich auf ein IN_CREATE-Ereignis in dem Verzeichnis, in dem sich die Datei befindet. Ich führe also tatsächlich eine stat()-Operation für die Datei als Reaktion auf die Erstellung der Datei aus und nicht notwendigerweise auf das IN_MODIFY-Ereignis, das möglicherweise später eintritt.

Ich werde meinen Code so ändern, dass ich, sobald ich das Ereignis IN_CREATE erhalte, IN_MODIFY für die Datei selbst abonniere und nicht versuche, die Datei zu lesen, bis ich das Ereignis IN_MODIFY erhalte. Mir ist bewusst, dass es da ein kleines Zeitfenster gibt, in dem ich möglicherweise einen Schreibvorgang in die Datei verpasse, aber das ist für meine Anwendung akzeptabel, da die Datei im schlimmsten Fall nach einer maximalen Anzahl von Sekunden geschlossen wird.

Antwort1

Nach dem, was ich sehe in derKernelquelle, inotify wird erst gestartet, nachdem ein Schreibvorgang abgeschlossen ist (d. h. Ihre Vermutung ist falsch). Nachdem die Benachrichtigung ausgelöst wurde, passieren nur noch zwei weitere Dinge in sys_write, der Funktion, die den writeSystemaufruf implementiert: das Setzen einiger Scheduler-Parameter und das Aktualisieren der Position im Dateideskriptor. Dieser Code war bereits in ähnlicher Form wie2.6.14. Wenn die Benachrichtigung ausgelöst wird, hat die Datei bereits ihre neue Größe.

Überprüfen Sie, ob etwas schiefgehen könnte:

  • Möglicherweise erhält der Leser alte Benachrichtigungen vom letzten Schreiben.
  • Wenn der Reader aufruft statund dann aufruft readoder umgekehrt, kann dazwischen etwas passieren. Wenn Sie weiterhin an die Datei anhängen, statgarantiert der erste Aufruf, dass Sie so weit lesen können, aber es ist möglich, dass bis zum Aufruf des Readers mehr Daten geschrieben wurden read, auch wenn er die Inotify-Benachrichtigung noch nicht erhalten hat.
  • Nur weil der Writer aufruft, writeheißt das nicht, dass der Kernel die angeforderte Anzahl Zeichen schreibt. Es gibt nur sehr wenige Umstände, unter denen atomare Schreibvorgänge bis zu einer beliebigen Größe garantiert sind. Jeder writeAufruf ist jedoch garantiert atomar: Irgendwann sind die Daten noch nicht geschrieben, und dann plötzlichNBytes wurden geschrieben, wobeiNist der Rückgabewert des writeAufrufs. Wenn Sie eine teilweise geschriebene Datei feststellen, bedeutet dies, dass writeweniger als das Größenargument zurückgegeben wurde.

Zu den nützlichen Tools zur Untersuchung der Vorgänge gehören:

  • strace -tt
  • das auditd-Subsystem

verwandte Informationen