Wohin gehen geöffnete Dateihandles, wenn sie sterben?

15

Was passiert mit den Dateien, die gelöscht werden, während ein Dateihandle für sie geöffnet ist?

Ich habe mich das gefragt, seit ich herausgefunden habe, dass ich eine Videodatei löschen kann, während sie in MPlayer abgespielt wird und bis zum Ende abgespielt wird . Woher bezieht es die Daten? Kommt es noch von der Festplatte? Wurde es nach dem Löschen der Datei in den Arbeitsspeicher kopiert?

Wenn es sich noch auf der Festplatte befindet, was passiert, wenn ich das Dateisystem auffülle, während das Programm das Lesen aus dem im Wesentlichen nicht zugewiesenen Speicherplatz ausführt? Wenn es im RAM gepuffert ist, was passiert, wenn ich die Puffer leere?

Was passiert, wenn sich die Datei auf einer NFS-Freigabe befindet - wird sie auf dem Server gespeichert? (Ist das nicht ein Sicherheitsrisiko - viele offene Remote-Datei-Handles?)

lsof -n |grep '(deleted)'Manchmal führt das Ausführen eines Tests zu interessanten Ergebnissen. Wenn ich Pakete aktualisiere, die gemeinsam genutzte Bibliotheksdateien austauschen, können Programme, die diese Bibliotheken verwendet haben, diese weiterhin verwenden, als ob sich nichts geändert hätte.

Bonusfrage: Gibt es in dieser Situation eine Möglichkeit, die Daten von den Toten zurückzubekommen?

Amphetamachine
quelle

Antworten:

13

Die Inodes verbleiben weiterhin auf der Festplatte, obwohl keine festen Verbindungen mehr zu den Inodes bestehen. Sie werden gelöscht, wenn der Dateideskriptor geschlossen wird. Bis dahin kann die Datei wie gewohnt geändert werden, mit Ausnahme von Vorgängen, die einen Dateinamen / eine feste Verknüpfung erfordern.

debugfs und ähnliche Werkzeuge können verwendet werden, um den Inhalt der Inodes wiederherzustellen.

Ignacio Vazquez-Abrams
quelle
10
Dies ist korrekt. Wenn die Datei jedoch noch geöffnet ist, können Sie sie zurückholen, indem Sie zu / proc / <PID> / fd gehen, wobei PID die PID eines Programms ist, in dem die Datei noch geöffnet ist. Dieses Verzeichnis enthält alle geöffneten Dateideskriptoren des Programms, und Sie können wie bei normalen Dateien darauf zugreifen, sodass Sie einen festen Link zum 'Wiederherstellen' der Datei erstellen können.
Patrick
Beachten Sie, dass dies /procLinux-spezifisch ist (wie es ist debugfs).
Ignacio Vazquez-Abrams
1
Solaris hat auch ein / proc und die Technik funktioniert dort prima. Ich weiß nicht über BSD Bescheid.
Patrick
2
Ich muss nur hinzufügen, dass dies fantastisch ist.
Nr.
1
@Patrick: Sie können keine feste Verknüpfung erstellen, um eine Datei von wiederherzustellen /proc. Hardlinks funktionieren nur auf demselben Dateisystem, nicht zwischen Dateisystemen. Da /proces sich um ein separates, nicht beschreibbares Dateisystem handelt, können Sie keine Hardlinks darauf erstellen. Sie können die Datei jedoch kopieren /proc.
19.
5

Der Kernel zählt die Referenzen auf den Inode. Siehe meine Antwort auf Was passiert, wenn ich einen Dateideskriptor schließe? .

Das Löschen von geöffneten Dateien ist für einen DOS-Mechanismus wahrscheinlich nicht effektiver als das Öffnen von Dateien. Die ulimitgeöffneten Dateien bieten einen gewissen Schutz gegen diesen DOS-Versuch. Es gilt für alle offenen Dateien, gelöscht oder nicht.

BillThor
quelle
5

Eine Datei wird im Dateisystem erst gelöscht, wenn alle Verweise darauf verschwunden sind. Sowohl Namen als auch offene Handles gelten als Referenzen. Solange die Datei in einem Programm geöffnet ist, wird sie nicht gelöscht, obwohl Sie auf den meisten Systemen keinen Namen dafür erstellen können.

Die Daten befinden sich noch auf dem Laufwerk, aber die Datei hat die Verbindungsanzahl 0. Wenn das System abstürzt, weiß fsck beim nächsten Neustart, dass die Daten gelöscht werden müssen. Dies führt nicht mehr zu einem Denial-of-Service als eine nicht gelöschte Datei.

Soweit ich weiß, können Sie auf einem Standard-Linux-System keine Verknüpfung zu der Datei wiederherstellen (ohne den Dateisystemtreiber debugfsoder ähnliche Methoden zu umgehen ), aber Sie können den Inhalt problemlos wiederherstellen: cat /proc/12345/fd/42Dabei steht 12345 für die Prozess-ID, unter der die Datei geöffnet ist und 42 ist die Dateideskriptornummer.

Wenn Sie über NFS eine Datei löschen, die in einem Client noch geöffnet ist, benennt der NFS-Server die Datei auf dem Server um, löscht sie jedoch erst, wenn alle Clients die Datei freigegeben haben. Meiner Erfahrung nach lautet der neue Name .nfs…, obwohl ich nicht weiß, ob der Name in allen NFS-Implementierungen gleich ist.

Gilles 'SO - hör auf böse zu sein'
quelle