Qualcosa su inode

Periodicamente, al fine di trasferirmi in CRS, partecipo a colloqui in diverse grandi aziende, principalmente di San Pietroburgo e Mosca, per la posizione di DevOps. Ho notato che in molte aziende (in molte buone aziende, per esempio in Yandex) vengono poste due domande simili:

  • che cos'è un inode;
  • per quali motivi si può ricevere un errore di scrittura su disco (o ad esempio: perché potrebbe finire lo spazio su disco, il concetto è lo stesso).

Come spesso accade, ero sicuro di conoscere bene questo argomento, ma non appena ho iniziato a spiegare, sono emerse lacune nelle mie conoscenze. Per sistematizzare le mie conoscenze, colmare le lacune e non vergognarmi più, scrivo questo articolo, potrebbe essere utile anche a qualcun altro.

Inizierò "dal basso", ossia dall'hard disk (escludiamo pen drive, SSD e altre moderne tecnologie, per esempio consideriamo un vecchio disco da 20 o 80 GB, poiché lì la dimensione del blocco è di 512 byte).

L'hard disk non può indirizzare il proprio spazio byte per byte, è convenzionalmente suddiviso in blocchi. La numerazione dei blocchi inizia da 0. (questo è chiamato LBA, maggiori dettagli qui: ru.wikipedia.org/wiki/LBA)

Qualcosa su inode

Come si può vedere dall'immagine, ho contrassegnato i blocchi LBA come livello HDD. A proposito, per controllare quale sia la dimensione del blocco del tuo disco puoi fare così:

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

Il livello superiore è partizionato, uno per l'intero disco (di nuovo, per semplicità). Di solito si usano due tipi di partizionamento: msdos e gpt. Di conseguenza, msdos è un formato vecchio, che supporta dischi fino a 2TB, gpt è un formato nuovo, 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 dall'immagine, la partizione inizia dal blocco n. 1, mentre lo zero è utilizzato per l'MBR.

Nella prima partizione ho creato un file system ext2, la dimensione del blocco predefinita è di 4096 byte, come riflesso nell'immagine. Puoi controllare la dimensione del blocco del file system così:

root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Nome volume file system:   
Ultima montata su:        
Filesystem UUID:          a600bf40-f660-41f6-a3e6-96c303995479
Numero magico del file system:  0xEF53
Revisione file system #:    1 (dinamico)
Caratteristiche del file system:      ext_attr resize_inode dir_index filetype sparse_super large_file
Flag del file system:         signed_directory_hash
Opzioni di montaggio predefinite:    user_xattr acl
Stato del file system:         pulito
Comportamento in caso di errori:          Continua
Tipo di OS del file system:       Linux
Conteggio degli inode:              65536
Conteggio dei blocchi:              261888
Conteggio blocchi riservati:     13094
Blocchi liberi:              257445
Inode liberi:              65525
Primo blocco:              0
Dimensione del blocco:               4096
Dimensione del frammento:            4096
Blocchi GDT riservati:      63
Blocchi per gruppo:         32768
Frammenti per gruppo:      32768
Inode per gruppo:         8192
Blocchi inode per gruppo:   512
File system creato:       Ven Aug  2 15:02:13 2019
Ultimo tempo di montaggio:          n/a
Ultimo tempo di scrittura:          Ven Aug  2 15:02:14 2019
Conteggio di montaggio:              0
Conteggio massimo di montaggio:      -1
Ultima verifica:             Ven Aug  2 15:02:13 2019
Intervallo di controllo:           0 ()
UID blocchi riservati:      0 (utente root)
GID blocchi riservati:      0 (gruppo root)
Primo inode:              11
Dimensione inode:               256
Extra isize richiesto:     28
Extra isize desiderato:      28
Hash directory predefinito:   half_md4
Seed Hash Directory:      c0155456-ad7d-421f-afd1-c898746ccd76

Il parametro che ci serve è «Dimensione del blocco».

Ora la parte interessante, come leggere il file /home/serp/testfile? Il file è composto da uno o più blocchi del file system, in cui sono memorizzati i suoi dati. Sapendo il nome del file, come trovarlo? Quali blocchi leggere?

Qui entrano in gioco gli inode. Nel file system ext2fs c'è una «tabella» che contiene informazioni su tutti gli inode. Il numero di inode nel caso di ext2fs è stabilito durante la creazione del file system. I numeri necessari li vediamo nel parametro «Conteggio inode» dell'output di tune2fs, cioè ne abbiamo 65536. Negli inode è contenuta l'informazione di cui abbiamo bisogno: l'elenco dei blocchi del file system per il file cercato. Come trovare il numero inode per il file specificato?

Il corrispondente del nome e del numero inode è contenuto nella directory, e la directory in ext2fs è un file di tipo speciale, quindi ha anch'essa il proprio numero inode. Per rompere questo circolo vizioso, per la directory radice è stato assegnato un numero inode «fisso» di «2». Esaminiamo il contenuto dell'inode numero 2:

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

Inode: 2   Tipo: directory    Modalità:  0755   Flags: 0x0
Generazione: 0    Versione: 0x00000000:00000002
Utente:     0   Gruppo:     0   Dimensione: 4096
File ACL: 0    Directory ACL: 0
Collegamenti: 3   Conteggio blocchi: 8
Frammento:  Indirizzo: 0    Numero: 0    Dimensione: 0
 ctime: 0x5d43cb51:16b61bcc -- Ven Aug  2 16:34:09 2019
 atime: 0x5d43c247:b704301c -- Ven Aug  2 15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Ven Aug  2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Ven Aug  2 15:02:14 2019
Dimensione dei campi extra dell'inode: 28
BLOCCO:
(0):579
TOTALE: 1

Come si può vedere, la directory di cui abbiamo bisogno si trova nel blocco numero 579. Qui troveremo il numero del nodo per la cartella home, e così via nella catena, finché nella directory serp non vedremo il numero del nodo per il file richiesto. Se qualcuno volesse controllare se il numero è corretto e se ci sono le informazioni necessarie, non è difficile farlo. Facciamo:

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

Nell'output è possibile leggere i nomi dei file nella directory.

Ecco che sono arrivato alla questione principale: "per quali motivi potrebbe verificarsi un errore di scrittura"?

Naturalmente ciò accade se non ci sono più blocchi disponibili nel file system. Cosa si può fare in questo caso? Oltre all'ovvio "eliminare qualcosa di superfluo", bisogna ricordare che nei file system ext2, 3 e 4 esiste una cosa chiamata "Reserved block count". Se guardiamo nel listing sopra, abbiamo "13094" di questi blocchi. Si tratta di blocchi accessibili per la scrittura solo all'utente root. Ma se è necessario risolvere rapidamente il problema, come soluzione temporanea si possono rendere disponibili a tutti, il che porterà a un po' di spazio libero:

root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Impostazione della percentuale di blocchi riservati a 0% (0 blocchi)

Cioè, per default, il 5% dello spazio su disco non è accessibile per la scrittura e considerando le dimensioni degli attuali dischi, possono essere centinaia di gigabyte.

Cosa potrebbe esserci ancora? È anche possibile che ci siano blocchi liberi, ma i nodi siano esauriti. Questo di solito accade se nel file system ci sono molti file di dimensioni inferiori a quelle del blocco del file system. Considerando che per 1 file o directory si utilizza 1 inode, e ne abbiamo in totale (per questo file system) 65536 — la situazione è più che reale. 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 si può ben vedere nella partizione /var/www, il numero di blocchi liberi del file system e il numero di nodi liberi differiscono notevolmente.

Nel caso in cui si esaurissero gli inode, non posso dare suggerimenti, poiché non ci sono (se sbaglio, fatemelo sapere). Pertanto, per le partizioni in cui si generano molti file piccoli, è importante scegliere correttamente il file system. Ad esempio, in btrfs gli inode non possono esaurirsi, poiché nuovi vengono creati dinamicamente secondo necessità.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS - ProHoster