Ist es möglich, seek () -Operationen für eine Named-Pipe-Rückgabe erfolgreich auszuführen?

12

Gibt es eine Möglichkeit, um sicherzustellen, dass Programme, die versuchen, seek()Operationen an einer Named Pipe auszuführen, erfolgreich zurückkehren (aber so tun, als ob die Pipe eine leere Datei wäre), anstatt 'Illegal seek'?

Ich habe auf meinem System jedes noch so kleine Protokoll in einer SQLite-Datenbank gespeichert, ich habe nirgendwo Dateien. Es gibt jedoch einige Programme, die Probleme damit haben. Es gibt 2 spezielle Fälle;

  • Ein Programm möchte in eine Protokolldatei schreiben, die syslog-ng als Named Pipe erstellt hat und aus der es liest. Das Programm möchte seek()aus irgendeinem Grund eine ausführen und schlägt dann fehl.
  • Ein Programm (wie denyhosts oder fail2ban) möchte aus einer Protokolldatei lesen, die syslog-ng als Named Pipe erstellt hat und in die geschrieben wird. Das Programm möchte einen ausführen seek()und schlägt fehl.

Idealerweise möchte ich, dass sich diese Suchanfragen so verhalten, als ob die Named Pipe nur eine leere Datei wäre. Ich kann keinen Grund erkennen, warum ein Programm, das ein Protokoll schreibt, ohnehin eine Suche durchführen müsste. Es sollte nur die Datei zum Anhängen öffnen und mit dem Schreiben beginnen. Ich kann sehen, warum ein Programm das Lesen suchen möchte, damit es von seiner letzten Position aus fortgesetzt werden kann, und ich möchte, dass es sich so verhält, als ob die Datei leer wäre (als ob sie abgeschnitten worden wäre).

Gibt es also eine Option, die für Named Pipes festgelegt werden kann, damit sie sich so verhalten? Wenn nicht, gibt es einen Modus, der eingestellt werden kann, wenn syslog-ng die Pipe öffnet, damit sich diese so verhält (ich bin offen für Codeänderungen)? Oder bin ich einen Bach hoch?

Patrick
quelle

Antworten:

10

Für den Linux-Kernel wurden suchbare Pipes vorgeschlagen, mir ist jedoch kein funktionierender Patch zur Implementierung bekannt.

Sie können eine LD_PRELOADed-Bibliothek verwenden, die den lseekAufruf bestimmter Dateien überschreibt . Ich kenne keine Standardverpackung für diesen Zweck. Shadowfs könnte beim Schreiben helfen.

Gilles 'SO - hör auf böse zu sein'
quelle
1
Ich werde die LD_PRELOAD-Route versuchen. Nicht die beste Lösung, sollte aber machbar sein.
Patrick
Übrigens, wäre eine suchbare Pipe notwendig, damit weniger Pipe auf die gleiche Weise folgen können wie eine Datei? Ich frage im Zusammenhang mit Follow a pipe mit weniger? Frage (Sie könnten es vorziehen, dort zu beantworten).
Piotr Dobrogost
@PiotrDobrogost Im Kontext des FBefehls in less würde es für less ausreichen, den Bildschirm zu aktualisieren, wenn er etwa eine Sekunde lang keine Ausgabe erhält. Pipes suchbar zu machen, hilft nichts: Der relevante Unterschied besteht darin, dass sie Fbis zum Ende der Datei reichen und dann darauf warten, dass Daten nach dem Ende angezeigt werden. Bei Pipes kommt das Dateiende jedoch erst, wenn der Writer die Datei schließt.
Gilles 'SO- hör auf böse zu sein'
1

Wenn die Anwendung seek aufruft, ist sie entweder defekt oder soll nicht mit Pipes arbeiten. Wenn das erstere, dann muss es behoben werden. Wenn letzteres der Fall ist, erwartet es, dass die Suche tatsächlich funktioniert. Wenn Sie also lügen und behaupten, dass sie funktioniert hat, wenn dies nicht der Fall ist, wird dies mit ziemlicher Sicherheit zu einer Fehlbedienung führen.

Auch wenn die Protokolldatei durch eine Named Pipe ersetzt wird, kann jeweils nur ein Prozess daraus lesen. Es sollte stattdessen eine Steckdose sein.

Psusi
quelle
2
Nicht dazu gedacht, an Rohren zu arbeiten, bedeutet nicht, dass man nicht an Rohren arbeiten kann. Was ist, wenn die Anwendung einfach ein SEEK_END ausführt, um zum Ende der Datei zu gelangen? Oder es wird ein SEEK_CUR ausgeführt, um den aktuellen Standort zu ermitteln. Beides würde keine Probleme verursachen, wenn ich das Programm über die Ergebnisse der Suche belügen würde. Der einzige Ort, an dem Fehler auftreten können, ist, wenn die Anwendung versucht, bereits geschriebene Daten zu überschreiben, was mit Protokolldateien nicht möglich ist. Und ja, mir ist die Beschränkung auf einen Prozess pro Pipe bekannt. Dies wird kein Problem sein.
Patrick
1
Wenn es nur versucht, bis zum Ende anzuhängen, sollte es die Datei nur im Anhänge-Modus öffnen, damit sie in die fehlerhafte Kategorie fällt. Anwendungen versuchen nicht, den aktuellen Speicherort zu finden, es sei denn, sie müssen irgendwo anders suchen und dann zum aktuellen Speicherort zurückkehren, sodass sie in die Kategorie "Sie werden ihn durch unbemerktes Fehlschlagen auflösen" fallen. Es ist sehr unwahrscheinlich, dass ein Programm seek aufruft, es aber nicht wirklich benötigt, um zu funktionieren (und wenn ja, fällt es in die Kategorie broken).
Psusi
1
Nicht wahr. Viele Anwendungen suchen nach dem Ende der Datei, falls ein anderes Programm seit dem letzten Mal in die Datei geschrieben hat. Anderenfalls würde das Schreiben dort, wo es sich gerade befindet, die Änderungen des anderen Programms zunichte machen. Und wenn es aus der Datei liest, kann es SEEK_CUR verwenden, um seinen aktuellen Speicherort abzurufen, damit es beim Neustart des Programms dort weitermachen kann, wo es aufgehört hat.
Patrick
1
Bei @Patrick sollte die Datei beim Anhängen erneut geöffnet werden. In diesem Fall handelt es sich um das Lesen. In diesem Fall ist es nicht sinnvoll, neue Daten zu überspringen, die noch nicht gelesen wurden (und wenn Sie die Suche unbemerkt ignorieren, wird dies unterbrochen). Im letzteren Fall wird versucht, mithilfe von "seek" nach dem Schließen und erneuten Öffnen der Datei, die in einer Pipe unterbrochen wird, an dieselbe Position zurückzukehren, wenn Sie die Suche unbemerkt ignorieren, da der Server beim Schließen der Pipe eine SIGPIPE erhält Vermutlich wird es zurückgesetzt, sodass der nächste Client, der die Pipe öffnet, am Anfang beginnt.
Psusi