Gelegentlich führe ich Interviews in verschiedenen großen Unternehmen, hauptsächlich in St. Petersburg und Moskau, in der Position als DevOps. Dabei ist mir aufgefallen, dass in vielen Firmen (in vielen renommierten Firmen, wie zum Beispiel Yandex) zwei ähnliche Fragen gestellt werden:
- Was ist ein Inode;
- Aus welchen Gründen kann man einen Schreibfehler auf der Festplatte erhalten (oder anders gesagt: Warum kann der Speicherplatz erschöpft sein, die Essenz ist die gleiche).
Wie es oft vorkommt, war ich überzeugt, dass ich dieses Thema gut kenne, aber sobald ich begann zu erklären, traten Wissenslücken zutage. Um mein Wissen zu systematisieren, diese Lücken zu schließen und mich nicht weiter zu blamieren, schreibe ich diesen Artikel, vielleicht ist er auch für andere nützlich.
Ich fange „von unten“ an, also bei der Festplatte (USB-Sticks, SSDs und andere moderne Geräte lassen wir mal beiseite, um ein Beispiel zu betrachten, schauen wir uns eine alte 20- oder 80-GB-Festplatte an, da die Blockgröße 512 Byte beträgt).
Eine Festplatte kann ihren Speicherplatz nicht byteweise adressieren; er ist an Blocks gebunden. Die Nummerierung der Blöcke beginnt bei 0. (Dies wird als LBA bezeichnet, Details dazu hier: )

Wie aus der Abbildung ersichtlich ist, habe ich die LBA-Blöcke als Ebene der HDD gekennzeichnet. Übrigens kann man herausfinden, welche Blockgröße Ihre Festplatte hat, auf folgende Weise:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512Eine Partition ist auf der gesamten Festplatte formatiert (wieder der Einfachheit halber). Am häufigsten werden zwei Arten von Partitionierung verwendet: msdos und gpt. Dabei ist msdos das alte Format, das Festplatten bis zu 2 TB unterstützt, während gpt das neue Format ist, das bis zu 1 Zettabyte von 512-Byte-Blöcken adressieren kann. In unserem Fall haben wir eine msdos-Partition, wie aus dem Bild ersichtlich ist, wobei die Partition bei Block Nr. 1 beginnt und Block 0 für den MBR verwendet wird.
Im ersten Partition habe ich ein ext2-Dateisystem erstellt. Der Standardblockgröße beträgt 4096 Byte, was ebenfalls im Bild dargestellt ist. So kann man die Blockgröße des Dateisystems überprüfen:
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Dateisystem-Volumenname:
Letzte Einbindung unter:
UUID des Dateisystems: a600bf40-f660-41f6-a3e6-96c303995479
Magische Nummer des Dateisystems: 0xEF53
Versionsnummer des Dateisystems: 1 (dynamisch)
Merkmale des Dateisystems: ext_attr resize_inode dir_index filetype sparse_super large_file
Flags des Dateisystems: signed_directory_hash
Standard-Mount-Optionen: user_xattr acl
Zustand des Dateisystems: sauber
Fehlerverhalten: Fortfahren
Betriebssystemtyp des Dateisystems: Linux
Inode-Anzahl: 65536
Blockanzahl: 261888
Reservierte Blockanzahl: 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 2. Aug 15:02:13 2019
Letzte Einbindungszeit: n/a
Letzte Schreibzeit: Fr 2. Aug 15:02:14 2019
Einbindungsanzahl: 0
Maximale Einbindungsanzahl: -1
Letzte Überprüfung: Fr 2. Aug 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 isize: 28
Gewünschte zusätzliche isize: 28
Standardverzeichnis-Hash: half_md4
Verzeichnis-Hash-Samen: c0155456-ad7d-421f-afd1-c898746ccd76Der benötigte Parameter ist die "Blockgröße".
Nun zur interessantesten Frage: Wie liest man 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, wenn ich den Dateinamen kenne, die entsprechenden Blöcke? Welche Blöcke sollen gelesen werden?
Hier kommen die Inodes ins Spiel. In einem ext2fs-Dateisystem gibt es eine „Tabelle“, in der Informationen zu allen Inodes gespeichert sind. Die Anzahl der Inodes wird beim Erstellen des Dateisystems festgelegt. Die erforderlichen Zahlen finden wir im Parameter „Inode count“ der Ausgabe von tune2fs, also haben wir 65.536 Stück. In einem Inode befindet sich die benötigte Information: die Liste der Blöcke des Dateisystems für die gesuchte Datei. Wie findet man die Inode-Nummer für eine bestimmte Datei?
Die Zuordnung von Namen und Inode-Nummer befindet sich im Verzeichnis, und ein Verzeichnis im ext2fs ist eine spezielle Art von Datei, d.h. auch sie hat eine eigene Inode-Nummer. Um diesen Teufelskreis zu durchbrechen, wurde der Wurzelverzeichnis die „feste“ 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 Nummer: 0 Größe: 0
ctime: 0x5d43cb51:16b61bcc -- Fr 2 Aug 16:34:09 2019
atime: 0x5d43c247:b704301c -- Fr 2 Aug 15:55:35 2019
mtime: 0x5d43cb51:16b61bcc -- Fr 2 Aug 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fr 2 Aug 15:02:14 2019
Größe der extra Inode-Felder: 28
BLOCKS:
(0):579
GESAMT: 1Wie zu sehen ist, befindet sich das benötigte Verzeichnis im Block mit der Nummer 579. Darin finden wir die Knotennummer für den Ordner home und so weiter in der Kette, bis wir im Verzeichnis serp die Knotennummer für die angeforderte Datei sehen. Falls jemand überprüfen möchte, ob die Nummer korrekt ist und die benötigten Informationen vorhanden sind, ist das nicht schwer. Machen wir folgendes:
root@ubuntu:/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 Datensätze eingefügt
1+0 Datensätze ausgegeben
4096 Bytes (4,1 kB) kopiert, 0,000184088 s, 22,3 MB/s
root@ubuntu:/# hexdump -c /home/serp/dd_imageIm Ausgabe können die Dateinamen im Verzeichnis gelesen werden.
Jetzt komme ich zur Hauptfrage: "Aus welchen Gründen kann es zu einem Schreibfehler kommen"?
Natürlich wird dies geschehen, wenn keine freien Blöcke im Dateisystem mehr vorhanden sind. Was kann in diesem Fall getan werden? Neben dem offensichtlichen "lösche irgendetwas Unnötiges" sollte man daran denken, dass es in den Dateisystemen ext2, 3 und 4 so etwas wie "Reserved block count" gibt. Wenn wir das Listing oben ansehen, haben wir solche Blöcke in der Anzahl von "13094". Diese Blöcke sind nur für den Benutzer root zum Schreiben verfügbar. Aber wenn es schnell gelöst werden muss, kann als vorübergehende Lösung dafür gesorgt werden, dass sie für alle zugänglich sind, was zu einem kleineren freien Speicherplatz führt:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setze den Prozentsatz der reservierten Blöcke auf 0 % (0 Blöcke)Das heißt, standardmäßig steht Ihnen kein Schreibzugriff auf 5 % des Speicherplatzes zur Verfügung, und bei den heutigen Festplattengrößen können das hunderte Gigabyte sein.
Was könnte noch sein? Es kann auch vorkommen, dass freie Blöcke vorhanden sind, aber die Inodes aufgebraucht sind. Dies tritt normalerweise auf, wenn Sie in Ihrem Dateisystem viele Dateien haben, die kleiner sind als die Blockgröße des Dateisystems. Da für jede Datei oder jedes Verzeichnis ein Inode benötigt wird und insgesamt (für dieses Dateisystem) 65536 verfügbar sind, ist diese Situation mehr als realistisch. Dies kann anschaulich im Output 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 Belegt 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 deutlich im Bereich /var/www zu sehen ist, unterscheiden sich die Anzahl der freien Blöcke im Dateisystem und die Anzahl der freien Inodes erheblich.
Für den Fall, dass die Inodes zur Neige gehen, kann ich keine Ratschläge geben, da es keine gibt (falls ich falsch liege, lassen Sie es mich wissen). Daher sollten für Partitionen, in denen viele kleine Dateien entstehen, die Dateisysteme gut gewählt werden. So können beispielsweise Inodes in btrfs nicht ausgehen, da neue bei Bedarf dynamisch erstellt werden.
Quelle: habr.com
