ubuntuusers.de

Im Skript sicher stellen, dass vor Beendigung alle Dateiänderungen auf Platte geschrieben wurde

Status: Ungelöst | Ubuntu-Version: Xubuntu 18.04 (Bionic Beaver)
Antworten |

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

Man kann sync datei (also mit Dateinamen) verwenden. Oder man kann dd ... of=datei conv=fsync verwenden. Gibt es noch andere Möglichkeiten, die ich übersehen habe?

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7782

sync datei und conv=fsync ist das gleiche in Blassblaulila.

Willst du jetzt noch mehr Befehle wissen, die ein fsync auslösen? Da wäre dann z.B. filefrag -s datei noch zu nennen.

Eine Stufe höher wäre das umounten (oder remount,ro) des Dateisystems auf dem sich die Datei befindet.

Aber abseits von Datenbanken o.ä. macht man das eigentlich nicht. Also da reicht einfach bei cp & co. auf den Exit-Status zu schauen und fertig.

Eine interessante Note aus der fsync Manpage:

Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.

So gesehen müsste man sync . datei schreiben bzw. sync "$datei" "$(dirname "$datei")"

rklm Team-Icon

Projektleitung
(Themenstarter)

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

frostschutz schrieb:

sync datei und conv=fsync ist das gleiche in Blassblaulila.

Nicht ganz, auch, wenn sie den selben Syscall benutzen.

Willst du jetzt noch mehr Befehle wissen, die ein fsync auslösen? Da wäre dann z.B. filefrag -s datei noch zu nennen.

Danke.

Eine Stufe höher wäre das umounten (oder remount,ro) des Dateisystems auf dem sich die Datei befindet.

Viel zu unselektiv und hat außerdem reichlich unerwünschte Nebenwirkungen. Da kann man lieber sync ohne Argumente verwenden.

Aber abseits von Datenbanken o.ä. macht man das eigentlich nicht. Also da reicht einfach bei cp & co. auf den Exit-Status zu schauen und fertig.

Nein, das reicht gerade nicht, wenn man sicher gehen will, dass die Änderungen persistiert sind. Der Exit-Status trifft ja überhaupt keine Aussagen dazu, ob die Datei bereits auf der Platte gespeichert ist oder nicht.

Eine interessante Note aus der fsync Manpage:

Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.

So gesehen müsste man sync . datei schreiben bzw. sync "$datei" "$(dirname "$datei")"

Guter Punkt!

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7782

rklm schrieb:

Aber abseits von Datenbanken o.ä. macht man das eigentlich nicht. Also da reicht einfach bei cp & co. auf den Exit-Status zu schauen und fertig.

Nein, das reicht gerade nicht, wenn man sicher gehen will, dass die Änderungen persistiert sind.

Ja, und sicher gehen wollen z.B. Datenbanken weil die eben auf eine Art und Weise mit Dateien arbeiten, bei der das eine Rolle spielt (eben sektorweise Veränderung mit Metadatenstrukturen die synchron bleiben müssen, gleich wie bei Dateisystemen).

Für normale Anwendungen die immer ne ganze Datei auf einmal schreiben ist das weit weniger interessant. Wenn du in einem Editor auf Speichern drückst, wird der normalerweise kein fsync machen, und das hat nichts damit zu tun, daß dein Geschreibsel unwichtig wäre.

Was willst du eigentlich machen?

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7782

frostschutz schrieb:

Wenn du in einem Editor auf Speichern drückst, wird der normalerweise kein fsync machen, und das hat nichts damit zu tun, daß dein Geschreibsel unwichtig wäre.

Okay, ich nehm das zurück.

nano macht kein fsync

vim macht scheinbar fsync

emacs kommt drauf an, siehe https://www.gnu.org/software/emacs/manual/html_node/emacs/Customize-Save.html

Emacs can invoke the fsync system call after saving a file. Using fsync does not eliminate the risk of data loss, partly because many systems do not implement fsync properly, and partly because Emacs's file-saving procedure typically relies also on directory updates that might not survive a crash even if fsync works properly.

Wenn beim fsync Fehler auftreten, bist du bei der dd Variante vielleicht besser unterwegs... in der Shell sind "schreib datei; sync datei;" zwei getrennte Aktionen, der Filedescriptor wird da zwischendurch zugemacht, und Fehler werden nur an offene Filedescriptor gemeldet. Wenn da also ein I/O Fehler o.ä. auftritt nach dem Schreiben der Datei aber vor dem Sync, bekommst du das nicht mit. Bei dd bleibt der filedescriptor offen, schreiben und sync ist da somit eine Aktion und nicht getrennt...

Aber normalerweise™ tritt dieser Fall so oder so nicht ein. Für Normalsterbliche und wenn du keine besonders außergewöhnliche Anforderungen in deiner Anwendung hast, reicht der normale Exit-Status völlig aus.

Antworten |