GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Gedanken zur Überwachung von Dateiänderungen mit Linux über das Netzwerk

Die Überwachung eines Verzeichnisses auf Änderungen ist unter Linux über den bekannten Mechanismus inotify möglich. Mit inotify ist es möglich, ein Verzeichnis zu überwachen, es so zu konfigurieren, dass es Ereignisse auf dem Inhalt überwacht, und Sie erhalten Nachrichten über einen Dateideskriptor, wenn etwas passiert. Dies funktioniert perfekt, wenn sich das Verzeichnis auf einem lokalen Speicher wie einer Festplatte, einer SSD oder einem USB-Laufwerk befindet. Es reicht jedoch nicht aus, wenn sich das Verzeichnis auf einem Netzwerkdateisystem befindet, wenn sich der Speicher auf einem anderen Computer befindet. Ein anderer Benutzer, der im selben Verzeichnis arbeitet und über dasselbe oder ein anderes Dateisystem verbunden ist, kann eine Datei entfernen, und die Überwachung, die Sie darauf eingestellt haben, wird nicht benachrichtigt.

Warum ist das so?

Inotify erhält per Design das Ergebnis einer Operation (wie mkdir oder chmod), aber auf welchem ​​Dateisystem sich die Überwachung befindet, ist Inotify unbekannt (eine Blackbox). Das Dateisystem "weiß" nicht, dass eine Überwachung eingestellt wurde, und kann daher nicht die richtigen Maßnahmen ergreifen, wie z. B. den entfernten Host zu benachrichtigen, auf dem jemand ein Verzeichnis überwachen möchte.

Solange Sie der einzige Benutzer sind, gibt es kein Problem. Es wird zu einem Problem, wenn mehrere Benutzer in dem Verzeichnis arbeiten, das Sie überwachen möchten.

Sie können dieses Verhalten mit einer öffentlichen Bibliothek vergleichen. Wenn Sie der einzige Benutzer sind, wissen Sie, welche Bücher verfügbar sind und welche nicht, da Sie wissen, welche Sie ausgeliehen haben. Dies ist nicht mehr möglich, wenn Sie nicht der einzige Benutzer sind, es gibt mehr Benutzer, die die Bücher ausleihen.

In diesem Fall sollte jemand in der Bibliothek verwalten, was von einem Benutzer ausgeliehen wird (was der übliche Fall ist), und Sie müssen sich an diese Person wenden, um zu erfahren, ob ein Buch verfügbar ist oder nicht. Das ist, als würde man jemanden bitten, Sie zu informieren, wenn ein gerade nicht vorhandenes Buch wieder verfügbar ist.

Nun, diese Kontaktaufnahme mit der Bibliothek, um Sie zu informieren, funktioniert nicht mit Linux, wo natürlich die Bibliothek der entfernte Speicher ist und der Server "jemand", der in der Bibliothek arbeitet.

Damit dies unter Linux funktioniert, muss der Remote-Server benachrichtigt werden, dass eine Überwachung eingestellt wurde.

Tatsächlich unterstützen Dateisysteme wie CIFS und neuere Versionen von NFS das Senden einer Überwachung an den Server:für CIFS in Zeile 6438 von fs/cifs/cifssmb.c von Kernel 4.1.2 ist die SMB-Nachricht dafür (NT_TRANSACT_NOTIFY_CHANGE) auskommentiert aber immer noch vorhanden. Der Grund für das Auskommentieren ist, dass es mit dnotify funktioniert hat, das seit langem nicht mehr das Standard-fsnotify-System für Linux ist.


Die Weiterleitung von Watches unter Linux mit Netzwerk-Dateisystemen und FUSE zum Laufen zu bringen, ist über Kernel Space möglich.

Neulich habe ich versucht, diese "Weiterleitung der Uhr zum Server" mit FUSE zu realisieren. Ich musste patchen:

Das fsnotify-Kernel-Subsystem, um das FUSE-Kernel-Modul zu benachrichtigen, dass eine Überwachung auf einem Inode gesetzt oder entfernt wurde.

Das FUSE-Kernelmodul soll Maßnahmen ergreifen, nachdem es von fsnotify informiert wurde. Ich habe einen neuen Operationscode
FUSE_FSNOTIFY eingeführt, den das Kernelmodul zusammen mit der Inodennummer und Maske an den Userspace-Daemon sendet.

Die FUSE-Bibliothek zum Empfangen und Verarbeiten des FUSE_FSNOTIFY-Aufrufs durch Aufrufen der richtigen Funktion des Userspace-Dateisystems.

Die FUSE-Bibliothek, um die fs-Ereignisse zu empfangen und zu verarbeiten und diese an das VFS zurückzumelden.

Wenn Sie sich die Funktionsweise genauer ansehen, wenn die Uhr vom Userspace-Dateisystem erfolgreich auf ihrem Backend eingestellt wurde (beachten Sie, dass es auch möglich ist, ENOSYS zu antworten), kann das Backend jederzeit ein Ereignis an die Uhr senden, bis die Uhr wird entfernt. Was tun mit diesem Ereignis?

Ein mögliches Szenario:

Führen Sie einen zusätzlichen FUSE-Opcode FUSE_FSNOTIFY_EVENT ein, übersetzen Sie die Maske in dem vom Backend-Protokoll empfangenen Ereignis in etwas, das fsnotify versteht, und senden Sie es mit dem neuen Opcode, dem Inode der Uhr, dem Namen des Eintrags und dem FUSE-Modul zurück die übersetzte Maske. Das FUSE-Modul sendet es seinerseits an das fsnotify-Subsystem, das die Listener (inotify und oder fanotify) informiert, wo die Information bereitgestellt wird, dass das Ereignis auf dem Backend liegt. (Ein extra Event-Flag wird benötigt, zB für inotify die Event-Maske IN_REMOTE, für fanotify FAN_REMOTE). Es ist Sache des Zuhörers, was er mit dieser Information macht. Das lokale VFS kann bereits auf dem neuesten Stand sein oder auch nicht.

Anmerkungen:

Das Übersetzen einer Maske von einem Backend in etwas, das fsnotify versteht, kann je nach Ereignis sehr einfach und nicht so einfach sein. Die grundlegenden Ereignisse wie das Erstellen (oder Entfernen) eines Eintrags im überwachten Verzeichnis sind einfach (FS_CREATE bzw. FS_DELETE), das Ändern des Besitzers ist auch nicht so schwer (FS_ATTRIB), aber so etwas wie ein erweitertes Attribut (SMB verwendet diese Menge) kann nur in etwas Allgemeines als FS_ATTRIB übersetzt werden.

Das FUSE-Modul soll prüfen, ob die Uhr und/oder der Inode noch gültig ist und ob die Maske der Uhr auf die Ereignismaske zutrifft.

Zusätzliche Maskenbits IN_REMOTE (für Inotify) und FAN_REMOTE (für Fanotify) sind erforderlich.

Doppelte Angaben sind zu vermeiden. Das ist schwierig. Zum Beispiel das Erstellen einer Datei im überwachten Verzeichnis auf demselben Host, auf dem die Überwachung läuft. Wenn dieser Vorgang erfolgreich ist, wird ein fsnotify-Ereignis FS_CREATE ausgelöst, und es wird auch ein FS_CREATE | erstellt FS_REMOTE-Ereignis, da die Operation erfolgreich auf dem Backend ausgeführt wird, was zu dieser Meldung führt (vom Backend→fuse-Bibliothek→FUSE-Kernelmodul→fsnotify-Subsystem→inotify und/oder fanotify).

Eine Möglichkeit, dies anzugehen, besteht darin, das Backend zu bitten, nur Ereignisse zu senden, die von anderen initiiert wurden. Für das Backend ist es ziemlich einfach, den Initiator (Host) eines FS-Ereignisses mit dem Host zu vergleichen, der die Verbindung herstellt.

Eine andere Lösung besteht darin, das gemeldete Ereignis mit dem lokalen Cache in der Fuse-Bibliothek und dem FUSE-Modul zu vergleichen. Mit dem Beispiel zum Erstellen einer Datei sollte die Bibliothek (und das FUSE-Modul) prüfen, ob der Eintrag bereits im überwachten Verzeichnis vorhanden ist. Wenn nicht, wird es nicht von diesem Host initiiert. Beim Löschen ist dies ähnlich.

Für andere Ereignisse, wie das Schreiben in eine Datei oder das Ändern des Besitzers, ist diese Methode nicht ausreichend, zusätzliche Informationen darüber, was sich entfernt geändert hat (wie neue Größe, neuer Besitzer), müssen in der Nachricht enthalten sein, die vom entfernten Host gesendet wird.

Wenn diese Informationen nicht vom Backend bereitgestellt werden, besteht eine andere Lösung darin, den Daemon, der für die Überwachung von FS-Ereignissen im Auftrag von Clients verantwortlich ist, dazu zu bringen, einen Cache der letzten lokalen Ereignisse zu verwalten. Wenn ein entferntes Ereignis gemeldet wird und im Cache kein lokales Äquivalent gefunden wird, wird es von einem anderen Host initiiert. Dies kann schwierig werden, da die Ereignisse über eine Verbindung für einen bestimmten Benutzer gemeldet werden, andere Benutzer möglicherweise berechtigt sind, Ereignisse zu empfangen oder nicht. Und wie groß wird dieser Cache sein?

Ich habe FUSE oben verwendet, ich denke, es ist ähnlich für andere Dateisysteme wie CIFS und NFS.

Ach ja, es gibt noch eine andere Möglichkeit:einfach alle 5 Sekunden oder so abfragen.

Stefan Bon


Linux
  1. Überwachen Sie Befehle und Aufgaben mit dem Linux-Überwachungsbefehl

  2. Finden Sie Dateien und Verzeichnisse unter Linux mit dem Befehl find

  3. Überprüfen Sie den Dateistatus unter Linux mit dem Befehl stat

  4. Kopieren und Einfügen in der Linux-Befehlszeile mit xclip

  5. Hinter den Kulissen mit Linux-Containern

Linux:So teilen Sie Dateien in einem lokalen Netzwerk mit woof

Linux-Uhrbefehl mit Beispielen

Linux-WC-Befehl mit Beispielen

Überwachung der Bandbreite unter Linux mit Nethogs

Network Manager unter Linux mit Beispielen

Sichern Sie Linux mit der Sudoers-Datei