Algo sobre inode

Periodicamente, para pasar ao Centro de Distribución Central, entrevisto a varias grandes empresas, principalmente en San Petersburgo e Moscova, para un posto de DevOps. Notei que moitas empresas (moitas boas empresas, por exemplo Yandex) fan dúas preguntas similares:

  • que é o inode;
  • por que razóns pode obter un erro de escritura no disco (ou, por exemplo: por que pode quedar sen espazo no disco, a esencia é a mesma).

Como adoita suceder, estaba seguro de que coñecía ben este tema, pero en canto comecei a explicar, fixéronse patentes as lagoas no coñecemento. Para sistematizar os meus coñecementos, encher os ocos e xa non avergoñarme, estou escribindo este artigo, quizais lle sexa útil a outra persoa.

Vou comezar por abaixo, é dicir. desde un disco duro (descartaremos unidades flash, SSD e outras cousas modernas; por exemplo, consideremos calquera unidade antiga de 20 ou 80 gigas, xa que o tamaño do bloque é de 512 bytes).

O disco duro non sabe como abordar o seu espazo byte a byte; está condicionadamente dividido en bloques. A numeración dos bloques comeza a partir de 0. (Isto chámase LBA, detalles aquí: ru.wikipedia.org/wiki/LBA)

Algo sobre inode

Como se pode ver na figura, designei bloques LBA como o nivel de disco duro. Por certo, podes ver que tamaño de bloque ten o teu disco así:

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

O nivel anterior é unha partición, unha para todo o disco (de novo por simplicidade). Na maioría das veces utilízanse dous tipos de marcado de partición: msdos e gpt. En consecuencia, msdos é un formato antigo que admite discos de ata 2 Tb, gpt é un formato novo capaz de abordar ata 1 zettabyte de bloques de 512 bytes. No noso caso, temos unha partición de tipo msdos, como se pode ver na figura, a partición comeza co bloque no 1, mentres que cero se usa para o MBR.

Na primeira partición creei un sistema de ficheiros ext2, o seu tamaño de bloque predeterminado é de 4096 bytes, o que tamén se reflicte na figura. Podes ver o tamaño do bloque do sistema de ficheiros deste xeito:

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

O parámetro que necesitamos é "Tamaño do bloque".

Agora a parte interesante é como ler o ficheiro /home/serp/testfile? Un ficheiro está formado por un ou máis bloques do sistema de ficheiros nos que se almacenan os seus datos. Coñecendo o nome do ficheiro, como atopalo? Que bloques debo ler?

Aquí é onde os inodos son útiles. O sistema de ficheiros ext2fs ten unha "táboa" que contén información para todos os inodos. O número de inodos no caso de ext2fs establécese ao crear o sistema de ficheiros. Observamos os números necesarios no parámetro "Reconto de inodos" da saída de tune2fs, é dicir. temos 65536 pezas. O inodo contén a información que necesitamos: unha lista de bloques do sistema de ficheiros para o ficheiro que buscamos. Como atopar o número de inodo para un ficheiro determinado?

O nome e o número de inodo correspondentes están contidos no directorio, e un directorio en ext2fs é un tipo especial de ficheiro, é dicir. tamén ten o seu propio número de inodo. Para romper este círculo vicioso, asignouse un número de inodo "fixo" "2" ao directorio raíz. Vexamos o contido do inodo número 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

Como podes ver, o directorio que necesitamos está contido no bloque número 579. Nel atoparemos o número de nodo para o cartafol de inicio, e así sucesivamente ata que no directorio serp vexamos o número de nodo para o ficheiro solicitado. Se de súpeto alguén quere comprobar se o número é correcto e se a información necesaria está alí, non é difícil. Facemos:

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

Na saída pode ler os nomes dos ficheiros do directorio.

Entón chego á pregunta principal: "¿Por que motivos se pode producir un erro de gravación?"

Por suposto, isto ocorrerá se non quedan bloques libres no sistema de ficheiros. Que se pode facer neste caso? Ademais do obvio "eliminar calquera cousa innecesaria", debes lembrar que nos sistemas de ficheiros ext2,3 e 4 hai algo como "Reconto de bloques reservados". Se miras a lista anterior, temos "13094" tales bloques. Estes son bloques escribibles só polo usuario root. pero se precisas resolver rapidamente o problema, como solución temporal podes poñelos a disposición de todos, obtendo un espazo libre:

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

Eses. por defecto, tes un 5% do espazo no disco non dispoñible para escribir e, dado o volume dos discos modernos, este pode ser de centos de gigabytes.

Que máis podería ser? Tamén é posible que haxa bloques libres, pero non haxa máis nodos. Isto adoita ocorrer se tes un montón de ficheiros no teu sistema de ficheiros que son máis pequenos que o tamaño do bloque do sistema de ficheiros. Tendo en conta que 1 inodo se gasta en 1 ficheiro ou directorio, e en total temos (para un determinado sistema de ficheiros) 65536 - a situación é máis que realista. Isto pódese ver claramente desde a saída do 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

Como é claramente visible na partición /var/www, o número de bloques libres no sistema de ficheiros e o número de nós libres varían moito.

No caso de que te quedes sen inodos, non che direi ningún feitizo, porque... non hai ningunha (se me equivoco, avisame). Polo tanto, para particións nas que se multiplican ficheiros pequenos, debes escoller o sistema de ficheiros con coidado. Por exemplo, os inodos btrfs non poden rematar, porque Os novos créanse dinámicamente se é necesario.

Fonte: www.habr.com

Engadir un comentario