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:
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