Periódicamente, con el fin de mudarme al CRS, me entrevisto en diferentes grandes empresas, principalmente de San Petersburgo y Moscú, para el puesto de DevOps. He notado que en muchas compañías (en muchas buenas empresas, como Yandex) se hacen dos preguntas similares:
- ¿Qué es un inode?
- ¿Por qué se puede obtener un error al escribir en el disco (o, por ejemplo: ¿por qué puede terminarse el 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 empecé a explicar, comenzaron a aparecer lagunas en mi conocimiento. Para sistematizar mis conocimientos, llenar los vacíos y no avergonzarme más, escribo este artículo, tal vez le sirva a alguien más.
Comenzaré "desde abajo", es decir, desde el disco duro (ignoraremos unidades flash, SSD y otras cosas modernas; tomemos como ejemplo cualquier disco viejo de 20 o 80 GB, ya que allí el tamaño del bloque es de 512 bytes).
El disco duro no puede dirigirse a su espacio byte por byte; en términos generales, está dividido en bloques. La numeración de los bloques comienza desde 0. (esto se llama LBA, los detalles aquí: )

Como se puede ver en la imagen, los bloques LBA los he etiquetado como el nivel HDD. Por cierto, para ver cuál es el tamaño del bloque de su disco, puede hacerlo así:
root@ubuntu:/home/serp# blockdev --getpbsz /dev/sdb
512El nivel superior está marcado como partición, una para todo el disco (de nuevo, por simplicidad). La mayoría de las veces se usan dos tipos de particiones: msdos y gpt. Por lo tanto, msdos es el formato antiguo, que admite discos de hasta 2Tb, gpt es el nuevo formato que puede dirigir hasta 1 zettabyte de bloques de 512 bytes. En nuestro caso, tenemos una partición del tipo msdos, como se puede ver en la imagen, la partición comienza en el bloque №1, el bloque cero se utiliza para el MBR.
En la primera partición, creé un sistema de archivos ext2, cuyo tamaño de bloque por defecto es de 4096 bytes, lo cual también se refleja en la imagen. Para ver el tamaño del bloque del sistema de archivos, puede hacerlo así:
root@ubuntu:/home/serp# tune2fs -l /dev/sdb1
tune2fs 1.42.9 (4-feb-2014)
Nombre del volumen del sistema de archivos:
Último montado en:
UUID del sistema de archivos: a600bf40-f660-41f6-a3e6-96c303995479
Número mágico del sistema de archivos: 0xEF53
Revisión del sistema de archivos #: 1 (dinámico)
Características del sistema de archivos: ext_attr resize_inode dir_index filetype sparse_super large_file
Banderas del sistema de archivos: signed_directory_hash
Opciones de montaje predeterminadas: user_xattr acl
Estado del sistema de archivos: limpio
Comportamiento ante errores: Continuar
Tipo de sistema operativo del sistema de archivos: Linux
Cantidad de inodos: 65536
Cantidad de bloques: 261888
Cantidad de bloques reservados: 13094
Bloques libres: 257445
Inodes libres: 65525
Primer bloque: 0
Tamaño del bloque: 4096
Tamaño del fragmento: 4096
Bloques GDT reservados: 63
Bloques por grupo: 32768
Fragmentos por grupo: 32768
Inodes por grupo: 8192
Bloques de inodes por grupo: 512
Sistema de archivos creado: Vie Ago 2 15:02:13 2019
Última vez montado: n/a
Última vez escrito: Vie Ago 2 15:02:14 2019
Cantidad de montajes: 0
Máxima cantidad de montajes: -1
Última verificación: Vie Ago 2 15:02:13 2019
Intervalo de verificación: 0 ()
UID de bloques reservados: 0 (usuario root)
GID de bloques reservados: 0 (grupo root)
Primer inode: 11
Tamaño de inode: 256
Tamaño extra requerido: 28
Tamaño extra deseado: 28
Hash de directorio predeterminado: half_md4
Semilla del hash de directorio: c0155456-ad7d-421f-afd1-c898746ccd76El parámetro que necesitamos es "Tamaño del bloque".
Ahora lo interesante, ¿cómo leer el archivo /home/serp/testfile? El archivo consta de uno o varios bloques del sistema de archivos, donde se almacenan sus datos. Sabiendo el nombre del archivo, ¿cómo encontrarlo? ¿Qué bloques leer?
Aquí es donde nos resultan útiles los inodes. En el sistema de archivos ext2fs hay una "tabla" que contiene información sobre todos los inodes. La cantidad de inodes en el caso de ext2fs se establece al crear el sistema de archivos. Los números necesarios se observan en el parámetro "Cantidad de inodos" de la salida de tune2fs, es decir, tenemos 65536. En el inode se almacena la información que necesitamos: la lista de bloques del sistema de archivos para el archivo buscado. ¿Cómo encontrar el número de inode para el archivo especificado?
La correspondencia entre el nombre y el número de inode se encuentra en el directorio, y un directorio en ext2fs es un archivo de tipo especial, es decir, también tiene su propio número de inode. Para romper este círculo vicioso, se asignó un número de inode "fijo" de 2 a el directorio raíz. Veamos el contenido del inode número 2:
root@ubuntu:/# debugfs /dev/sdb1
debugfs 1.42.9 (4-feb-2014)
debugfs: stat
Inode: 2 Tipo: directorio Modo: 0755 Banderas: 0x0
Generación: 0 Versión: 0x00000000:00000002
Usuario: 0 Grupo: 0 Tamaño: 4096
ACL de archivo: 0 ACL de directorio: 0
Enlaces: 3 Conteo de bloques: 8
Fragmento: Dirección: 0 Número: 0 Tamaño: 0
ctime: 0x5d43cb51:16b61bcc -- Vie Ago 2 16:34:09 2019
atime: 0x5d43c247:b704301c -- Vie Ago 2 15:55:35 2019
mtime: 0x5d43cb51:16b61bcc -- Vie Ago 2 16:34:09 2019
crtime: 0x5d43b5c6:00000000 -- Vie Ago 2 15:02:14 2019
Tamaño de campos extras de inode: 28
BLOQUES:
(0):579
TOTAL: 1Como se puede ver, el directorio que necesitamos se encuentra en el bloque número 579. Allí encontraremos el número del nodo para la carpeta home, y así sucesivamente en la cadena, hasta que en el directorio serp veamos el número del nodo para el archivo solicitado. Si alguien quisiera verificar si el número es correcto y si allí hay información necesaria, no es complicado. Hacemos:
root@ubuntu:~# dd if=/dev/sdb1 of=/home/serp/dd_image bs=4096 count=1 skip=579
1+0 registros en
1+0 registros fuera
4096 bytes (4,1 kB) copiados, 0,000184088 s, 22,3 MB/s
root@ubuntu:~# hexdump -c /home/serp/dd_imageEn la salida se pueden leer los nombres de los archivos en el directorio.
Aquí estoy, llegando a la pregunta principal: "¿por qué puede ocurrir un error de escritura"?
Naturalmente, esto sucederá si no quedan bloques libres en el sistema de archivos. ¿Qué se puede hacer en este caso? Además de la obvia idea de "eliminar algo innecesario", hay que recordar que en los sistemas de archivos ext2, 3 y 4 hay algo llamado "Reserved block count". Si miramos el listado anterior, tenemos esos bloques "13094". Estos bloques son accesibles para escritura solo para el usuario root. Pero si es necesario resolver el problema rápidamente, como solución temporal se pueden hacer accesibles para todos, lo que resultará en un poco de espacio libre:
root@ubuntu:/mnt# tune2fs -m 0 /dev/sdb1
tune2fs 1.42.9 (4-Feb-2014)
Estableciendo el porcentaje de bloques reservados a 0% (0 bloques)Es decir, por defecto, no tiene disponible para escritura el 5% del espacio en disco, y considerando el tamaño de los discos modernos, esto puede ser cientos de gigabytes.
¿Qué más puede haber? También puede suceder que haya bloques libres, pero se hayan acabado los nodos. Esto ocurre generalmente si tienes en el sistema de archivos un montón de archivos de tamaño menor al tamaño del bloque del sistema de archivos. Considerando que se gasta 1 inode por archivo o directorio, y que en total tenemos (para este sistema de archivos) 65536 — la situación es más que real. Esto se puede ver claramente en la salida 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\/wwwComo se puede ver claramente en la sección \/var\/www, la cantidad de bloques libres del sistema de archivos y la cantidad de nodos libres difieren considerablemente.
En caso de que se agoten los inode, no puedo sugerir conjuros, ya que no hay (si me equivoco, házmelo saber). Por lo tanto, para las secciones donde se generan muchos archivos pequeños, es importante elegir el sistema de archivos adecuadamente. Por ejemplo, en btrfs, los inode no pueden agotarse, ya que se crean dinámicamente cuando es necesario.
Fuente: habr.com
