Alles, was Sie schon immer über Inodes unter Linux wissen wollten

Das Linux-Dateisystem basiert auf Inodes. Diese wichtigen Teile des Innenlebens des Dateisystems werden oft missverstanden. Schauen wir uns genau an, was sie sind und was sie tun.

Die Elemente eines Dateisystems

Per Definition muss ein Dateisystem Dateien speichern und sie enthalten auch Verzeichnisse. Die Dateien werden in den Verzeichnissen gespeichert, und diese Verzeichnisse können Unterverzeichnisse haben. Irgendwo muss etwas aufzeichnen, wo sich alle Dateien im Dateisystem befinden, wie sie genannt werden, zu welchen Konten sie gehören, welche Berechtigungen sie haben und vieles mehr. Diese Informationen werden als Metadaten bezeichnet, da diese Daten andere Daten beschreiben.

Im Linux ext4-Dateisystem arbeiten die Inode- und Verzeichnisstrukturen zusammen, um ein zugrunde liegendes Framework bereitzustellen, in dem alle Metadaten für jede Datei und jedes Verzeichnis gespeichert sind. Sie machen die Metadaten für jeden zugänglich, es erfordert, ob das den Kernel, Benutzeranwendungen oder Linux - Dienstprogramme wie ls, stat, und df.

Inodes und Dateisystemgröße

Zwar gibt es zwei Strukturen, aber ein Dateisystem erfordert viel mehr. Es gibt Tausende und Abertausende von jeder Struktur. Für jede Datei und jedes Verzeichnis ist ein Inode erforderlich. Da sich jede Datei in einem Verzeichnis befindet, ist für jede Datei auch eine Verzeichnisstruktur erforderlich. Verzeichnisstrukturen werden auch als Verzeichniseinträge oder "Einträge" bezeichnet.

Jeder Inode hat eine Inode-Nummer, die innerhalb eines Dateisystems eindeutig ist. Dieselbe Inode-Nummer kann in mehr als einem Dateisystem vorkommen. Die Dateisystem-ID und die Inode-Nummer bilden jedoch zusammen eine eindeutige Kennung, unabhängig davon, wie viele Dateisysteme auf Ihrem Linux-System bereitgestellt sind.

Denken Sie daran, dass Sie unter Linux keine Festplatte oder Partition bereitstellen. Sie mounten das Dateisystem, das sich auf der Partition befindet, sodass es einfach ist, mehrere Dateisysteme zu haben, ohne es zu merken. Wenn Sie mehrere Festplatten oder Partitionen auf einer einzelnen Festplatte haben, haben Sie mehr als ein Dateisystem. Sie können vom gleichen Typ sein - zum Beispiel alle ext4 -, aber es handelt sich immer noch um unterschiedliche Dateisysteme.

Alle Inodes werden in einer Tabelle gespeichert. Unter Verwendung einer Inode-Nummer berechnet das Dateisystem einfach den Versatz in die Inode-Tabelle, in der sich dieser Inode befindet. Sie können sehen, warum das "i" im Inode für Index steht.

Die Variable, die die Inode-Nummer enthält, wird im Quellcode als 32-Bit-Ganzzahl ohne Vorzeichen deklariert. Dies bedeutet, dass die Inode-Nummer ein ganzzahliger Wert mit einer maximalen Größe von 2 ^ 32 ist, der sich auf 4.294.967.295 berechnet - weit über 4 Milliarden Inodes.

Das ist das theoretische Maximum. In der Praxis wird die Anzahl der Inodes in einem ext4-Dateisystem bestimmt, wenn das Dateisystem mit einem Standardverhältnis von einem Inode pro 16 KB Dateisystemkapazität erstellt wird. Verzeichnisstrukturen werden im laufenden Betrieb erstellt, wenn das Dateisystem verwendet wird, da Dateien und Verzeichnisse im Dateisystem erstellt werden.

Mit einem Befehl können Sie sehen, wie viele Inodes sich in einem Dateisystem auf Ihrem Computer befinden. Die -iOption (Inodes) des dfBefehls weist ihn an, seine Ausgabe in Anzahl von Inodes anzuzeigen.

Wir werden uns das Dateisystem auf der ersten Partition auf der ersten Festplatte ansehen, also geben wir Folgendes ein:

df -i / dev / sda1

Die Ausgabe gibt uns:

  • Dateisystem : Das Dateisystem, über das berichtet wird.
  • Inodes : Die Gesamtzahl der Inodes in diesem Dateisystem.
  • IUsed : Die Anzahl der verwendeten Inodes.
  • IFree : Die Anzahl der verbleibenden Inodes, die zur Verwendung verfügbar sind.
  • IUse% : Der Prozentsatz der verwendeten Inodes.
  • Bereitgestellt am : Der Bereitstellungspunkt für dieses Dateisystem.

Wir haben 10 Prozent der Inodes in diesem Dateisystem verwendet. Dateien werden in Festplattenblöcken auf der Festplatte gespeichert. Jeder Inode zeigt auf die Plattenblöcke, in denen der Inhalt der von ihnen dargestellten Datei gespeichert ist. Wenn Sie Millionen winziger Dateien haben, können Ihnen die Inodes ausgehen, bevor Ihnen der Festplattenspeicher ausgeht. Dies ist jedoch ein sehr schwieriges Problem.

In der Vergangenheit hatten einige Mailserver, die E-Mail-Nachrichten als diskrete Dateien gespeichert haben (was schnell zu großen Sammlungen kleiner Dateien führte), dieses Problem. Als diese Anwendungen ihre Backends auf Datenbanken umstellten, löste dies das Problem. Dem durchschnittlichen Heimsystem gehen die Inodes nicht aus, was auch gut so ist, da Sie mit dem ext4-Dateisystem keine weiteren Inodes hinzufügen können, ohne das Dateisystem neu zu installieren.

Um die Größe der Festplattenblöcke in Ihrem Dateisystem anzuzeigen, können Sie den blockdevBefehl mit der --getbszOption (Blockgröße abrufen) verwenden:

sudo blockdev --getbsz / dev / sda

Die Blockgröße beträgt 4096 Bytes.

Verwenden Sie die -BOption (Blockgröße), um eine Blockgröße von 4096 Byte anzugeben und die reguläre Festplattennutzung zu überprüfen:

df-B 4096 / dev / sda1

Diese Ausgabe zeigt uns:

  • Dateisystem : Das Dateisystem, über das wir berichten.
  • 4K-Blöcke : Die Gesamtzahl von 4 KB-Blöcken in diesem Dateisystem.
  • Verwendet : Wie viele 4K-Blöcke werden verwendet?
  • Verfügbar : Die Anzahl der verbleibenden 4-KB-Blöcke, die zur Verwendung verfügbar sind.
  • Use% : Der Prozentsatz der 4 KB-Blöcke, die verwendet wurden.
  • Bereitgestellt am : Der Bereitstellungspunkt für dieses Dateisystem.

In unserem Beispiel hat der Dateispeicher (und die Speicherung der Inodes und Verzeichnisstrukturen) 28 Prozent des Speicherplatzes in diesem Dateisystem auf Kosten von 10 Prozent der Inodes belegt, sodass wir in guter Verfassung sind.

Inode-Metadaten

Um die Inode-Nummer einer Datei anzuzeigen, können Sie Folgendes lsmit der -iOption (Inode) verwenden:

ls -i geek.txt

Die Inode-Nummer für diese Datei lautet 1441801, daher enthält dieser Inode die Metadaten für diese Datei und traditionell die Zeiger auf die Festplattenblöcke, in denen sich die Datei auf der Festplatte befindet. Wenn die Datei fragmentiert, sehr groß oder beides ist, können einige der Blöcke, auf die der Inode zeigt, weitere Zeiger auf andere Plattenblöcke enthalten. Einige dieser anderen Plattenblöcke enthalten möglicherweise auch Zeiger auf einen anderen Satz von Plattenblöcken. Dies überwindet das Problem, dass der Inode eine feste Größe hat und eine endliche Anzahl von Zeigern auf Plattenblöcke halten kann.

Diese Methode wurde durch ein neues Schema ersetzt, das "Extents" verwendet. Diese zeichnen den Start- und Endblock jedes Satzes zusammenhängender Blöcke auf, die zum Speichern der Datei verwendet werden. Wenn die Datei nicht fragmentiert ist, müssen Sie nur den ersten Block und die Dateilänge speichern. Wenn die Datei fragmentiert ist, müssen Sie den ersten und letzten Block jedes Teils der Datei speichern. Diese Methode ist (offensichtlich) effizienter.

Wenn Sie sehen möchten, ob Ihr Dateisystem Festplattenblockzeiger oder -bereiche verwendet, können Sie in einen Inode schauen. Dazu verwenden wir den debugfsBefehl mit der -ROption (Anfrage) und übergeben ihm den Inode der interessierenden Datei. Dies fordert Sie  debugfs auf, den internen Befehl "stat" zu verwenden, um den Inhalt des Inodes anzuzeigen. Da Inode-Nummern nur innerhalb eines Dateisystems eindeutig sind, müssen wir auch debugfs dem Dateisystem mitteilen , auf dem sich der Inode befindet.

So würde dieser Beispielbefehl aussehen:

sudo debugfs -R "stat" / dev / sda1

Wie unten gezeigt, debugfsextrahiert der Befehl die Informationen aus dem Inode und präsentiert sie uns in less:

Die folgenden Informationen werden angezeigt:

  • Inode : Die Nummer des Inodes, den wir betrachten.
  • Typ : Dies ist eine reguläre Datei, kein Verzeichnis oder symbolischer Link.
  • Modus : Die Dateiberechtigungen in Oktal.
  • Flags : Indikatoren, die unterschiedliche Merkmale oder Funktionen darstellen. Das 0x80000 ist das Flag "Extents" (mehr dazu weiter unten).
  • Generierung : Ein Network File System (NFS) verwendet dies, wenn jemand über eine Netzwerkverbindung auf Remote-Dateisysteme zugreift, als ob er auf dem lokalen Computer bereitgestellt wäre. Die Inode- und Generierungsnummern werden als eine Art Dateihandle verwendet.
  • Version : Die Inode-Version.
  • Benutzer : Der Eigentümer der Datei.
  • Gruppe : Der Gruppeneigentümer der Datei.
  • Projekt : Sollte immer Null sein.
  • Größe : Die Größe der Datei.
  • Datei-ACL : Die Liste der Dateizugriffskontrollen. Diese wurden entwickelt, um Ihnen den kontrollierten Zugriff auf Personen zu ermöglichen, die nicht zur Eigentümergruppe gehören.
  • Links : Die Anzahl der festen Links zur Datei.
  • Blockcount : Der dieser Datei zugewiesene Festplattenspeicher in 512-Byte-Blöcken. Unsere Datei hat acht davon zugewiesen, das sind 4.096 Bytes. Unsere 98-Byte-Datei befindet sich also in einem einzelnen 4.096-Byte-Plattenblock.
  • Fragment : Diese Datei ist nicht fragmentiert. (Dies ist eine veraltete Flagge.)
  • Ctime : Der Zeitpunkt, zu dem die Datei erstellt wurde.
  • Zeitpunkt : Der Zeitpunkt, zu dem zuletzt auf diese Datei zugegriffen wurde.
  • Mtime : Der Zeitpunkt, zu dem diese Datei zuletzt geändert wurde.
  • Crtime : Der Zeitpunkt, zu dem die Datei erstellt wurde.
  • Größe zusätzlicher Inode-Felder : Das ext4-Dateisystem hat die Möglichkeit eingeführt, zum Formatierungszeitpunkt einen größeren Inode auf der Festplatte zuzuweisen. Dieser Wert gibt die Anzahl der zusätzlichen Bytes an, die der Inode verwendet. Dieser zusätzliche Speicherplatz kann auch verwendet werden, um zukünftige Anforderungen für neue Kernel zu erfüllen oder um erweiterte Attribute zu speichern.
  • Inode-Prüfsumme : Eine Prüfsumme für diesen Inode, mit der festgestellt werden kann, ob der Inode beschädigt ist.
  • Extents : Wenn Extents verwendet werden (in ext4 standardmäßig), haben die Metadaten zur Verwendung von Dateien auf Festplattenblöcken zwei Zahlen, die den Start- und Endblock jedes Teils einer fragmentierten Datei angeben. Dies ist effizienter als das Speichern jedes Plattenblocks, der von jedem Teil einer Datei belegt wird. Wir haben eine Ausdehnung, weil sich unsere kleine Datei an diesem Blockversatz in einem Plattenblock befindet.

Wo ist der Dateiname?

Wir haben jetzt viele Informationen über die Datei, aber wie Sie vielleicht bemerkt haben, haben wir den Dateinamen nicht erhalten. Hier kommt die Verzeichnisstruktur ins Spiel. Unter Linux hat ein Verzeichnis genau wie eine Datei einen Inode. Anstatt auf Plattenblöcke zu verweisen, die Dateidaten enthalten, verweist ein Verzeichnis-Inode auf Plattenblöcke, die Verzeichnisstrukturen enthalten.

Im Vergleich zu einem Inode enthält eine Verzeichnisstruktur eine begrenzte Menge an Informationen zu einer Datei. Es enthält nur die Inode-Nummer, den Namen und die Länge des Namens der Datei.

Der Inode und die Verzeichnisstruktur enthalten alles, was Sie (oder eine Anwendung) über eine Datei oder ein Verzeichnis wissen müssen. Die Verzeichnisstruktur befindet sich in einem Verzeichnisdatenträgerblock, sodass wir wissen, in welchem ​​Verzeichnis sich die Datei befindet. Die Verzeichnisstruktur gibt uns den Dateinamen und die Inode-Nummer. Der Inode sagt uns alles andere über die Datei, einschließlich Zeitstempel, Berechtigungen und wo sich die Dateidaten im Dateisystem befinden.

Verzeichnis-Inodes

Sie können die Inode-Nummer eines Verzeichnisses genauso einfach sehen wie für Dateien.

Im folgenden Beispiel verwenden wir ls die Optionen -l(Langformat), -i(Inode) und -d(Verzeichnis) und sehen uns das workVerzeichnis an:

ls -lid Arbeit /

Da wir die -dOption (Verzeichnis) verwendet haben,  lswird über das Verzeichnis selbst berichtet, nicht über dessen Inhalt. Der Inode für dieses Verzeichnis ist 1443016.

Um dies für das homeVerzeichnis zu wiederholen , geben wir Folgendes ein:

ls -lid ~

Der Inode für das homeVerzeichnis lautet 1447510, und das workVerzeichnis befindet sich im Ausgangsverzeichnis . Schauen wir uns nun den Inhalt des workVerzeichnisses an. Anstelle der  -dOption (Verzeichnis) verwenden wir die -aOption (Alle). Dies zeigt uns die Verzeichniseinträge, die normalerweise ausgeblendet sind.

Wir geben Folgendes ein:

ls -lia Arbeit /

Da wir die -aOption (all) verwendet haben, werden die Einträge mit einem (.) Und einem doppelten Punkt (..) angezeigt. Diese Einträge repräsentieren das Verzeichnis selbst (Einzelpunkt) und das übergeordnete Verzeichnis (Doppelpunkt).

Wenn Sie sich die Inode-Nummer für den Einzelpunkteintrag ansehen, stellen Sie fest, dass es sich um 1443016 handelt - dieselbe Inode-Nummer, die wir erhalten haben, als wir die Inode-Nummer für das workVerzeichnis ermittelt haben. Außerdem entspricht die Inode-Nummer für den Doppelpunkteintrag der Inode-Nummer für das homeVerzeichnis.

Aus diesem Grund können Sie mit dem cd ..Befehl eine Ebene im Verzeichnisbaum nach oben verschieben. Wenn Sie einem Anwendungs- oder Skriptnamen vorangestellt haben   ./, teilen Sie der Shell ebenfalls mit, von wo aus die Anwendung oder das Skript gestartet werden soll.

Inodes und Links

Wie bereits erwähnt, sind drei Komponenten erforderlich, um eine wohlgeformte und zugängliche Datei im Dateisystem zu haben: die Datei, die Verzeichnisstruktur und der Inode. Die Datei besteht aus den auf der Festplatte gespeicherten Daten, die Verzeichnisstruktur enthält den Namen der Datei und ihre Inode-Nummer und die Inode enthält alle Metadaten für die Datei.

Symbolische Links sind Dateisystemeinträge, die wie Dateien aussehen, aber wirklich Verknüpfungen sind, die auf eine vorhandene Datei oder ein vorhandenes Verzeichnis verweisen. Mal sehen, wie sie das schaffen und wie die drei Elemente verwendet werden, um dies zu erreichen.

Angenommen, wir haben ein Verzeichnis mit zwei Dateien: Eine ist ein Skript und die andere ist eine Anwendung, wie unten gezeigt.

Wir können den Befehl ln und die -sOption (symbolisch) verwenden, um einen Softlink zur Skriptdatei zu erstellen, wie folgt:

ls -s my_script geek.sh

Wir haben einen Link erstellt my_script.shgenannt geek.sh. Wir können Folgendes eingeben und verwenden  ls , um die beiden Skriptdateien anzuzeigen:

ls -li * .sh

Der Eintrag für geek.sh erscheint in blau. Das erste Zeichen der Berechtigungsflags ist ein "l" für die Verknüpfung und die  ->Punkte auf my_script.sh. All dies zeigt an, dass geek.shes sich um einen Link handelt.

Wie Sie wahrscheinlich erwarten, haben die beiden Skriptdateien unterschiedliche Inode-Nummern. Was jedoch überraschender sein könnte, ist der Softlink geek.sh, der nicht die gleichen Benutzerberechtigungen wie die ursprüngliche Skriptdatei hat. Tatsächlich sind die Berechtigungen für  geek.shviel liberaler - alle Benutzer verfügen über vollständige Berechtigungen.

Die Verzeichnisstruktur für geek.shenthält den Namen des Links und seinen Inode. Wenn Sie versuchen, den Link zu verwenden, wird auf seinen Inode verwiesen, genau wie auf eine normale Datei. Der Link-Inode zeigt auf einen Plattenblock, aber anstatt Dateiinhaltsdaten zu enthalten, enthält der Plattenblock den Namen der Originaldatei. Das Dateisystem leitet zur Originaldatei um.

Wir werden die Originaldatei löschen und sehen, was passiert, wenn wir Folgendes eingeben, um den Inhalt von anzuzeigen  geek.sh:

rm my_script.sh
Katze geek.sh

Die symbolische Verknüpfung ist unterbrochen und die Umleitung schlägt fehl.

Wir geben nun Folgendes ein, um einen festen Link zur Anwendungsdatei zu erstellen:

In der Special-App Geek-App

Um die Inodes für diese beiden Dateien anzuzeigen, geben Sie Folgendes ein:

ls -li

Beide sehen aus wie normale Dateien. Nichts geek-appdeutet darauf hin, dass es sich um einen Link handelt, wie er in der lsListe aufgeführt ist geek.sh. Außerdem  geek-app hat es die gleichen Benutzerberechtigungen wie die Originaldatei. Was jedoch überraschen könnte, ist, dass beide Anwendungen dieselbe Inode-Nummer haben: 1441797.

Der Verzeichniseintrag für geek-appenthält den Namen "Geek-App" und eine Inode-Nummer, entspricht jedoch der Inode-Nummer der Originaldatei. Wir haben also zwei Dateisystemeinträge mit unterschiedlichen Namen, die beide auf denselben Inode verweisen. Tatsächlich kann eine beliebige Anzahl von Elementen auf dieselbe Inode verweisen.

Wir geben Folgendes ein und verwenden das statProgramm, um die Zieldatei anzuzeigen:

stat special-app

Wir sehen, dass zwei feste Links auf diese Datei verweisen. Dies wird im Inode gespeichert.

Im folgenden Beispiel löschen wir die Originaldatei und versuchen, den Link mit einem geheimen, sicheren Passwort zu verwenden:

rm special-app
./geek-app korrektes Pferdebatterystaple

Überraschenderweise läuft die Anwendung wie erwartet, aber wie? Dies funktioniert, da beim Löschen einer Datei der Inode wieder verwendet werden kann. Die Verzeichnisstruktur wird mit einer Inode-Nummer von Null markiert, und die Plattenblöcke stehen dann zur Verfügung, damit eine andere Datei in diesem Bereich gespeichert werden kann.

Wenn die Anzahl der Hardlinks zum Inode jedoch größer als eins ist, wird die Anzahl der Hardlinks um eins verringert und die Inode-Nummer der Verzeichnisstruktur der gelöschten Datei auf Null gesetzt. Der Dateiinhalt auf der Festplatte und im Inode steht den vorhandenen Festplatten weiterhin zur Verfügung.

Wir werden Folgendes eingeben und stat erneut verwenden - diesmal am geek-app:

stat geek-app

Diese Details werden aus demselben Inode (1441797) wie der vorherige statBefehl abgerufen . Die Anzahl der Links wurde um eins reduziert.

Da wir nur einen festen Link zu diesem Inode haben, wird  geek-appdie Datei beim Löschen wirklich gelöscht. Das Dateisystem gibt den Inode frei und markiert die Verzeichnisstruktur mit einem Inode von Null. Eine neue Datei kann dann den Datenspeicher auf der Festplatte überschreiben.

VERBINDUNG: Verwendung des Befehls stat unter Linux

Inode-Gemeinkosten

Es ist ein ordentliches System, aber es gibt Gemeinkosten. Um eine Datei zu lesen, muss das Dateisystem Folgendes tun:

  • Finden Sie die richtige Verzeichnisstruktur
  • Lesen Sie die Inode-Nummer
  • Finde den richtigen Inode
  • Lesen Sie die Inode-Informationen
  • Folgen Sie entweder den Inode-Links oder den Extents zu den entsprechenden Plattenblöcken
  • Lesen Sie die Dateidaten

Ein bisschen mehr herumspringen ist notwendig, wenn die Daten nicht zusammenhängend sind.

Stellen Sie sich die Arbeit vor, die ausgeführt werden muss  ls , um eine Langformat-Dateiliste mit vielen Dateien durchzuführen. Es gibt viel Hin und Her, nur lsum die Informationen zu erhalten, die zur Generierung der Ausgabe erforderlich sind.

Um den Zugriff auf das Dateisystem zu beschleunigen, versucht Linux natürlich, so viel präventives Datei-Caching wie möglich durchzuführen. Dies hilft sehr, aber manchmal - wie bei jedem Dateisystem - kann der Overhead offensichtlich werden.

Jetzt wissen Sie warum.