Algo sobre el inodo

Periódicamente, para trasladarme al Centro de Distribución Central, me entrevisto en varias grandes empresas, principalmente en San Petersburgo y Moscú, para un puesto de DevOps. Noté que muchas empresas (muchas buenas empresas, por ejemplo Yandex) hacen dos preguntas similares:

  • qué es el inodo;
  • ¿Por qué motivos puede aparecer un error de escritura en el disco (o, por ejemplo: por qué es posible que se quede sin espacio en el disco? La esencia es la misma).

Como suele suceder, estaba seguro de que conocía bien este tema, pero tan pronto como comencé a explicarlo, se hicieron evidentes lagunas en el conocimiento. Para sistematizar mis conocimientos, llenar los vacíos y no avergonzarme más, estoy escribiendo este artículo, tal vez le resulte útil a alguien más.

Empezaré desde abajo, es decir. desde un disco duro (descartaremos unidades flash, SSD y otras cosas modernas; por ejemplo, consideremos cualquier disco antiguo de 20 u 80 gigas, ya que el tamaño del bloque es de 512 bytes).

El disco duro no sabe cómo dirigirse a su espacio byte a byte, está dividido condicionalmente en bloques. La numeración de bloques comienza desde 0. (Esto se llama LBA, detalles aquí: ru.wikipedia.org/wiki/LBA)

Algo sobre el inodo

Como puede verse en la figura, designé los bloques LBA como nivel de HDD. Por cierto, puedes ver qué tamaño de bloque tiene tu disco así:

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

El nivel superior es una partición, una para todo el disco (nuevamente por simplicidad). Muy a menudo, se utilizan dos tipos de marcado de partición: msdos y gpt. En consecuencia, msdos es un formato antiguo que admite discos de hasta 2 TB, gpt es un formato nuevo capaz de direccionar hasta 1 zettabyte de bloques de 512 bytes. En nuestro caso tenemos una partición de tipo msdos, como se puede ver en la figura, la partición comienza con el bloque No. 1, mientras que para el MBR se utiliza el cero.

En la primera partición creé un sistema de archivos ext2, su tamaño de bloque predeterminado es 4096 bytes, lo que también se refleja en la figura. Puede ver el tamaño del bloque del sistema de archivos de esta manera:

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

El parámetro que necesitamos es "Tamaño de bloque".

Ahora la parte interesante es ¿cómo leer el archivo /home/serp/testfile? Un archivo consta de uno o más bloques del sistema de archivos en los que se almacenan sus datos. Conociendo el nombre del archivo, ¿cómo encontrarlo? ¿Qué bloques debo leer?

Aquí es donde los inodos resultan útiles. El sistema de archivos ext2fs tiene una "tabla" que contiene información para todos los inodos. El número de inodos en el caso de ext2fs se establece al crear el sistema de archivos. Observamos los números requeridos en el parámetro "Recuento de inodos" de la salida de tune2fs, es decir Disponemos de 65536 piezas. El inodo contiene la información que necesitamos: una lista de bloques del sistema de archivos para el archivo que estamos buscando. ¿Cómo encontrar el número de inodo para un archivo determinado?

El nombre correspondiente y el número de inodo están contenidos en el directorio, y un directorio en ext2fs es un tipo especial de archivo, es decir. también tiene su propio número de inodo. Para romper este círculo vicioso, se asignó un número de inodo “fijo” “2” al directorio raíz. Veamos el contenido del 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 puede ver, el directorio que necesitamos está contenido en el bloque número 579. En él encontraremos el número de nodo de la carpeta de inicio, y así sucesivamente hasta que en el directorio serp veamos el número de nodo del archivo solicitado. Si de repente alguien quiere comprobar si el número es correcto y si contiene la información necesaria, no es difícil. Hacemos:

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

En el resultado puede leer los nombres de los archivos en el directorio.

Llego entonces a la pregunta principal: “¿por qué motivos puede producirse un error de grabación?”

Naturalmente, esto sucederá si no quedan bloques libres en el sistema de archivos. ¿Qué se puede hacer en este caso? Además del obvio "eliminar todo lo innecesario", debe recordar que en los sistemas de archivos ext2,3, 4 y 13094 existe el "recuento de bloques reservados". Si observa la lista anterior, tenemos “XNUMX” de dichos bloques. Estos son bloques en los que sólo el usuario root puede escribir. pero si necesita resolver rápidamente el problema, como solución temporal puede ponerlos a disposición de todos, lo que resultará en algo de espacio libre:

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

Aquellos. De forma predeterminada, tiene el 5% del espacio en disco no disponible para escribir y, dado el volumen de los discos modernos, esto puede ser cientos de gigabytes.

¿Qué más podría ser? También es posible que queden bloques libres, pero no haya más nodos. Esto suele suceder si tiene varios archivos en su sistema de archivos que son más pequeños que el tamaño del bloque del sistema de archivos. Teniendo en cuenta que se gasta 1 inodo en 1 archivo o directorio, y en total tenemos (para un sistema de archivos determinado) 65536, la situación es más que realista. Esto se puede ver claramente en el resultado 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

Como se ve claramente en la partición /var/www, la cantidad de bloques libres en el sistema de archivos y la cantidad de nodos libres varían mucho.

En caso de que te quedes sin inodos, no te contaré ningún hechizo, porque... no hay ninguno (si me equivoco, házmelo saber). Entonces, para particiones en las que se multiplican archivos pequeños, debe elegir sabiamente el sistema de archivos. Por ejemplo, los inodos btrfs no pueden terminar, porque Los nuevos se crean dinámicamente si es necesario.

Fuente: habr.com

Añadir un comentario