Gelegentlich führe ich Gespräche mit verschiedenen großen Unternehmen, hauptsächlich in St. Petersburg und Moskau, um in die SysAdmin-Rolle zu wechseln. Ich habe festgestellt, dass in vielen Unternehmen (in vielen guten Unternehmen, zum Beispiel bei Yandex) zwei ähnliche Fragen gestellt werden:
- Was ist ein Inode?
- Aus welchen Gründen kann es zu einem Schreibfehler auf der Festplatte kommen (oder zum Beispiel: Warum könnte der Speicherplatz auf der Festplatte zu Ende gehen, der Kern ist derselbe)?
Wie es oft der Fall ist, war ich mir sicher, dass ich dieses Thema gut kenne, aber sobald ich anfing zu erklären, traten Wissenslücken auf. Um mein Wissen zu systematisieren, die Lücken zu schließen und mich nicht weiter bloßzustellen, schreibe ich diesen Artikel, vielleicht hilft er noch jemandem.
Ich beginne "von unten", das heißt, von der Festplatte (USB-Sticks, SSDs und andere moderne Dinge lassen wir mal außen vor, um ein Beispiel mit einer beliebigen alten 20- oder 80-GB-Festplatte zu betrachten, da dort die Blockgröße 512 Byte beträgt).
Die Festplatte kann ihren Speicherplatz nicht byteweise adressieren; bedingt gesagt, ist er in Blöcke unterteilt. Die Nummerierung der Blöcke beginnt bei 0. (dies wird als LBA bezeichnet, Einzelheiten finden Sie hier: )

Wie aus der Abbildung zu sehen ist, habe ich die LBA-Blöcke als Ebene HDD gekennzeichnet. Übrigens können Sie die Blockgröße Ihrer Festplatte so überprüfen:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512Ebenen höher wird eine Partition gekennzeichnet, eine für die gesamte Festplatte (wiederum zur Vereinfachung). Am häufigsten werden Partitionierungsschemata zweier Typen verwendet: msdos und gpt. Dabei ist msdos das alte Format, das Festplatten bis 2 TB unterstützt, während gpt das neue Format ist, das bis zu 1 Zettabyte großen Blöcken mit 512 Byte adressieren kann. In unserem Fall haben wir eine Partition des Typs msdos, wie aus der Abbildung zu sehen ist, beginnt die Partition dabei mit dem Block Nr. 1, während der Nullblock für den MBR verwendet wird.
In der ersten Partition habe ich ein ext2-Dateisystem erstellt, dessen Blockgröße standardmäßig 4096 Byte beträgt, was ebenfalls in der Abbildung dargestellt ist. Die Größe des Dateisystemblocks kann so überprüft werden:
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Dateisystem-Volumenname:
Zuletzt montiert:
Dateisystem UUID: a600bf40-f660-41f6-a3e6-96c303995479
Dateisystem-Magic-Zahl: 0xEF53
Dateisystem-Revision #: 1 (dynamisch)
Dateisystem-Features: ext_attr resize_inode dir_index filetype sparse_super large_file
Dateisystem-Flags: signed_directory_hash
Standard-Mountoptionen: user_xattr acl
Dateisystem-Zustand: sauber
Fehlerverhalten: Fortfahren
Dateisystem-OSTyp: Linux
Inode-Anzahl: 65536
Block-Anzahl: 261888
Reservierte Block-Anzahl: 13094
Freie Blöcke: 257445
Freie Inodes: 65525
Erster Block: 0
Blockgröße: 4096
Fragmentgröße: 4096
Reservierte GDT-Blöcke: 63
Blöcke pro Gruppe: 32768
Fragmente pro Gruppe: 32768
Inodes pro Gruppe: 8192
Inode-Blöcke pro Gruppe: 512
Dateisystem erstellt: Fr Aug 2 15:02:13 2019
Letzte Mount-Zeit: n/a
Letzte Schreibzeit: Fr Aug 2 15:02:14 2019
Mount-Anzahl: 0
Maximale Mount-Anzahl: -1
Letzte Überprüfung: Fr Aug 2 15:02:13 2019
Überprüfungsintervall: 0 ()
Reservierte Blöcke uid: 0 (Benutzer root)
Reservierte Blöcke gid: 0 (Gruppe root)
Erster inode: 11
Inode-Größe: 256
Erforderliche zusätzliche Größe: 28
Gewünschte zusätzliche Größe: 28
Standardverzeichnis-Hash: half_md4
Verzeichnis-Hash-Saat: c0155456-ad7d-421f-afd1-c898746ccd76Der benötigte Parameter ist „Blockgröße“.
Jetzt wird es interessant: Wie lese ich die Datei /home/serp/testfile? Die Datei besteht aus einem oder mehreren Blöcken des Dateisystems, in denen ihre Daten gespeichert sind. Wie finde ich die Datei, wenn ich den Dateinamen kenne? Welche Blöcke sollte ich lesen?
Hier kommen uns die Inodes zugute. Im Dateisystem ext2fs gibt es eine „Tabelle“, die Informationen über alle Inodes enthält. Die Anzahl der Inodes wird beim Erstellen des Dateisystems für ext2fs festgelegt. Die notwendigen Zahlen können wir im Parameter „Inode-Anzahl“ der Ausgabe von tune2fs sehen, d.h. wir haben 65536 Stück. In den Inodes finden wir die benötigten Informationen: eine Liste der Blöcke des Dateisystems für die gesuchte Datei. Wie finde ich die Inode-Nummer für die angegebene Datei?
Die Zuordnung zwischen Namen und Inode-Nummer befindet sich im Verzeichnis, und ein Verzeichnis in ext2fs ist eine Datei eines speziellen Typs, das heißt, es hat ebenfalls eine eigene Inode-Nummer. Um diesen Teufelskreis zu durchbrechen, wurde der Wurzelverzeichnismit der „festgelegte“ Inode-Nummer „2“ zugewiesen. Schauen wir uns den Inhalt des Inodes mit der Nummer 2 an:
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs: stat
Inode: 2 Typ: Verzeichnis Modus: 0755 Flags: 0x0
Generierung: 0 Version: 0x00000000:00000002
Benutzer: 0 Gruppe: 0 Größe: 4096
Datei-ACL: 0 Verzeichnis-ACL: 0
Links: 3 Blockanzahl: 8
Fragment: Adresse: 0 Anzahl: 0 Größe: 0
ctime: 0x5d43cb51:16b61bcc -- Fr Aug 2 16:34:09 2019
atime: 0x5d43c247:b704301c -- Fr Aug 2 15:55:35 2019
mtime: 0x5d43cb51:16b61bcc -- Fr Aug 2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fr Aug 2 15:02:14 2019
Größe der extra Inode-Felder: 28
BLOQUE:
(0):579
GESAMT: 1Wie man sieht, befindet sich das benötigte Verzeichnis im Block mit der Nummer 579. Darin finden wir die Nummer des Knotens für den Ordner home und so weiter in der Kette, bis wir im Verzeichnis serp die Knoten-Nummer für die angeforderte Datei sehen. Falls jemand überprüfen möchte, ob die Nummer korrekt ist und ob die benötigten Informationen vorhanden sind, ist das nicht schwer. Wir machen:
root@ubuntu:/$ dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 Datensätze eingelesen
1+0 Datensätze geschrieben
4096 Bytes (4,1 kB) kopiert, 0,000184088 s, 22,3 MB/s
root@ubuntu:/$ hexdump -c /home/serp/dd_imageIm Ausgabe kann man die Dateinamen im Verzeichnis lesen.
Jetzt komme ich zu der Hauptfrage: «Aus welchen Gründen kann ein Schreibfehler auftreten?»
Das wird natürlich passieren, wenn keine freien Blöcke im Dateisystem mehr vorhanden sind. Was kann man in diesem Fall tun? Neben dem offensichtlichen „etwas Überflüssiges löschen“, sollte man daran denken, dass es in den Dateisystemen ext2, 3 und 4 so etwas wie „Reservierte Blockanzahl“ gibt. Wenn man sich die obige Liste ansieht, haben wir „13094“ dieser Blöcke. Diese Blöcke sind nur für den Benutzer root zum Schreiben verfügbar. Aber wenn es notwendig ist, das Problem schnell zu lösen, können sie vorübergehend für alle zugänglich gemacht werden, wodurch etwas freier Platz entsteht:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setze den Prozentsatz reservierter Blöcke auf 0% (0 Blöcke)Das heißt, standardmäßig steht Ihnen für die Aufnahme 5% des Speicherplatzes nicht zur Verfügung, und angesichts der Größe moderner Festplatten können das Hunderte von Gigabyte sein.
Was könnte noch sein? Es kann auch die Situation auftreten, dass es freie Blöcke gibt, die Knoten aber erschöpft sind. Dies passiert normalerweise, wenn Sie im Dateisystem eine Menge Dateien haben, die kleiner sind als die Blockgröße des Dateisystems. Da für jede Datei oder jedes Verzeichnis 1 inode verwendet wird und wir insgesamt (für dieses Dateisystem) 65536 haben, ist diese Situation mehr als realistisch. Dies kann anschaulich aus der Ausgabe des Befehls df gesehen werden:
serp@ubuntu:~$ df -hi
Dateisystem Inodes IUsed IFree IUse% Eingehängt auf
udev 493K 480 492K 1% \/dev
tmpfs 493K 425 493K 1% \/run
\/dev\/xvda1 512K 240K 273K 47% \/
none 493K 2 493K 1% \/sys\/fs\/cgroup
none 493K 2 493K 1% \/run\/lock
none 493K 1 493K 1% \/run\/shm
none 493K 2 493K 1% \/run\/user
\/dev\/xvdc1 320K 4,1K 316K 2% \/var
\/dev\/xvdb1 64K 195 64K 1% \/home
\/dev\/xvdh1 4,0M 3,1M 940K 78% \/var\/www
serp@ubuntu:~$ df -h
Dateisystem Größe Benutzt Verfügbar Nutzung% Eingehängt auf
udev 2,0G 4,0K 2,0G 1% \/dev
tmpfs 395M 620K 394M 1% \/run
\/dev\/xvda1 7,8G 2,9G 4,6G 39% \/
none 4,0K 0 4,0K 0% \/sys\/fs\/cgroup
none 5,0M 0 5,0M 0% \/run\/lock
none 2,0G 0 2,0G 0% \/run\/shm
none 100M 0 100M 0% \/run\/user
\/dev\/xvdc1 4,8G 2,6G 2,0G 57% \/var
\/dev\/xvdb1 990M 4,0M 919M 1% \/home
\/dev\/xvdh1 63G 35G 25G 59% \/var\/wwwWie gut auf dem Verzeichnis \/var\/www zu erkennen ist, unterscheiden sich die Anzahl der freien Blöcke im Dateisystem und die Anzahl der freien Inodes erheblich.
Falls die Inodes ausgehen, kann ich keine Tricks verraten, da es keine gibt (wenn ich mich irre, lassen Sie es mich wissen). Daher sollte man bei Partitionen, auf denen viele kleine Dateien entstehen, das Dateisystem sorgfältig wählen. Zum Beispiel können bei btrfs die Inodes nicht ausgehen, da bei Bedarf dynamisch neue erstellt werden.
Quelle: habr.com
