Saltar al contenido

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.

CapaQué contiene
Espacio de usuarioAplicaciones y librerías del sistema, entre ellas la librería C
Interfaz de llamadas al sistemaLa frontera: aquí se cambia a modo núcleo. Es la capa POSIX
Subsistemas del núcleoEntrada y salida, memoria, procesos, red y sistema de ficheros virtual
Controladores y módulosEl código que habla con cada dispositivo concreto
HardwareProcesador, 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.

bash
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 marcha

Monolí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-nodoQué guarda
Número de i-nodoEl identificador, único dentro de la partición
Tipo de ficheroOrdinario, directorio, enlace, dispositivo, socket o tubería
PermisosLos tres tríos de lectura, escritura y ejecución, y los bits especiales
UID y GIDPropietario y grupo propietario
TamañoEn bytes
Tres marcas de tiempoAcceso, modificación y cambio
Contador de enlaces durosCuántos nombres apuntan a este i-nodo
Punteros a bloquesDó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.

bash
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-nodo

El 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 punteroA dónde lleva
DirectoDirectamente a un bloque de datos
Indexación simpleA un bloque lleno de punteros a bloques de datos
Indexación dobleA un bloque de punteros a bloques de punteros
Indexación tripleUn 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.

bash
df -h    # espacio libre en bloques
df -i    # i-nodos libres: la otra mitad de la respuesta

Si 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.

CapaQué esDe qué se compone
Volumen físicoUn disco o una partición entregada a LVMSe divide en extents físicos
Grupo de volúmenesEl almacén común formado por varios volúmenes físicosSuma de todos sus extents
Volumen lógicoEl trozo que se formatea y se montaSe 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ónVolumen físicoGrupoVolumen lógico
Crearpvcreatevgcreatelvcreate
Consultarpvdisplayvgdisplaylvdisplay
AmpliarNo aplicavgextendlvextend
Reducirpvmovevgreducelvreduce

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.

bash
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/contenido

Ampliar 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.

bash
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 montaje

La 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.

bash
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_contenido

Ampliar 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