it-swarm.com.de

Wie unterscheiden sich die O_SYNC- und O_DIRECT-Flags in open (2)?

Die Verwendung und die Auswirkungen der Flags O_SYNC und O_DIRECT sind sehr verwirrend und scheinen zwischen den Plattformen etwas zu variieren. Auf der Linux-Manpage (siehe Beispiel hier ) bietet O_DIRECT synchrone E/A, minimiert Cache-Effekte und erfordert, dass Sie die Blockgrößenausrichtung selbst vornehmen. O_SYNC garantiert nur synchrone I/O. Obwohl beide garantieren, dass Daten in den Festplattencache geschrieben werden, glaube ich, dass direkte E/A-Vorgänge schneller sein sollen als normale E/A-Vorgänge, da sie den Seitencache umgehen (obwohl FreeBSDs Manpage für open (2) dies angibt Der Cache wird umgangen, wenn O_SYNC verwendet wird (siehe hier ).

Was genau sind die Unterschiede zwischen den Flags O_DIRECT und O_SYNC? Bei einigen Implementierungen wird die Verwendung von O_SYNC | empfohlen O_DIRECT. Warum? 

44
user625070

O_DIRECT allein verspricht nur, dass der Kernel das Kopieren von Daten aus dem Benutzerraum in den Kernelraum vermeidet und stattdessen direkt über DMA schreibt (direkter Speicherzugriff; wenn möglich). Daten werden nicht in Caches gespeichert. Es gibt keine strikte Garantie, dass die Funktion erst zurückkehrt, nachdem alle Daten übertragen wurden.

O_SYNC garantiert, dass der Aufruf nicht zurückkehrt , bevor alle Daten auf die Festplatte übertragen wurden (soweit das Betriebssystem dies erkennt). Dies garantiert immer noch nicht, dass sich die Daten nicht irgendwo im Festplatten-Schreibcache befinden, dies ist jedoch das, was das Betriebssystem garantieren kann.

O_DIRECT | O_SYNC ist die Kombination davon, d. H. "DMA + Garantie".

79
Damon

Eigentlich unter Linux 2.6 ist o_direct synchron, siehe Manpage:

Manpage von Open, es gibt 2 Abschnitt darüber ..

Unter 2.4 wird nicht garantiert

O_DIRECT (Seit Linux 2.4.10) Versuchen Sie, die Cache-Effekte der E/A zu und von dieser Datei zu minimieren. Normalerweise verringert dies die Leistung, ist jedoch in besonderen Situationen hilfreich, wenn z. B. Anwendungen ihre eigene Zwischenspeicherung durchführen. Die Datei E/A wird direkt in/aus Pufferbereichen für Benutzer ausgeführt. Das O_DIRECT-Flag allein ist bemüht, Daten synchron zu übertragen, gibt dem O_SYNC-Flag jedoch nicht die Gewähr, dass Daten und erforderliche Metadaten übertragen werden. Um eine synchrone E/A zu gewährleisten, muss zusätzlich zu O_DIRECT O_SYNC verwendet werden. Weitere Hinweise finden Sie unten unter HINWEISE.

Eine semantisch ähnliche (aber veraltete) Schnittstelle für Blockgeräte wird in raw (8) beschrieben.

aber unter 2.6 ist es garantiert, siehe

O_DIRECT

Das O_DIRECT-Flag kann Ausrichtungsbeschränkungen für die Länge und Adresse von Userpace-Puffern und den Datei-Offset von E/As auferlegen. In Linux variieren die Ausrichtungsbeschränkungen je nach Dateisystem und Kernel-Version und sind möglicherweise nicht vollständig. Es gibt jedoch derzeit keine dateisystemunabhängige Schnittstelle, mit der eine Anwendung diese Einschränkungen für eine bestimmte Datei oder ein Dateisystem erkennen kann. Einige Dateisysteme stellen hierfür eigene Schnittstellen zur Verfügung, beispielsweise die Operation XFS_IOC_DIOINFO in xfsctl (3).

Unter Linux 2.4 müssen die Übertragungsgrößen und die Ausrichtung des Benutzerpuffers und der Dateioffset ein Vielfaches der logischen Blockgröße des Dateisystems sein. Unter Linux 2.6 genügt die Ausrichtung auf 512-Byte-Grenzen.

O_DIRECT-E/As sollten niemals gleichzeitig mit dem Systemaufruf von fork (2) ausgeführt werden, wenn der Speicherpuffer ein privates Mapping ist (dh, jedes mit dem Kennzeichen mmap (2) MAP_PRIVATE erstellte Mapping), einschließlich auf dem Heapspeicher und statisch zugewiesenem Speicher zugeordnete Puffer). Jede dieser E/As, ob über eine asynchrone E/A-Schnittstelle oder von einem anderen Thread im Prozess übermittelt, sollte abgeschlossen sein, bevor Fork (2) aufgerufen wird. Andernfalls kann es zu Datenbeschädigung und undefiniertem Verhalten in übergeordneten und untergeordneten Prozessen kommen. Diese Einschränkung gilt nicht, wenn der Speicherpuffer für die O_DIRECT-E/As mit shmat (2) oder mmap (2) mit dem Flag MAP_SHARED erstellt wurde. Diese Einschränkung gilt auch nicht, wenn der Speicherpuffer als MADV_DONTFORK mit madvise (2) empfohlen wurde, um sicherzustellen, dass er dem Kind nach einer Verzweigung (2) nicht zur Verfügung steht.

Das Flag O_DIRECT wurde in SGI IRIX eingeführt, wo es Ausrichtungsbeschränkungen gibt, die denen von Linux 2.4 ähneln. IRIX hat auch einen Aufruf von fcntl (2), um die entsprechenden Ausrichtungen und Größen abzufragen. FreeBSD 4.x hat ein Flag mit demselben Namen eingeführt, jedoch ohne Ausrichtungseinschränkungen.

Die Unterstützung von O_DIRECT wurde unter Linux in der Kernel-Version 2.4.10 hinzugefügt. Ältere Linux-Kernel ignorieren dieses Flag einfach. Einige Dateisysteme implementieren das Flag möglicherweise nicht, und open () schlägt mit EINVAL fehl, wenn es verwendet wird.

Anwendungen sollten das Mischen von O_DIRECT und normaler E/A in dieselbe Datei und insbesondere in überlappende Bytebereiche in derselben Datei vermeiden. Selbst wenn das Dateisystem die Kohärenzprobleme in dieser Situation korrekt behandelt, ist der E/A-Durchsatz insgesamt wahrscheinlich langsamer als die Verwendung beider Modi. Ebenso sollten Anwendungen das Mischen von mmap (2) von Dateien mit direkter E/A zu denselben Dateien vermeiden.

Das Verhalten von O_DIRECT mit NFS unterscheidet sich von lokalen Dateisystemen. Ältere Kernel oder auf bestimmte Weise konfigurierte Kernel unterstützen diese Kombination möglicherweise nicht. Das NFS-Protokoll unterstützt keine Übergabe des Flags an den Server, sodass O_DIRECT I/O nur den Seitencache auf dem Client umgeht. Der Server kann die E/A weiterhin zwischenspeichern. Der Client fordert den Server auf, die E/A synchron zu machen, um die synchrone Semantik von O_DIRECT zu erhalten. Einige Server arbeiten unter diesen Umständen schlecht, insbesondere wenn die E/A-Größe klein ist. Einige Server können auch so konfiguriert sein, dass sie Clients darauf hinweisen, dass die E/A einen stabilen Speicher erreicht hat. Dadurch wird die Leistungseinbuße bei einem gewissen Risiko für die Datenintegrität bei einem Stromausfall des Servers vermieden. Der Linux-NFS-Client legt keine Ausrichtungsbeschränkungen für O_DIRECT-E/A fest.

Zusammenfassend ist O_DIRECT ein potenziell leistungsfähiges Werkzeug, das mit Vorsicht verwendet werden sollte. Es wird empfohlen, dass Anwendungen die Verwendung von O_DIRECT als Leistungsoption behandeln, die standardmäßig deaktiviert ist.

"Die Sache, die mich an O_DIRECT immer gestört hat, ist, dass die gesamte Schnittstelle nur dumm ist und wahrscheinlich von einem verwirrten Affen auf einigen ernsthaften, den Geist kontrollierenden Substanzen entworfen wurde." --- Linus

8
HardySimpson

In diesem lwn-Artikel finden Sie eine klare Beschreibung der Rollen von O_DIRECT und O_SYNC und deren Auswirkungen auf die Datenintegrität:

https://lwn.net/Articles/457667/

7
jmoyer

AFAIK, O_DIRECT umgeht den Seitencache. O_SYNC verwendet den Page-Cache, synchronisiert ihn jedoch sofort. Der Seiten-Cache wird von Prozessen gemeinsam genutzt. Wenn also ein anderer Prozess in derselben Datei ohne das Flag O_DIRECT ausgeführt wird, können die korrekten Daten gelesen werden.

0