Qualcosa sull'inode

Periodicamente, con l'obiettivo di trasferirmi in un data center, partecipo a colloqui in diverse grandi aziende, principalmente a San Pietroburgo e Mosca, per il ruolo di DevOps. Ho notato che in molte aziende (in molte buone aziende, come Yandex) fanno due domande simili:

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

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

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

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

Qualcosa sull'inode

Come si può vedere dall'immagine, i blocchi LBA li ho identificati 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

Al livello superiore è contrassegnata una partizione, una per tutto il disco (di nuovo per semplicità). Si usano più frequentemente due tipi di partizionamento: msdos e gpt. In questo caso, msdos è un formato vecchio che supporta dischi fino a 2TB, mentre 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, che inizia con il blocco n. 1, mentre lo zero viene utilizzato per il MBR.

Nella prima partizione ho creato un file system ext2, la cui dimensione del blocco è di 4096 byte per impostazione predefinita, come mostrato anche nell'immagine. Puoi controllare 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)
Nome volume filesystem:   
Ultimo montato su:         
UUID filesystem:          a600bf40-f660-41f6-a3e6-96c303995479
Numero magico filesystem:  0xEF53
Revisione filesystem #:    1 (dinamico)
Caratteristiche filesystem:      ext_attr resize_inode dir_index filetype sparse_super large_file
Flag filesystem:         signed_directory_hash
Opzioni di montaggio predefinite:    user_xattr acl
Stato filesystem:         pulito
Comportamento errori:          Continua
Tipo OS filesystem:       Linux
Conteggio inode:              65536
Conteggio blocchi:              261888
Conteggio blocchi riservati:     13094
Blocchi liberi:              257445
Inode liberi:              65525
Primo blocco:              0
Dimensione blocco:               4096
Dimensione frammento:            4096
Blocchi GDT riservati:      63
Blocchi per gruppo:         32768
Frammenti per gruppo:      32768
Inode per gruppo:         8192
Blocchi inode per gruppo:   512
Filesystem creato:       Ven Ago  2 15:02:13 2019
Ultimo tempo di montaggio:          n/a
Ultimo tempo di scrittura:          Ven Ago  2 15:02:14 2019
Conteggio montaggi:              0
Conteggio montaggi massimo:      -1
Ultima verifica:             Ven Ago  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
Dimensione extra richiesta:     28
Dimensione extra desiderata:      28
Hash directory predefinito:   half_md4
Seed hash directory:      c0155456-ad7d-421f-afd1-c898746ccd76

Il parametro di cui abbiamo bisogno è «Block size».

Ora la parte interessante: come leggere il file /home/serp/testfile? Il file è composto da uno o più blocchi del filesystem, 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 esiste una «tabella» che contiene informazioni su tutti gli inode. Il numero di inode per ext2fs è definito al momento della creazione del file system. Per i dati necessari, facciamo riferimento al parametro «Inode count» dell'output di tune2fs, ad esempio, abbiamo 65536 pezzi. Gli inode contengono le informazioni che ci servono: l'elenco dei blocchi del file system per il file specificato. Come trovare il numero inode per un file dato?

La corrispondenza tra il nome e il numero inode è contenuta 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»: «2». Vediamo 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   Flag: 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 2 Ago  16:34:09 2019
 atime: 0x5d43c247:b704301c -- Ven 2 Ago  15:55:35 2019
 mtime: 0x5d43cb51:16b61bcc -- Ven 2 Ago  16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Ven 2 Ago  15:02:14 2019
Dimensione dei campi inode extra: 28
BLOCCO:
(0):579
TOTALE: 1

Come si può notare, 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, fino a vedere nella directory serp il numero del nodo per il file richiesto. Se qualcuno volesse controllare se il numero è corretto e se ci sono le informazioni necessarie, non è complicato. Facciamo così:

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 è possibile leggere i nomi dei file nella directory.

Ed eccomi arrivato alla domanda principale: "per quali motivi potrebbe verificarsi un errore di scrittura"?

Naturalmente ciò avverrà se non ci sono blocchi liberi nel file system. Cosa si può fare in questo caso? Oltre alla ovvia "cancellare qualcosa di non necessario", va ricordato che nei file system ext2, 3 e 4 esiste una cosa chiamata "Reserved block count". Se si guarda nel listing sopra, abbiamo "13094" di questi blocchi. Questi blocchi sono disponibili per la scrittura solo per l'utente root, ma se è necessario risolvere temporaneamente la questione, è possibile renderli disponibili per tutti, creando in questo modo 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 impostazione predefinita, non hai accesso alla scrittura per il 5% dello spazio su disco, e considerando le dimensioni dei dischi moderni, questo può essere centinaia di gigabyte.

Cos'altro potrebbe esserci? È anche possibile che ci siano blocchi liberi, ma gli inode siano esauriti. Questo di solito accade quando nella tua filesystem ci sono molti file di dimensioni inferiori alla dimensione del blocco del filesystem. Tenendo presente che 1 inode è speso per 1 file o directory, e ne abbiamo in totale (per questo filesystem) 65536, la situazione è più che reale. Questo può essere chiaramente visto 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 è ben visibile nella partizione /var/www, il numero di blocchi liberi del file system e il numero di nodi liberi differiscono notevolmente.

Nel caso in cui finiscano gli inode, non posso suggerire incantesimi, poiché non ci sono (se sbaglio, fatemelo sapere). Pertanto, per le partizioni in cui proliferano piccoli file, è necessario scegliere saggiamente il file system. Ad esempio, in btrfs gli inode non possono finire, poiché ne vengono creati di nuovi dinamicamente all'occorrenza.

Fonte: habr.com

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