Ein paar Besonderheiten von Linux/Unix-Filesystemen

Unix und in der Folge auch Linux liegt ein gewisses Verständnis darüber zugrunden, wie die Dateisysteme (Filesysteme) funktionieren. Man kann zwar unter Linux auch Filesysteme wie FAT32 einbinden, die diese Eigenschaften nicht haben, sollte das aber nur tun, um Daten mit einem Medium auszutauschen, das auch von anderen Betriebssystemen verwendet wird, nicht aber für die eigentliche Linux-Installation, nicht einmal für das Home-Verzeichnis.

Man hat aber heute eine Vielzahl von guten Filesystemen zur Verfügung, die die benötigten Features haben.

Grundsätzlich ist ein Verzeichnis (engl. Directory) selbst eine spezielle Datei, die die darin vorkommenden Dateinamen und jeweils eine Referenz zu einem sogenannten I-Node (inode) enthält, wo u.a. gespeichert ist, welche Berechtigungen, welche Änderungs- und Zugriffsdaten und welche Größte die Datei hat und wo man deren Inhalte finden kann. Normalerweise sind die Dateien in „Blöcken“ gespeichert, die z.B. 1024 Bytes groß sind, wobei der letzte Block normalerweise nicht vollständig ausgenutzt wird. Zusätzlich benötigt man bei größeren Dateien mit vielen Blöcken eine Struktur, um diese zu finden, die im I-Node selbst keinen Platz hat.

Nun kann man sogenannte „hard-links“ anlegen, z.B. mit ln. Das bedeutet, dass ein I-Node von mehreren Verzeichnissen referenziert wird. Der hard-link und sein
Original sind dabei völlig gleichberechtigt, es gibt keinen Unterschied zwischen dem zuerst vorhandenen Eintrag und dem neuen, als Hardlink angelegten. Deutlich zu unterscheiden ist das von sogenannten Softlinks, die auf einen anderen Verzeichniseintrag verweisen und damit indirekt auf eine Datei, wenn dieser Verzeichniseintrag tatsächlich existiert. Wegen der hard-links kann eine Datei also beliebig oft im Dateisystem eingetragen sein und wenn man sie mit rm löscht, dann wird in Wirklichkeit nur der eine Eintrag im Verzeichnis gelöscht. Nur wenn diese Datei wirklich nirgendwo sonst mehr referenziert wird, wird sie auch selber gelöscht. Dazu führt der I-Node noch einen Referenzzähler.

Was passiert nun, wenn man eine Datei mit einem Programm öffnet und löscht, bevor das Programm beendet ist? Etwa so etwas:

In xterm1:

$ sort grosse-datei.txt > sorted.txt

Und in xterm2 direkt nachdem das sort gestartet wurde, aber bevor es beendet wurde:

$ rm grosse-datei.txt

?
Die Datei wird wirklich aus dem Verzeichnis gelöscht, ist also mit ls nicht mehr zu sehen.

Das „sort“ greift aber über den I-Node darauf zu und hat noch weiterhin zugriff, zählt also auch als eine Referenz in der Zählung. So kann sort seine Arbeit noch beenden, aber kein anderes Programm mehr auf diese „halb-gelöschte“ Datei zugreifen. Man kann das mit df -k erkennen. Sobald das sort fertig ist, wird der Referenzzähler im I-Node heruntergezählt und wenn nicht noch Hardlinks oder andere Programme darauf zugreifen, dann geht er auf 0 runter und die Datei wird wirklich gelöscht, erkennbar mit df.

Vorsicht ist natürlich geboten bei Programmen, die eine Datei zwar lesen, aber dabei eine raffinierte File-Handle-Verwaltung benutzen, also die Datei immer wieder kurz zum Lesen öffnen, ein paar Daten lesen und wieder schließen, um aufwendige Berechnungen mit den Daten zu machen, bis der nächste Lesezugriff erfolgt. Bei so einem Programm würde das Wiederöffnen der Datei in unserem obigen Szenario zu einem Fehler führen, weil die Datei vom System als nicht mehr referenziert erkannt und
definitiv gelöscht worden wäre.

Die typischen Unix/Linux/Posix-Tools wie grep, sort, uniq, cat,…. öffnen aber die betreffende Datei nur einmal und lesen alles sequentiell. Dieses raffinierte Öffnen und Schließen ist eher bei Datenbanksytemen und datenbankähnlicher Software zu üblich.

Wenn man dieses Verhalten kennt, kann man damit viel anfangen, wenn man es nicht kennt, gibt es wohl gelegentlich Überraschungen.

Share Button

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*