Banned schrieb:
da kann immer mal was schief gehen, und dann kann der fehlerhaft abgeschlossene Prozess eben nicht zurück gerollt werden.
Ist die Frage, ob das überhaupt geschieht.
In erster Linie ist es ja Sache des Prozesses. Für den Fall, das er gracefully beendet wird, ist es sowieso klar. Da kann (und sollte) es sich natürlich drum kümmern.
Für den von Dir angesprochenen Fall, das ein Programm zwangsweise beendet wird (entweder weil er gezielt "getötet" wird oder weil er abgestürzt ist), gibts meines Wissens nach keinen automatischen Mechanismus.
Das "Dateisystem" oder "der Kernel" kann ja auch gar nicht entscheiden, ob eine Datei vollständig geschrieben ist oder nicht.
Ein Indikator könnte sein, ob der File-Deskriptor zurückgegeben worden ist. Dann kann man sicher sein, das das Programm alles geschrieben hat. Aber wenn der nicht freigegeben worden ist, heißt das ja noch lange nicht, das die Datei unvollständig ist.
Und wäre ja auch doof, wenn ein Programm eine Datei vollständig geschrieben hat aber abstürzt, bevor es ein CLOSE absetzen kann. Dann würde ja eine eigentlich intakte Datei weg-rollbacked werden.
Und das Dateisystem bzw. Journal guckt in der Regel nur innerhalb der eigenen Sphäre.
Ich sag mal, wenn jetzt eine Datei gelöscht wird. Dann gibts dafür einen Syscall. Aber für das Dateisystem sind das natürlich viele Schritte. Da müssen verschiedene Meta-Daten angepasst werden, weil Blöcke als frei markiert werden und Directory-Einträge entfernt werden usw.
Und das ist dann tatsächlich gegenüber dem Userland atomar. Das heißt, da gibts auch kein "halb gelöscht" wenn ein Prozess abstürzt oder gekillt wird.
Für das normale Schreiben in eine Datei hat man das aber nicht. Und das ist natürlich ein Problem. Weil man will ja auch intakte Dateien nicht versehentlich kaputt machen, wenn ein Prozess mitten beim schreiben gekillt wird.
Daher ist ja auch ein gängiges Pattern bei Programmen den Inhalt der Datei nicht "in-place" zu schreiben, sondern eine neue Datei anzulegen und wenn der Schreibvorgang erfolgreich war, die dann in den richtigen Dateinamen umzubenennen.
Aber von sich aus macht da das Dateisystem oder Betriebssystem nichts.
Das kann man auch gern mal ausprobieren anhand eines einfachen C-Programms:
C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void generate_random_data(const char *filename, size_t size) {
FILE *file = fopen(filename, "wb");
if (file == NULL) {
perror("Fehler beim Öffnen der Datei");
exit(EXIT_FAILURE);
}
// Initialisiere den Zufallszahlengenerator
srand(time(NULL));
// Schreibe zufällige Daten in die Datei
for (size_t i = 0; i < size; i++) {
unsigned char random_byte = rand() % 256; // Zufälliges Byte (0-255)
fwrite(&random_byte, sizeof(unsigned char), 1, file);
}
fclose(file);
printf("Zufällige Daten wurden in die Datei '%s' geschrieben.\n", filename);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Verwendung: %s <Dateiname> <Größe in Bytes>\n", argv[0]);
return EXIT_FAILURE;
}
const char *filename = argv[1];
size_t size = strtoul(argv[2], NULL, 10);
generate_random_data(filename, size);
return EXIT_SUCCESS;
}
Das führt man aus und lässt es eine Datei beschreiben (oder auch überschreiben) und dann setzt man während das Programm läuft ein
kill -9 <pid> ab. Er schreibt halt, so weit wie er kommt und das wars.
Es gab immer mal Bestrebungen auch Transaktion in eine höhere Ebene einzubauen. Weiß nicht, wie weit das gekommen ist und wo und von wem das benutzt wird. Aber so unter 'nem üblichen Linux unter Benutzung der üblichen Systemaufrufe, passiert in der Richtung erst mal nix.