Qualcosa riguardo l'inode

Periodicamente, per trasferirmi al Centro di distribuzione centrale, faccio colloqui presso varie grandi aziende, principalmente a San Pietroburgo e Mosca, per una posizione DevOps. Ho notato che molte aziende (molte buone aziende, ad esempio Yandex) pongono due domande simili:

  • cos'è l'inode;
  • per quali motivi puoi ricevere un errore di scrittura su disco (o ad esempio: perché potresti esaurire lo spazio su disco, l'essenza è la stessa).

Come spesso accade, ero sicuro di conoscere bene questo argomento, ma non appena ho iniziato a spiegare, le lacune nella conoscenza sono diventate evidenti. Per sistematizzare le mie conoscenze, colmare le lacune e non mettermi più in imbarazzo, scrivo questo articolo, magari sarà utile a qualcun altro.

Inizierò dal basso, cioè da un disco rigido (scarteremo unità flash, SSD e altre cose moderne; ad esempio, consideriamo qualsiasi vecchia unità da 20 o 80 GB, poiché la dimensione del blocco è di 512 byte).

Il disco rigido non sa come gestire il suo spazio byte per byte, è suddiviso condizionatamente in blocchi. La numerazione dei blocchi inizia da 0. (Questo si chiama LBA, dettagli qui: ru.wikipedia.org/wiki/LBA)

Qualcosa riguardo l'inode

Come si può vedere dalla figura, ho designato i blocchi LBA come livello dell'HDD. A proposito, puoi vedere quale dimensione del blocco ha il tuo disco in questo modo:

root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512

Il livello superiore è una partizione, una per l'intero disco (sempre per semplicità). Molto spesso vengono utilizzati due tipi di markup della partizione: msdos e gpt. Di conseguenza, msdos è un vecchio formato che supporta dischi fino a 2Tb, gpt è un nuovo formato in grado di indirizzare fino a 1 zettabyte di blocchi da 512 byte. Nel nostro caso abbiamo una partizione di tipo msdos, come si può vedere dalla figura, la partizione inizia con il blocco n°1, mentre per l'MBR viene utilizzato zero.

Nella prima partizione ho creato un file system ext2, la sua dimensione di blocco predefinita è 4096 byte, che si riflette anche nella figura. Puoi visualizzare la dimensione del blocco del file system in questo modo:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          a600bf40-f660-41f6-a3e6-96c303995479
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              65536
Block count:              261888
Reserved block count:     13094
Free blocks:              257445
Free inodes:              65525
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      63
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Filesystem created:       Fri Aug  2 15:02:13 2019
Last mount time:          n/a
Last write time:          Fri Aug  2 15:02:14 2019
Mount count:              0
Maximum mount count:      -1
Last checked:             Fri Aug  2 15:02:13 2019
Check interval:           0 (<none>)
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Default directory hash:   half_md4
Directory Hash Seed:      c0155456-ad7d-421f-afd1-c898746ccd76

Il parametro di cui abbiamo bisogno è "Dimensione del blocco".

Ora la parte interessante è come leggere il file /home/serp/testfile? Un file è costituito da uno o più blocchi del file system in cui sono archiviati i suoi dati. Conoscendo il nome del file, come trovarlo? Quali blocchi devo leggere?

È qui che gli inode tornano utili. Il file system ext2fs ha una "tabella" che contiene informazioni per tutti gli inode. Il numero di inode nel caso di ext2fs viene impostato durante la creazione del file system. Osserviamo i numeri richiesti nel parametro "Inode count" dell'output di tune2fs, ad es. abbiamo 65536 pezzi. L'inode contiene le informazioni di cui abbiamo bisogno: un elenco di blocchi del file system per il file che stiamo cercando. Come trovare il numero di inode per un determinato file?

Il nome e il numero di inode corrispondenti sono contenuti nella directory e una directory in ext2fs è un tipo speciale di file, ad es. ha anche il proprio numero di inode. Per spezzare questo circolo vizioso, alla directory root è stato assegnato un inode numero “fisso” “2”. Diamo un'occhiata al contenuto dell'inode numero 2:

root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-Feb-2014)
debugfs:  stat <2>

Inode: 2   Type: directory    Mode:  0755   Flags: 0x0
Generation: 0    Version: 0x00000000:00000002
User:     0   Group:     0   Size: 4096
File ACL: 0    Directory ACL: 0
Links: 3   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Fri Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Fri Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Fri Aug  2 15:02:14 2019
Size of extra inode fields: 28
BLOCKS:
(0):579
TOTAL: 1

Come puoi vedere, la directory di cui abbiamo bisogno è contenuta nel blocco numero 579. In esso troveremo il numero di nodo per la cartella home, e così via lungo la catena finché nella directory serp non vedremo il numero di nodo per il file richiesto. Se all'improvviso qualcuno vuole verificare se il numero è corretto e se ci sono le informazioni necessarie, non è difficile. Noi facciamo:

root@ubuntu:/# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 records in
1+0 records out
4096 bytes (4,1 kB) copied, 0,000184088 s, 22,3 MB/s
root@ubuntu:/# hexdump -c /home/serp/dd_image

Nell'output puoi leggere i nomi dei file nella directory.

Arrivo quindi alla domanda principale: “per quali motivi può verificarsi un errore di registrazione?”

Naturalmente ciò accadrà se nel file system non sono rimasti blocchi liberi. Cosa si può fare in questo caso? Oltre all'ovvio "elimina tutto ciò che non è necessario", dovresti ricordare che nei file system ext2,3 e 4 esiste qualcosa come "Conteggio blocchi riservati". Se guardi l'elenco sopra, abbiamo "13094" blocchi di questo tipo. Questi sono blocchi scrivibili solo dall'utente root. ma se hai bisogno di risolvere velocemente il problema, come soluzione temporanea puoi renderli disponibili a tutti, liberando così un po' di spazio:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 0% (0 blocks)

Quelli. per impostazione predefinita, il 5% dello spazio su disco non è disponibile per la scrittura e, dato il volume dei dischi moderni, può essere di centinaia di gigabyte.

Cos'altro potrebbe essere? È anche possibile che ci siano blocchi liberi, ma non ci siano più nodi. Questo di solito accade se sul file system sono presenti molti file più piccoli della dimensione del blocco del file system. Considerando che 1 inode viene speso per 1 file o directory e in totale abbiamo (per un dato file system) 65536, la situazione è più che realistica. Questo può essere visto chiaramente dall'output del comando df:

serp@ubuntu:~$ df -hi
Filesystem     Inodes IUsed IFree IUse% Mounted on
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
Filesystem      Size  Used Avail Use% Mounted on
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/www

Come è chiaramente visibile sulla partizione /var/www, il numero di blocchi liberi nel file system e il numero di nodi liberi variano notevolmente.

Nel caso in cui finissi gli inode, non ti dirò nessun incantesimo, perché... non ce ne sono (se sbaglio fatemelo sapere). Quindi, per le partizioni in cui si moltiplicano i file di piccole dimensioni, dovresti scegliere saggiamente il file system. Ad esempio, gli inode btrfs non possono terminare, perché Se necessario, ne vengono creati dinamicamente di nuovi.

Fonte: habr.com

Aggiungi un commento