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