Linux: ficheros y LVM
Cómo está organizado por dentro el núcleo que se administra, qué es exactamente la capa que unifica todo el almacenamiento, qué guarda un i-nodo y cómo llega a los datos, y cómo se monta un almacenamiento que se pueda ampliar sin parar la máquina.
La arquitectura del núcleo y los módulos
El núcleo de Linux es monolítico: todos sus subsistemas comparten el mismo espacio de memoria y se llaman entre ellos sin cambiar de contexto, lo que lo hace rápido a costa de que un fallo en cualquier parte se lleve el sistema entero. Pero es un monolítico modular, y ese matiz es la clave de su administración.
El sistema se reparte en dos espacios que no se mezclan. Arriba, el espacio de usuario, donde corren las aplicaciones y las librerías del sistema, la principal de ellas la librería C. Abajo, el espacio de núcleo, donde están los subsistemas y los controladores. Entre los dos hay una única puerta: la interfaz de llamadas al sistema.
| Capa | Qué contiene |
|---|---|
| Espacio de usuario | Aplicaciones y librerías del sistema, entre ellas la librería C |
| Interfaz de llamadas al sistema | La frontera: aquí se cambia a modo núcleo. Es la capa POSIX |
| Subsistemas del núcleo | Entrada y salida, memoria, procesos, red y sistema de ficheros virtual |
| Controladores y módulos | El código que habla con cada dispositivo concreto |
| Hardware | Procesador, memoria y periféricos |
Que la interfaz de llamadas al sistema sea POSIX es lo que explica que un programa escrito para un UNIX se recompile en Linux con pocos cambios: no es el mismo código el que hay debajo, pero sí el mismo contrato. En la arquitectura de treinta y dos bits, el paso a modo núcleo se hacía con una interrupción software, la 80 hexadecimal, que es el detalle que suele citarse.
Los subsistemas del núcleo son los sospechosos habituales: entrada y salida, gestión de memoria con memoria virtual y paginación, gestión de procesos con señales, hilos y planificador, terminales, sockets y el sistema de ficheros virtual. Y por encima de todos ellos, los módulos cargables.
Un módulo es un trozo de núcleo que se carga y se descarga con la máquina en marcha, normalmente un controlador. Gracias a ellos no hace falta recompilar el núcleo ni reiniciar para dar soporte a un dispositivo nuevo, que es exactamente lo que se necesita en un servidor en producción.
lsmod # módulos cargados ahora mismo
modprobe nombre # cargar un módulo con sus dependencias
modprobe -r nombre # descargarlo
uname -r # versión del núcleo en marchaMonolítico pero modular: la ventaja de rendimiento del monolítico con la flexibilidad de poder añadir y quitar controladores sin reiniciar.
Para el examen
Qué tipo de núcleo es Linux: monolítico pero MODULAR
Qué gana con ello: rendimiento de monolítico y controladores cargables sin reiniciar
El sistema de ficheros virtual
El sistema de ficheros virtual es la capa del núcleo que presenta a los procesos una única forma de trabajar con ficheros, sea cual sea el sistema de ficheros real que hay debajo. Un programa abre, lee y cierra, y nunca sabe si al otro lado hay un ext4, un sistema de ficheros de Windows en un pendrive o un directorio compartido por red.
Funciona como una capa de despacho. Cuando el proceso pide leer, el sistema de ficheros virtual mira qué sistema real corresponde a ese punto del árbol y llama a la función concreta de ese sistema. La relación es la misma que hay entre una aplicación y un controlador: el que llama trabaja siempre contra la misma interfaz.
Esa pieza es la que hace posible el rasgo más característico de Linux frente a Windows: que todo cuelgue de un único árbol de directorios en vez de tener una letra por volumen. Añadir un disco no crea un espacio de nombres nuevo, lo injerta en el que ya hay.
Tiene además una consecuencia que se pregunta: permite que existan sistemas de ficheros que no están en ningún disco. Los ficheros de /proc no ocupan espacio: se fabrican en memoria en el momento de leerlos, y lo que devuelven es el estado interno del núcleo traducido a texto.
El sistema de ficheros virtual no guarda datos: traduce una interfaz única a la implementación de cada sistema de ficheros. Por eso un mismo programa funciona sobre ext4, sobre un recurso de red o sobre /proc.
Para el examen
Qué hace el VFS: traduce una interfaz única a cada sistema de ficheros
Lo que NO hace: guardar datos
Su consecuencia: el mismo programa funciona sobre ext4, un recurso de red o /proc
Qué guarda un i-nodo
El i-nodo es la ficha de un fichero. Hay uno por fichero y lleva todo lo que el sistema sabe de él menos una cosa: el nombre, que vive en el directorio. Conocer su contenido es lo que permite entender por qué ciertas operaciones cambian unas fechas y no otras.
| Campo del i-nodo | Qué guarda |
|---|---|
| Número de i-nodo | El identificador, único dentro de la partición |
| Tipo de fichero | Ordinario, directorio, enlace, dispositivo, socket o tubería |
| Permisos | Los tres tríos de lectura, escritura y ejecución, y los bits especiales |
| UID y GID | Propietario y grupo propietario |
| Tamaño | En bytes |
| Tres marcas de tiempo | Acceso, modificación y cambio |
| Contador de enlaces duros | Cuántos nombres apuntan a este i-nodo |
| Punteros a bloques | Dónde están los datos: directos e indexados |
Las tres fechas se confunden siempre y la diferencia es fina. La de acceso cambia al leer. La de modificación cambia cuando cambia el contenido. Y la de cambio no es la de creación: registra cuándo se tocó un metadato, es decir los permisos, el propietario o el propio contador de enlaces.
De ahí sale una consecuencia que se pregunta: al modificar el contenido cambian las dos, la de modificación y la de cambio, porque el tamaño y los punteros son metadatos y también se actualizan. Al cambiar solo los permisos cambia únicamente la de cambio.
stat informe.txt # el i-nodo completo, en formato legible
ls -li informe.txt # el número de i-nodo y el contador de enlaces
find /var -inum 918273 # localizar todos los nombres de un i-nodoEl contador de enlaces explica por qué borrar no siempre borra. Cada nombre que apunta al i-nodo suma uno; al eliminar un nombre, el contador baja. Solo cuando llega a cero se libera el i-nodo y sus bloques. Por eso un fichero con varios enlaces duros sigue ahí después de borrar uno de sus nombres.
La tercera fecha del i-nodo no es la de creación, es la de cambio de metadatos. Los sistemas de ficheros de Unix clásicos no guardan fecha de creación, aunque algunos modernos sí la añaden.
Para el examen
Las tres fechas: acceso, modificación y cambio de metadatos
La tercera NO es: la de creación
Por qué: los sistemas Unix clásicos no guardan fecha de creación
Cómo llega el i-nodo a los datos: la indexación
Un i-nodo tiene tamaño fijo, así que no puede guardar una lista ilimitada de bloques. El esquema clásico resuelve el problema en escalones: unos cuantos punteros van directamente al dato y los últimos apuntan a bloques que solo contienen más punteros.
| Tipo de puntero | A dónde lleva |
|---|---|
| Directo | Directamente a un bloque de datos |
| Indexación simple | A un bloque lleno de punteros a bloques de datos |
| Indexación doble | A un bloque de punteros a bloques de punteros |
| Indexación triple | Un escalón más, para los ficheros muy grandes |
El diseño está pensado para el caso real: la inmensa mayoría de los ficheros son pequeños y se resuelven con los punteros directos, en un solo acceso. Los ficheros enormes pagan accesos adicionales, pero son pocos. Es un compromiso entre el tamaño del i-nodo y el coste de llegar al dato.
De este esquema sale un efecto que sorprende al administrador novato: una partición puede quedarse sin espacio aunque sobren gigabytes. Los i-nodos se reservan al formatear y son un número finito; millones de ficheros diminutos los agotan antes que a los bloques, y el sistema empieza a dar error de disco lleno.
df -h # espacio libre en bloques
df -i # i-nodos libres: la otra mitad de la respuestaSi df -h dice que hay sitio y aun así no se puede crear un fichero, el siguiente comando es df -i. Se han agotado los i-nodos, no el espacio.
Para el examen
Si df -h dice que hay sitio y no se puede crear un fichero: df -i
Qué se ha agotado: los i-nodos, no el espacio
LVM: las tres capas
Con particiones normales, un sistema de ficheros está atado al trozo de disco donde se creó, y ampliarlo significa mover particiones vecinas o reinstalar. El gestor de volúmenes lógicos rompe esa atadura metiendo una capa intermedia entre el disco y el sistema de ficheros.
| Capa | Qué es | De qué se compone |
|---|---|---|
| Volumen físico | Un disco o una partición entregada a LVM | Se divide en extents físicos |
| Grupo de volúmenes | El almacén común formado por varios volúmenes físicos | Suma de todos sus extents |
| Volumen lógico | El trozo que se formatea y se monta | Se divide en extents lógicos |
La unidad de reparto es el extent, un trozo de tamaño fijo. LVM mantiene una tabla de correspondencias entre los extents lógicos de cada volumen y los extents físicos donde caen de verdad, y esa tabla es la que permite lo importante: un volumen lógico no tiene por qué ser contiguo ni estar en un solo disco.
De ahí sale toda la flexibilidad. Ampliar un volumen lógico es pedirle más extents al grupo; ampliar el grupo es meterle otro disco. Nada de eso obliga a mover datos ni a parar el sistema, que es la razón por la que en un servidor se monta LVM casi siempre.
Un aviso de vocabulario: no es raro leer que LVM es lo mismo que los discos dinámicos. No lo es. Los discos dinámicos son la tecnología equivalente de Windows, con sus propias reglas. Son análogos en propósito, no el mismo producto.
Debajo de los volúmenes físicos puede haber discos sueltos o un conjunto RAID montado por software, que en Linux se administra con mdadm. Las dos capas se combinan: el RAID aporta tolerancia a fallos y LVM aporta flexibilidad de reparto.
El orden de las capas de abajo arriba es volumen físico, grupo de volúmenes y volumen lógico. Los extents son la moneda con la que el grupo paga a sus volúmenes lógicos.
Las capas de LVM, de abajo arriba
PV · volumen físico
- El disco o la partición real, marcada para que LVM la use
VG · grupo de volúmenes
- La bolsa común que suman uno o varios PV
- Se reparte en extents, la unidad de asignación
LV · volumen lógico
- El trozo que se saca del VG y se formatea
- Es lo que el sistema monta: crece y mengua sin tocar el disco
Para el examen
PV: volumen físico: el disco o la partición real
VG: grupo de volúmenes: la bolsa común
LV: volumen lógico: el trozo que se formatea y se monta
Extents: la unidad de reparto dentro del grupo
LVM en la práctica: crear, ampliar y fotografiar
Los comandos de LVM siguen un patrón que se aprende de una vez: dos letras de capa y detrás el verbo. pv para volúmenes físicos, vg para grupos y lv para volúmenes lógicos.
| Acción | Volumen físico | Grupo | Volumen lógico |
|---|---|---|---|
| Crear | pvcreate | vgcreate | lvcreate |
| Consultar | pvdisplay | vgdisplay | lvdisplay |
| Ampliar | No aplica | vgextend | lvextend |
| Reducir | pvmove | vgreduce | lvreduce |
Montar un almacenamiento nuevo son cinco pasos, y los dos últimos son los de siempre: un volumen lógico no se puede usar hasta que tiene un sistema de ficheros encima y está montado en algún punto del árbol.
pvcreate /dev/sdb /dev/sdc
vgcreate vg_temario /dev/sdb /dev/sdc
lvcreate -L 200G -n lv_contenido vg_temario
mkfs.ext4 /dev/vg_temario/lv_contenido
mount /dev/vg_temario/lv_contenido /srv/contenidoAmpliar en caliente es el motivo por el que existe LVM, y son dos pasos, no tres. Primero se agranda el volumen lógico y después se le dice al sistema de ficheros que ocupe el espacio nuevo. Volver a formatear con mkfs en este punto es un error grave: destruiría todo lo que hay dentro.
vgextend vg_temario /dev/sdd # meter otro disco al grupo
lvextend -L +100G /dev/vg_temario/lv_contenido
resize2fs /dev/vg_temario/lv_contenido # ext2, ext3 y ext4
# en xfs el equivalente es xfs_growfs sobre el punto de montajeLa otra gran razón para usar LVM son las instantáneas. Una instantánea es un volumen lógico especial que congela el estado de otro en un momento dado sin duplicar los datos: solo guarda los bloques que cambian a partir de ese instante. Es lo que permite hacer una copia coherente de una base de datos sin pararla.
lvcreate -s -L 20G -n snap_contenido /dev/vg_temario/lv_contenido
# copiar tranquilamente desde la instantánea y después retirarla
lvremove /dev/vg_temario/snap_contenidoAmpliar es lvextend y después resize2fs. Nunca mkfs: eso formatea de nuevo el volumen y se lleva por delante los datos.
Para el examen
Ampliar un volumen: lvextend y después resize2fs
Lo que nunca se hace: mkfs: vuelve a formatear y se lleva los datos