Terminamos la lección anterior señalando una costura que llevamos ignorando todo el módulo. Cuando recorremos /var/lib/meteora/lecturas/2026-08-31.dat componente a componente, damos por hecho que el árbol es una cosa homogénea. No lo es. / es un ext4 sobre una partición del primer NVMe; /var/lib/meteora es otro ext4, sobre el RAID 1 /dev/md0; /run es tmpfs y vive en la RAM; /proc no tiene ningún dispositivo detrás y sus ficheros se inventan en el momento de leerlos. Cuatro sistemas de archivos radicalmente distintos, con estructuras internas incompatibles, y sin embargo la resolución de rutas camina de uno a otro sin enterarse.
Esta lección explica cómo se consigue eso, y lo hace en dos mitades que se complementan. La primera es de administración: cómo se trocea un dispositivo de bloques en particiones, cómo LVM añade una capa de flexibilidad encima, cómo se crea un sistema de archivos y —la operación central— qué ocurre exactamente al ejecutar mount, con /etc/fstab campo a campo y las opciones que protegen de verdad. La segunda es de arquitectura: el Sistema de Archivos Virtual (VFS), la capa de indirección del núcleo que hace que el mismo open() funcione sobre un SSD, sobre la RAM y sobre un servidor al otro lado de la red.
Al terminar sabrás particionar y montar un servidor con criterio, entender por qué separar /var de / no es manía sino prevención, resolver el "target is busy" que todo el mundo sufre, y explicar con precisión por qué /proc/cpuinfo se comporta como un fichero sin serlo.
Contenido
- Del dispositivo de bloques a la partición: MBR y GPT
- Esquema de particionado de un servidor y por qué separar
/var - Ver lo que hay:
lsblk,fdisk -lyblkid - LVM: volúmenes físicos, grupos de volúmenes y volúmenes lógicos
- Instantáneas de LVM para copiar
/var/lib/meteoraen caliente - Crear el sistema de archivos con
mkfs - El montaje: qué ocurre exactamente al ejecutar
mount - Identificación estable: UUID, etiquetas y
/etc/fstabcampo a campo - Opciones de montaje y qué protege cada una
- Desmontar, "target is busy" y cómo resolverlo
- Montajes bind y espacios de nombres de montaje
- El Sistema de Archivos Virtual (VFS) y sus cuatro objetos
- Sistemas de archivos virtuales y en memoria
- Sistemas de archivos en red: NFS y SMB
Del dispositivo de bloques a la partición: MBR y GPT
En el módulo 2 dejamos el disco como un vector de bloques direccionables por LBA. Una partición es simplemente un rango contiguo de ese vector declarado como una unidad independiente: "del LBA 2048 al 1050623, esto es una cosa". Nada más. La partición no impone formato ni contenido; solo delimita.
¿Por qué particionar en lugar de usar el disco entero? Por cuatro razones que siguen siendo válidas: aislar el llenado (si /var/log se desborda, no debe impedir que puedas iniciar sesión), aplicar políticas distintas de montaje a cada zona, usar sistemas de archivos distintos según la carga (04-01), y satisfacer los requisitos de arranque (la UEFI exige una partición FAT32; el cifrado de disco necesita /boot sin cifrar).
La tabla de particiones vive en los primeros sectores del disco, y hay dos formatos. MBR (Master Boot Record), de 1983, ocupa los primeros 512 bytes: 446 para el código de arranque, 64 para la tabla —4 entradas de 16 bytes— y 2 para la firma 0x55AA. GPT (GUID Partition Table), parte de UEFI, usa una cabecera en el LBA 1 y un array de entradas de 128 bytes, con una copia completa al final del disco.
| MBR | GPT | |
|---|---|---|
| Año | 1983 | 1998 |
| Tamaño máximo de disco | 2 TiB (LBA de 32 bits × 512 B) | 8 ZiB |
| Particiones primarias | 4 | 128 (por defecto en Linux) |
| Particiones extendidas | Necesarias para pasar de 4 | No existen: todas son iguales |
| Redundancia de la tabla | Ninguna | Copia al final del disco |
| Suma de verificación | No | CRC32 de cabecera y entradas |
| Identificación | Número de partición | GUID único por partición y por disco |
| Etiquetas de partición | No | Sí, 36 caracteres |
| Tipo de partición | 1 byte (83, 82, 8e...) |
GUID de 16 bytes |
| Arranque | BIOS heredada | UEFI (y BIOS con bios_grub) |
| Protección heredada | — | MBR protector en el LBA 0 |
Tres diferencias importan de verdad. El límite de 2 TiB de MBR es infranqueable: inicio y tamaño se guardan en 32 bits de sectores de 512 bytes, y 2³² × 512 = 2 TiB, así que cualquier disco de 4 u 8 TB exige GPT. La redundancia: en MBR, corromper 512 bytes destruye la tabla y el acceso a todo; GPT guarda una copia íntegra al final y verifica ambas con CRC32, de modo que gdisk reconstruye una a partir de la otra —la diferencia entre "he perdido el disco" y "he tardado un minuto"—. Y el MBR protector: GPT escribe en el LBA 0 un MBR falso con una partición de tipo 0xEE que cubre todo el disco, para que una herramienta antigua lo vea como ocupado y no lo formatee alegremente.
Regla actual: usa GPT siempre, salvo que necesites arrancar una BIOS heredada muy antigua.
Esquema de particionado de un servidor y por qué separar /var
Este es el esquema real de meteo-01, con dos NVMe de 512 GB en RAID 1 (02-05) más el volumen de datos:
| Partición | Tamaño | Tipo | Punto de montaje | Sistema de archivos |
|---|---|---|---|---|
/dev/nvme0n1p1 |
512 MiB | EFI System | /boot/efi |
FAT32 |
/dev/nvme0n1p2 |
1 GiB | Linux | /boot |
ext4 |
/dev/nvme0n1p3 |
40 GiB | Linux | / |
ext4 |
/dev/nvme0n1p4 |
20 GiB | Linux | /var |
ext4 |
/dev/nvme0n1p5 |
8 GiB | Linux swap | — | swap |
/dev/md0 |
196 GiB | RAID 1 | /var/lib/meteora |
ext4 (noatime) |
Y ahora la justificación, que es lo que importa. Separar /var de / no es un ritual heredado: previene un modo de fallo concreto y frecuente.
/var contiene todo lo que crece sin control: logs, colas de correo, cachés, bases de datos, imágenes de contenedores. Si comparte partición con / y un log se desboca, ningún proceso puede crear temporales, systemd no puede escribir su estado, sudo puede fallar al no poder registrar, la shell no guarda historial ni ficheros de bloqueo, y —lo grave— no puedes iniciar sesión, porque tu perfil necesita escribir.
Esa última consecuencia es todo el argumento: un / lleno es un servidor que no te deja entrar a arreglarlo. Con /var separado, un log desbocado llena /var, fallan los servicios de esa partición, y / conserva espacio para que puedas conectarte, diagnosticar y borrar. Es también la razón del -m 5 que ext4 reserva por defecto para root (04-01) y de que en / no debas bajarlo.
El mismo razonamiento, aplicado al resto: /boot mantiene el núcleo accesible aunque / esté cifrado o dañado; /home impide que un usuario llene el sistema y permite reinstalar sin perder datos; /tmp montado noexec,nosuid corta muchos exploits; y /var/lib/meteora aísla datos irrecuperables en su propio RAID, con su propio mkfs y su noatime.
El contraargumento honesto: las particiones fijas desperdician espacio —/ con 30 GiB libres no ayuda a /var lleno— y son difíciles de redimensionar. Esa es exactamente la carencia que LVM viene a resolver.
Ver lo que hay: lsblk, fdisk -l y blkid
Tres herramientas, tres puntos de vista. Nunca formatees ni particiones sin haber mirado las tres.
lsblk muestra el árbol de dispositivos de bloques: qué contiene qué.
$ lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT NAME SIZE TYPE FSTYPE MOUNTPOINT nvme0n1 476,9G disk ├─nvme0n1p1 512M part vfat /boot/efi ├─nvme0n1p3 40G part ext4 / ├─nvme0n1p4 20G part ext4 /var └─nvme0n1p6 196G part linux_raid_member └─md0 196G raid1 ext4 /var/lib/meteora nvme1n1 476,9G disk └─nvme1n1p1 196G part linux_raid_member └─md0 196G raid1 ext4 /var/lib/meteora
Lo valioso es la jerarquía: se ve que md0 está formado por dos particiones de discos distintos y que es él, y no ellas, quien lleva el ext4. TYPE distingue disk, part, raid1, lvm y crypt. Y un campo vacío en MOUNTPOINT significa que no está montado, que es lo primero que hay que comprobar antes de tocar nada.
fdisk -l entra en la tabla de particiones:
$ sudo fdisk -l /dev/nvme0n1 Disco /dev/nvme0n1: 476,94 GiB, 512110190592 bytes, 1000215216 sectores Tamaño de sector (lógico/físico): 512 bytes / 512 bytes Tipo de etiqueta de disco: gpt Dispositivo Comienzo Final Sectores Tamaño Tipo /dev/nvme0n1p1 2048 1050623 1048576 512M Sistema EFI /dev/nvme0n1p2 1050624 3147775 2097152 1G Sistema de ficheros de Linux /dev/nvme0n1p3 3147776 87033855 83886080 40G Sistema de ficheros de Linux
Lo que aporta y lsblk no: Tipo de etiqueta de disco: gpt (confirma el formato), los LBA exactos de inicio y fin, y el tamaño de sector lógico/físico. El comienzo en el sector 2048 no es casual: alinea la primera partición a 1 MiB, lo que garantiza que los bloques de 4 KiB del sistema de archivos coincidan con los sectores físicos del disco y con las páginas de borrado del SSD. Una partición mal alineada provoca ciclos leer-modificar-escribir en cada operación y puede costar el 30 % del rendimiento; hoy las herramientas alinean solas, pero conviene saber por qué está ese 2048 ahí.
blkid identifica el contenido: qué sistema de archivos hay y con qué UUID.
$ sudo blkid /dev/nvme0n1p1: UUID="A1B2-C3D4" TYPE="vfat" PARTLABEL="EFI System" /dev/nvme0n1p3: UUID="c4e8f1a0-...-3b7d" TYPE="ext4" PARTUUID="8f2a..." /dev/md0: LABEL="meteora-datos" UUID="9f3a1c22-7d4e-4a51-b7c8-2e5f0a1d6b93" TYPE="ext4"
Ahí está el UUID que usaremos en /etc/fstab, y la etiqueta meteora-datos que pusimos con mkfs -L en 04-01. Ojo con la distinción: UUID identifica el sistema de archivos (lo escribe mkfs en el superbloque) y PARTUUID identifica la partición (lo escribe la tabla GPT). Reformatear cambia el UUID pero no el PARTUUID.
LVM: volúmenes físicos, grupos de volúmenes y volúmenes lógicos
El problema de las particiones fijas es que decides los tamaños el día de la instalación, cuando menos sabes, y cambiarlos después es arriesgado. LVM (Logical Volume Manager) inserta una capa de indirección que lo resuelve, con tres niveles:
graph TB
PV1["PV: /dev/sdb1 — 500 GB"] --> VG
PV2["PV: /dev/sdc1 — 500 GB"] --> VG
VG["<b>VG 'datos' — 1 TB</b><br/>reserva única de extents de 4 MiB"]
VG --> LV1["LV lv_meteora — 600 GB<br/>ext4 → /var/lib/meteora"]
VG --> LV2["LV lv_backup — 200 GB<br/>ext4 → /srv/backup"]
VG --> LV3["200 GB SIN ASIGNAR<br/>(margen para crecer)"]
- PV (physical volume): un dispositivo de bloques —partición, disco entero o RAID— entregado a LVM.
- VG (volume group): la unión de varios PV en una reserva única de espacio, dividida en extents de 4 MiB.
- LV (logical volume): un dispositivo de bloques virtual construido con extents del VG. Sobre él se hace
mkfsy se monta, exactamente igual que sobre una partición.
La creación completa, y después la ampliación en caliente, sin desmontar ni parar el servicio:
sudo pvcreate /dev/sdb1 /dev/sdc1 # 1. declarar los PV
sudo vgcreate datos /dev/sdb1 /dev/sdc1 # 2. crear el VG 'datos' (1 TB)
sudo lvcreate -L 600G -n lv_meteora datos # 3. crear un LV de 600 GB
sudo mkfs.ext4 /dev/datos/lv_meteora # 4. formatearlo
sudo lvextend -L +100G /dev/datos/lv_meteora # 5. +100 GB al volumen lógico
sudo resize2fs /dev/datos/lv_meteora # 6. y al sistema de archivosDos pasos porque son dos capas: lvextend agranda el dispositivo virtual y resize2fs extiende el ext4 para que ocupe el espacio nuevo. El orden importa: al ampliar, primero el volumen y luego el sistema de archivos; al reducir, al revés —primero resize2fs para encoger el ext4 y después lvreduce—, porque si reduces el volumen antes que el sistema de archivos, cortas datos y los pierdes. lvresize -r hace ambos pasos en el orden correcto y es la forma segura de hacerlo. Una nota que conecta con 04-01: ext4 se puede reducir; XFS no, porque xfs_growfs solo crece; es un argumento fuerte a favor de ext4 cuando no sabes cómo evolucionarán tus volúmenes.
| Capacidad | Particiones fijas | LVM |
|---|---|---|
| Redimensionar en caliente | Muy difícil y arriesgado | Sí, un comando |
| Un volumen sobre varios discos | No | Sí |
| Añadir un disco a un volumen existente | No | Sí (vgextend + lvextend) |
| Instantáneas | No | Sí |
| Mover datos entre discos en caliente | No | Sí (pvmove) |
| Complejidad y capas que pueden fallar | Mínima | Mayor |
Instantáneas de LVM para copiar /var/lib/meteora en caliente
Aquí está la funcionalidad que resuelve un problema real de Meteora. Copiar /var/lib/meteora/lecturas/2026-09-01.dat mientras el ingestor escribe en él produce una copia inconsistente: el principio del fichero es de las 03:00 y el final de las 03:04, con una estructura Lectura posiblemente cortada por la mitad. Parar el servicio media hora cada noche no es aceptable.
Una instantánea (snapshot) de LVM congela el estado de un volumen en un instante:
# 1. Crear la instantánea (instantáneo: menos de un segundo)
sudo lvcreate -L 20G -s -n snap_meteora /dev/datos/lv_meteora
# 2. Montarla en solo lectura
sudo mkdir -p /mnt/snap
sudo mount -o ro /dev/datos/snap_meteora /mnt/snap
# 3. Copiar con calma: el contenido está congelado, el servicio sigue vivo
sudo tar czf /srv/backup/meteora-$(date +%F).tar.gz -C /mnt/snap .
# 4. Desmontar y ELIMINAR la instantánea
sudo umount /mnt/snap
sudo lvremove -y /dev/datos/snap_meteoraCómo funciona: la instantánea no copia nada al crearse. Es una tabla vacía más una regla de copia en la primera escritura (copy-on-write): cuando el ingestor escribe en un bloque del volumen original, LVM primero copia el contenido antiguo a la zona de la instantánea y después deja escribir. Así, quien lee la instantánea ve el estado congelado y quien lee el original ve el actual.
Y ahora la advertencia, que es la parte que la gente ignora y luego lamenta:
| Coste | Detalle |
|---|---|
| Penalización de escritura | Cada escritura nueva sobre un bloque no copiado se convierte en leer + escribir + escribir. La caída típica es del 20-40 %, y con muchas instantáneas activas se multiplica |
| Espacio finito | La instantánea tiene un tamaño fijo (los 20 GB del ejemplo). Almacena los bloques originales de todo lo que cambie mientras viva |
| Desbordamiento = pérdida | Si se llena, la instantánea se invalida por completo y la copia se pierde. El volumen original no sufre, pero tu copia sí |
| Vida corta | Cuanto más tiempo viva, más cambios acumula y más lento va todo. Se crea, se usa y se elimina |
Dimensionarla es aritmética: si Meteora escribe 17,3 MB al día y la copia tarda 20 minutos, cambiarán unos 240 KB, así que 20 GB dan margen de sobra incluso para un pico anómalo. La vigilancia se hace con lvs, mirando la columna Data%; si se acerca al 100 %, hay que ampliarla con lvextend ya:
$ sudo lvs LV VG Attr LSize Origin Data% lv_meteora datos owi-aos--- 600,00g snap_meteora datos swi-aos--- 20,00g lv_meteora 0,12
Un matiz de honestidad técnica: la instantánea congela los bloques del dispositivo, no la memoria. Si el ingestor tenía datos en la caché de páginas sin volcar, la instantánea no los tiene. Por eso la copia perfecta lleva un paso previo: pedir al servicio que haga fsync() (o enviarle SIGHUP), ejecutar sync, y entonces crear la instantánea. Lo veremos al hablar de fsync en Gestión de Archivos, y las garantías de consistencia son el tema de Asignación de Espacio, Journaling e Integridad.
Crear el sistema de archivos con mkfs
mkfs escribe sobre el dispositivo las estructuras que estudiamos en 04-01: superbloque, descriptores de grupo, mapas de bits y tabla de inodos. No pregunta y no avisa: si el dispositivo es el equivocado, los datos anteriores dejan de ser accesibles al instante.
Las opciones que de verdad se usan, y qué decide cada una:
| Opción | Qué hace | Cuándo tocarla |
|---|---|---|
-b 4096 |
Tamaño de bloque | Bajar a 1024 con millones de ficheros pequeños (04-01) |
-i N |
Un inodo por cada N bytes | Subirlo con pocos ficheros grandes; bajarlo con muchos pequeños |
-N N |
Número exacto de inodos | Cuando sabes la cifra exacta |
-m N |
Porcentaje reservado para root | 5 % en /; 1 % o 0 % en volúmenes de datos |
-L etiqueta |
Etiqueta del sistema de archivos | Siempre: facilita /etc/fstab y el diagnóstico |
-O car |
Activar/desactivar características | extent, dir_index, metadata_csum, ^has_journal |
-E stride=,stripe_width= |
Alinear con la geometría del RAID | Con RAID 5/6, marca diferencias reales |
-n |
Simulacro: no escribe nada | Antes de cada mkfs real |
El procedimiento seguro, con el simulacro incluido:
lsblk /dev/md0 ; sudo blkid /dev/md0 ; findmnt --source /dev/md0 # 1-3. verificar
sudo mkfs.ext4 -n -b 4096 -i 1048576 -m 1 -L meteora-datos /dev/md0 # 4. simulacro
sudo mkfs.ext4 -b 4096 -i 1048576 -m 1 -L meteora-datos /dev/md0 # 5. de verdadLos tres primeros comandos responden "¿es el dispositivo correcto?", "¿qué contiene ahora?" y "¿está montado?" en cinco segundos, y evitan el accidente más caro de la administración de sistemas. El paso 4 con -n imprime exactamente lo que haría —número de inodos, de bloques, posiciones de los superbloques de respaldo— sin tocar nada.
El montaje: qué ocurre exactamente al ejecutar mount
Llegamos a la operación central. Montar es injertar el árbol de un sistema de archivos en un punto del árbol global, de modo que la resolución de rutas cruce de uno a otro sin notarlo.
Los pasos que ejecuta el núcleo, en orden:
- Resolver el punto de montaje.
/var/lib/meteorase convierte en un inodo, con el algoritmo de 04-02. Debe existir y ser un directorio; si no,ENOTDIRoENOENT. - Abrir el dispositivo y leer su superbloque, que en ext4 empieza en el byte 1024: de ahí salen el tamaño de bloque, el número de inodos, la posición de la tabla de inodos, el UUID, las características activas y el estado.
- Comprobar el estado. Si dice "sucio" —no se desmontó bien—, se dispara la recuperación desde el diario (04-05). Si exige características que este núcleo no soporta, se rechaza el montaje.
- Crear un objeto
superblocken memoria, la representación viva del sistema de archivos, con sus operaciones (leer inodo, escribir inodo, estadísticas...). - Crear una estructura
vfsmountque asocia ese superblock con el inodo del punto de montaje. - Enganchar la dentry. A partir de ahora, cuando la resolución de rutas llegue a la dentry de
/var/lib/meteora, verá la marca de "aquí hay un montaje" y saltará al inodo raíz del nuevo sistema de archivos. - Registrarlo en la tabla de montajes, visible en
/proc/mounts.
El paso 6 es la clave de todo, y explica el comportamiento más desconcertante del montaje:
Montar sobre un directorio no vacío no borra su contenido: lo oculta. Los ficheros siguen ahí, intactos, pero la ruta ya no llega a ellos porque el paso 6 desvía la resolución.
Se comprueba fácilmente:
sudo touch /var/lib/meteora/OCULTO.txt
ls /var/lib/meteora # → OCULTO.txt
sudo mount /dev/md0 /var/lib/meteora
ls /var/lib/meteora # → lecturas/ archivo/ (¡sin OCULTO.txt!)
sudo umount /var/lib/meteora
ls /var/lib/meteora # → OCULTO.txt (¡ha vuelto!)De ahí un incidente clásico: alguien escribe datos en /var/lib/meteora antes de montar el volumen, luego monta, y esos datos desaparecen de la vista mientras siguen ocupando espacio invisible en /. Para verlos sin desmontar existe el truco del bind mount del apartado 11.
La tabla de montajes:
$ cat /proc/mounts /dev/nvme0n1p3 / ext4 rw,relatime 0 0 /dev/nvme0n1p4 /var ext4 rw,relatime 0 0 /dev/md0 /var/lib/meteora ext4 rw,noatime 0 0 proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 tmpfs /run tmpfs rw,nosuid,nodev,size=1608040k,mode=755 0 0 tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0 devtmpfs /dev devtmpfs rw,nosuid,size=4096k,nr_inodes=2003417 0 0
/proc/mounts es la verdad del núcleo, con las opciones realmente en vigor. mount sin argumentos muestra lo mismo, y findmnt lo presenta en árbol: acepta un punto de montaje o un dispositivo, filtra por tipo (-t ext4) y devuelve un código de salida útil para scripts, así que es la herramienta a usar.
Identificación estable: UUID, etiquetas y /etc/fstab campo a campo
Un problema real: los nombres /dev/sdX no son estables. Se asignan en el orden en que el núcleo detecta los discos, que depende de la velocidad de arranque de cada controlador, del orden de los puertos y de si hay un USB conectado; el disco que hoy es /dev/sdb puede ser /dev/sdc mañana, y una entrada de fstab que lo nombre montará el volumen equivocado o fallará el arranque. Las cuatro formas de identificar un dispositivo:
| Forma | Qué identifica | Estabilidad | Ejemplo |
|---|---|---|---|
/dev/sdb1 |
Nombre del núcleo | Mala | Cambia con el orden de detección |
LABEL= |
Etiqueta del sistema de archivos | Buena, pero puede duplicarse | LABEL=meteora-datos |
UUID= |
Sistema de archivos, por mkfs |
Excelente | UUID=9f3a1c22-7d4e-... |
PARTUUID= |
Partición, por GPT | Excelente, sobrevive al formateo | PARTUUID=8f2a... |
Usa UUID= en /etc/fstab. Es lo que hacen todos los instaladores modernos. La única precaución: el UUID cambia al reformatear, así que tras un mkfs hay que actualizar fstab o el sistema no arrancará.
El /etc/fstab real de meteo-01:
# <sistema de archivos> <punto> <tipo> <opciones> <dump> <pass> UUID=c4e8f1a0-2b19-4d7c-9e35-6a80f2c13b7d / ext4 defaults 0 1 UUID=A1B2-C3D4 /boot/efi vfat umask=0077,shortname=winnt 0 2 UUID=7d3e9b41-05fa-4c28-8b16-d9e4a7c0f582 /boot ext4 defaults,nosuid,nodev,noexec 0 2 UUID=b81f6c30-9a24-4e5d-af73-1c206e8b4d95 /var ext4 defaults,nosuid,nodev 0 2 UUID=9f3a1c22-7d4e-4a51-b7c8-2e5f0a1d6b93 /var/lib/meteora ext4 noatime,nosuid,nodev,noexec 0 2 UUID=3f8a2c17-6d40-4b91-a5e8-7c1b09d3e264 none swap sw 0 0 tmpfs /tmp tmpfs rw,nosuid,nodev,noexec,size=2G 0 0
Los seis campos, uno a uno:
- Origen. Qué montar: UUID, etiqueta, dispositivo, o un nombre arbitrario para los sistemas virtuales (
tmpfs,proc). - Punto de montaje. Dónde. Para swap,
none. - Tipo.
ext4,vfat,tmpfs,swap,nfs... oautopara quemountlo deduzca leyendo el superbloque. - Opciones, separadas por comas y sin espacios. Es el campo del apartado siguiente.
dump. Reliquia de la utilidaddumpde los años 80. Hoy siempre 0.pass. Orden de comprobación confsckal arrancar:1para la raíz,2para las demás (se comprueban en paralelo si están en discos distintos) y0para no comprobar —obligatorio en tmpfs y sistemas de red, que no tienenfsck—.
El error más peligroso de todo este módulo vive en fstab: una línea mal escrita puede impedir que la máquina arranque, dejándola en modo de emergencia sin acceso remoto. El procedimiento seguro es innegociable:
sudo cp /etc/fstab /etc/fstab.bak # 1. copia de seguridad
sudo nano /etc/fstab # 2. editar
sudo findmnt --verify --verbose # 3. VALIDAR sintaxis, UUID y opciones
sudo mount -a # 4. montar lo pendiente: si falla, lo dice AQUÍfindmnt --verify comprueba que los UUID y los puntos de montaje existen y que las opciones son válidas sin montar nada. mount -a intenta montarlo todo: si hay un error, aparece ahora, con la máquina viva, y no en el arranque. Y si algo sale mal de todos modos, la opción nofail evita que el fallo de una entrada bloquee el arranque —muy recomendable en discos externos y montajes de red—.
Opciones de montaje y qué protege cada una
Las opciones del cuarto campo son una de las herramientas de endurecimiento más baratas que existen: cuestan cero rendimiento y cierran clases enteras de ataque.
| Opción | Qué hace | De qué protege |
|---|---|---|
defaults |
rw,suid,dev,exec,auto,nouser,async |
Nada: es el conjunto permisivo por omisión |
ro |
Solo lectura | Modificaciones accidentales o maliciosas; obligatorio en medios forenses |
rw |
Lectura y escritura | (Por defecto) |
noexec |
Prohíbe ejecutar binarios | Que se ejecute un programa subido a un directorio de datos o a /tmp |
nosuid |
Ignora los bits setuid/setgid | Escalada de privilegios con un binario setuid colocado ahí (04-06) |
nodev |
Ignora los ficheros de dispositivo | Que alguien cree un /dev/sda propio y lea el disco crudo saltándose los permisos |
noatime |
No actualiza el atime | Escrituras inútiles (04-01) |
relatime |
Atime perezoso | (Por defecto desde 2009) |
sync |
Escrituras síncronas | Pérdida de datos ante corte; cuesta muchísimo rendimiento |
nofail |
No bloquea el arranque si falla | Que un disco ausente deje la máquina en modo de emergencia |
errors=remount-ro |
Ante un error de E/S, remonta en solo lectura | Que un disco moribundo siga corrompiendo datos |
El trío noexec,nosuid,nodev es la receta estándar para cualquier volumen que contenga solo datos. nosuid es el más importante: sin él, un atacante con permiso de escritura puede colocar una copia de /bin/bash con el bit setuid de root y obtener una shell de superusuario; con nosuid el núcleo ignora ese bit y el ataque no funciona —una palabra en fstab frente a una escalada a root—. nodev cierra la vía análoga con dispositivos: sin él se podría crear un fichero de dispositivo con el mayor/menor de /dev/sda y leer el disco entero saltándose los permisos. Y noexec impide ejecutar binarios desde ahí, aunque no es una barrera fuerte: un script sigue corriendo con bash script.sh y un binario con /lib/ld-linux.so.2 ./binario, así que úsalo como capa de defensa, no como muro.
Por eso /var/lib/meteora se monta con noatime,nosuid,nodev,noexec: contiene datos, nunca programas, así que las cuatro opciones son gratis y cierran tres vectores. Aplicar el mismo trío a /tmp, /var y /home es una de las mejores relaciones esfuerzo/beneficio de la administración de sistemas, y volveremos sobre ello en el módulo 5. Las opciones se pueden cambiar en caliente con mount -o remount,ro /var/lib/meteora (y rw para volver), que es justo lo que hace el núcleo con errors=remount-ro al detectar un error de E/S: congelar las escrituras para no empeorar el daño.
Desmontar, "target is busy" y cómo resolverlo
umount desmonta: vuelca las escrituras pendientes, sincroniza el superbloque, lo marca como limpio (decisivo para 04-05) y desengancha el punto de montaje. Pero:
Un sistema de archivos está ocupado si algún proceso lo está usando, y "usando" incluye cuatro casos que la gente olvida:
- Tiene un fichero abierto dentro (04-04).
- Tiene su cwd dentro (04-02).
- Tiene un fichero mapeado en memoria con
mmap()(02-04). - Hay otro montaje encima de un subdirectorio suyo.
El diagnóstico, con dos herramientas complementarias:
$ sudo lsof +f -- /var/lib/meteora COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME meteo-api 2841 meteora cwd DIR 9,0 4096 1180928 /var/lib/meteora meteo-api 2841 meteora 7r REG 9,0 17280000 1180934 .../2026-08-31.dat agregador 2903 meteora mem REG 9,0 17280000 1180934 .../2026-08-31.dat
En lsof, la columna FD es la clave: cwd es directorio de trabajo, mem es fichero mapeado, y un número (7r) es un descriptor abierto. fuser -vm /var/lib/meteora dice lo mismo con letras: c (cwd), e (ejecutable en uso), f (fichero abierto), r (raíz) y m (mapeado).
Las soluciones, en orden de preferencia:
sudo systemctl stop meteo-api agregador # 1. LO CORRECTO: parar quien lo usa
sudo umount /var/lib/meteora
sudo umount -l /var/lib/meteora # 2. perezoso: desengancha ya, libera después
sudo umount -f /mnt/nfs-remoto # 3. forzar (montajes de red colgados)
sudo fuser -km /var/lib/meteora # 4. ÚLTIMO RECURSO: matar a quien lo usaSobre las tres últimas, con honestidad. umount -l (lazy) desengancha el punto de montaje inmediatamente de la jerarquía, pero mantiene el sistema de archivos vivo hasta que se cierre el último descriptor: las rutas dejan de funcionar al instante, pero el dispositivo sigue en uso, así que si tu objetivo era desconectarlo o formatearlo, aún no puedes. umount -f está pensado para NFS con el servidor caído, donde los procesos están bloqueados en estado D; en un sistema local puede dejar escrituras sin volcar. Y fuser -k envía SIGKILL, sin dar oportunidad de guardar nada: comprueba antes con fuser -vm a quién vas a matar.
Un cuarto caso, poco conocido pero frecuente: si el sistema de archivos parece libre y aun así está ocupado, mira si tienes otro montaje encima (un bind mount, un contenedor, un overlay) con findmnt -R /var/lib/meteora, que muestra el subárbol de montajes recursivamente.
Montajes bind y espacios de nombres de montaje
Un montaje bind hace visible un directorio ya existente en un segundo punto del árbol. No copia nada ni crea un enlace: es el mismo sistema de archivos montado dos veces.
sudo mkdir -p /srv/publicacion/datos
sudo mount --bind /var/lib/meteora/lecturas /srv/publicacion/datosAhora las dos rutas llevan a los mismos inodos. La diferencia con un enlace simbólico es sustancial:
| Enlace simbólico | Montaje bind | |
|---|---|---|
| Qué es | Un fichero con una ruta dentro | Una entrada en la tabla de montajes |
| Sobrevive al reinicio | Sí (está en el disco) | No (salvo entrada en fstab) |
Funciona dentro de un chroot |
No (la ruta apunta fuera) | Sí |
| Lo ve un proceso confinado | Puede romperse | Sí |
| Opciones distintas al original | No | Sí: se puede remontar en solo lectura |
Esa última fila es la más útil en la práctica: puedes exponer un directorio de datos a un servicio solo para lectura, sin tocar el original, y de paso resolver el enigma del apartado 7 —ver lo que quedó oculto bajo un montaje— sin desmontar nada:
sudo mount -o remount,bind,ro /srv/publicacion/datos # solo esta vista es de lectura
sudo mount --bind / /mnt/raiz-real # monta la raíz REAL, sin montajes encima
ls /mnt/raiz-real/var/lib/meteora # → OCULTO.txt, el fichero escondido
sudo umount /mnt/raiz-realEl servicio que sirve /srv/publicacion/datos no puede escribir; el ingestor, que usa la ruta original, sí. Es el mecanismo detrás de ReadOnlyPaths= de systemd (módulo 7) y de los volúmenes de solo lectura de Docker.
Los montajes bind son, además, la puerta de entrada a un concepto mayor: los espacios de nombres de montaje (mount namespaces). Linux permite que cada proceso tenga su propia tabla de montajes, de modo que /var/lib/meteora signifique cosas distintas para dos procesos de la misma máquina. Es la base de los contenedores, que lo combinan con pivot_root, sistemas de archivos por capas (overlayfs) y cgroups; se ve completo en Contenedores: Namespaces y cgroups. Aquí basta con quedarse con que la tabla de montajes no es necesariamente global, y que /proc/<pid>/mountinfo dice cuál ve cada proceso.
El Sistema de Archivos Virtual (VFS) y sus cuatro objetos
Hemos llegado a la pieza que lo explica todo. Considera este programa:
int a = open("/var/lib/meteora/lecturas/2026-08-31.dat", O_RDONLY); /* ext4 en NVMe */
int b = open("/dev/shm/meteora-cache", O_RDONLY); /* tmpfs en RAM */
int c = open("/proc/2841/status", O_RDONLY); /* inventado */
int d = open("/mnt/historico/2025-01-01.dat", O_RDONLY); /* NFS por red */
read(a, buf, 4096); read(b, buf, 4096); read(c, buf, 4096); read(d, buf, 4096);Cuatro sistemas de archivos incompatibles: uno con inodos y extents en un SSD, otro que vive en la caché de páginas, otro que genera el contenido en el momento de la lectura ejecutando código del núcleo, y otro que traduce cada operación en paquetes de red. Y sin embargo, las mismas cuatro líneas de código funcionan sobre los cuatro.
Eso lo hace posible el VFS (Virtual File System), una capa de abstracción dentro del núcleo:
graph TB
APP["Proceso en modo usuario<br/>open() read() write() close()"]
SC["Interfaz de llamadas al sistema (01-06)"]
VFS["<b>VFS — Sistema de Archivos Virtual</b><br/>superblock · inode · dentry · file"]
E4["ext4 / XFS"]
TMP["tmpfs"]
PROC["procfs / sysfs"]
NFS["NFS"]
PC["Caché de páginas (02-04)"]
BIO["Capa de bloques y planificador (02-05)"]
DRV["Controlador NVMe (02-07)"]
HW["/dev/md0 — RAID 1"]
RAM["RAM"]
NET["Pila de red → servidor remoto"]
APP --> SC --> VFS
VFS --> E4
VFS --> TMP
VFS --> PROC
VFS --> NFS
E4 --> PC
TMP --> RAM
PROC -->|genera al vuelo| RAM
NFS --> NET
PC --> BIO --> DRV --> HW
La idea es exactamente la del polimorfismo en programación orientada a objetos, implementada en C con tablas de punteros a función. El VFS define qué operaciones existen; cada sistema de archivos aporta su implementación. Cuando llega un read(), el VFS no sabe leer nada: mira la tabla de operaciones del fichero y llama al puntero correspondiente, que apunta a ext4_file_read_iter, a shmem_file_read_iter o a la función del módulo de procfs.
Los cuatro objetos del VFS, que conviene tener claros porque explican comportamientos concretos:
| Objeto | Representa | Uno por... | Estructura | Dónde lo has visto |
|---|---|---|---|---|
| superblock | Un sistema de archivos montado | Montaje | struct super_block |
Se crea en el paso 4 de mount |
| inode | Un fichero concreto | Fichero | struct inode |
El inodo de 04-01, en memoria |
| dentry | Un nombre dentro de un directorio | Componente de ruta | struct dentry |
La caché de dentries de 04-02 |
| file | Un fichero abierto por un proceso | open() |
struct file |
El descriptor, tema de 04-04 |
Las relaciones entre ellos responden preguntas que quizá te hayas hecho. Varias dentries pueden apuntar al mismo inode: eso son los enlaces duros, dos nombres y un fichero. Varios file pueden apuntar al mismo inode: dos procesos que abren el mismo fichero tienen objetos file distintos —cada uno con su desplazamiento y su modo— sobre un solo inode, y de ahí sale todo el comportamiento de descriptores, fork y dup de 04-04. Y el inode del VFS no es el inodo del disco, sino su representación en memoria común a todos los sistemas de archivos: un fichero de procfs tiene inode del VFS aunque en el disco no exista nada.
Un ejemplo de la tabla de operaciones, simplificado del núcleo real:
struct file_operations { /* lo que el VFS ESPERA de cualquier FS */
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter)(struct kiocb *, struct iov_iter *);
int (*fsync) (struct file *, loff_t, loff_t, int);
int (*mmap) (struct file *, struct vm_area_struct *);
};
const struct file_operations ext4_file_operations = { /* lo que APORTA ext4 */
.read_iter = ext4_file_read_iter, .write_iter = ext4_file_write_iter,
.fsync = ext4_sync_file, .mmap = ext4_file_mmap,
};read() en modo usuario acaba, tras el cambio a modo núcleo de 01-06, en vfs_read(), que hace esencialmente file->f_op->read_iter(...). Una indirección por puntero a función, y ahí es donde el camino se bifurca hacia ext4, tmpfs o NFS.
Lo que el VFS aporta, resumido: una sola implementación de las llamadas al sistema para todos los sistemas de archivos; cachés compartidas (páginas, dentries, inodos) que benefician a todos; la posibilidad de añadir un sistema de archivos nuevo como módulo sin tocar el resto del núcleo; y la transparencia que permite que una ruta cruce de ext4 a tmpfs a mitad de camino sin que ningún programa se entere. Es la misma filosofía de máquina extendida de 01-01, aplicada una capa más abajo.
Sistemas de archivos virtuales y en memoria
Con el VFS entendido, los sistemas de archivos "raros" dejan de serlo. Todos implementan la misma interfaz; lo que cambia es de dónde sacan los datos.
| Sistema | Montado en | Dónde están los datos | Persistente | Para qué |
|---|---|---|---|---|
| procfs | /proc |
Se generan al leer | No | Procesos y parámetros del núcleo |
| sysfs | /sys |
Se generan al leer | No | Modelo de dispositivos, controladores |
| devtmpfs | /dev |
RAM | No | Ficheros de dispositivo, poblado por el núcleo |
| tmpfs | /run, /dev/shm, /tmp |
Caché de páginas + swap | No | Datos volátiles rápidos |
| cgroupfs | /sys/fs/cgroup |
Se generan al leer | No | Límites de recursos (06-02) |
| overlayfs | Variable | Dos capas superpuestas | Depende | Imágenes de contenedores |
procfs es el más peculiar: sus ficheros no existen. Cuando ejecutas cat /proc/2841/status, el read() llega vía VFS a una función del núcleo que recorre el task_struct del proceso 2841 y formatea texto sobre la marcha. Por eso ls -l /proc/2841/status muestra tamaño 0 —el núcleo no sabe cuántos bytes producirá hasta generarlos— y por eso el contenido cambia entre dos lecturas consecutivas. Todo lo que hemos usado del módulo 2 y 3 —/proc/<pid>/maps, /proc/<pid>/stack, /proc/<pid>/fd, /proc/mounts— es esto: una interfaz de consulta al núcleo disfrazada de ficheros, para poder usarla con cat, grep y awk en lugar de con una API especial. Es una de las mejores ideas de Linux.
tmpfs es un sistema de archivos completo cuyo almacén es la caché de páginas. Es rapidísimo, porque una escritura es una copia en RAM; es volátil, y eso es una característica y no un defecto —es por lo que /run/meteora/lecturas.fifo y /run/meteora/api.sock están ahí (04-02)—; crece y encoge dinámicamente hasta el límite de size=; y puede irse a swap bajo presión de memoria, a diferencia de un disco RAM clásico que la inmoviliza.
$ df -h /dev/shm /run /tmp tmpfs 7,7G 132M 7,5G 2% /dev/shm tmpfs 1,6G 1,8M 1,6G 1% /run tmpfs 2,0G 24K 2,0G 1% /tmp
Y aquí se cierra un círculo del módulo 3. La caché de Meteora, /dev/shm/meteora-cache, la creamos con shm_open() + mmap() como memoria compartida POSIX. Ahora ya se ve qué es realmente: shm_open() es un open() sobre un fichero de tmpfs montado en /dev/shm, y mmap() mapea sus páginas en varios procesos. La memoria compartida POSIX en Linux está implementada sobre el sistema de archivos, y por eso puedes hacerle ls -l, chmod y rm como a cualquier otro fichero:
128 MiB de caché que son, a la vez, un fichero y un segmento de memoria compartida. No hay contradicción: es el VFS haciendo su trabajo.
Sistemas de archivos en red: NFS y SMB
El VFS permite algo más ambicioso: que el sistema de archivos esté en otra máquina. El cliente implementa las operaciones del VFS traduciéndolas a peticiones de red.
| NFS | SMB / CIFS | |
|---|---|---|
| Origen | Sun, 1984 | IBM/Microsoft, 1983 |
| Mundo natural | UNIX y Linux | Windows |
| Modelo de permisos | UID/GID de UNIX | ACL de Windows y usuarios de dominio |
| Estado en el servidor | Sin estado hasta NFSv3; con estado en v4 | Con estado |
| Autenticación | Confianza en el UID (o Kerberos en v4) | Usuario y contraseña, Kerberos |
| Bloqueo de ficheros | Problemático (protocolo aparte hasta v4) | Integrado |
| Puerto típico | 2049 | 445 |
Montarlos es como montar cualquier otra cosa, lo que es precisamente la gracia del VFS:
sudo mount -t nfs -o vers=4,hard,timeo=600 nas.meteora.local:/export/historico /mnt/historico
sudo mount -t cifs -o credentials=/etc/smb.cred,uid=990,gid=990 //nas/datos /mnt/datosLos tres problemas que hay que conocer antes de usarlos en producción:
1. La latencia lo cambia todo. Un stat() local cuesta microsegundos; sobre NFS, una ida y vuelta de red: entre 0,1 y 5 ms. Un ls -l de un directorio con 1.000 ficheros hace 1.000 stat(), lo que en local son milisegundos y sobre NFS pueden ser cinco segundos. La causa nunca es el ancho de banda, sino el número de idas y vueltas.
2. La semántica no es la misma. POSIX garantiza que un write() completado es visible de inmediato para cualquier otro proceso; NFS usa coherencia débil, cachea atributos y datos, y otro cliente puede tardar segundos en ver el cambio. Peor aún, el bloqueo de ficheros (flock, que veremos en 04-04) es notoriamente frágil sobre NFS. Regla práctica: no pongas sobre NFS nada que dependa de bloqueos o de escrituras coordinadas entre máquinas, bases de datos en particular.
3. hard frente a soft. Con hard (por defecto), si el servidor deja de responder los procesos se quedan bloqueados indefinidamente en estado D, sin responder ni a SIGKILL: el cuadro clínico del módulo 3 y el motivo del detector hung task de 03-06. La alternativa soft devuelve error tras un tiempo límite, pero puede corromper datos si el error llega a mitad de una escritura. Lo equilibrado es hard más intr (o NFSv4, que permite interrumpir), y montar siempre con nofail.
Meteora usa NFS solo para el archivo histórico de solo lectura en /mnt/historico: datos que ya no cambian, sin bloqueos, sin escrituras concurrentes. /var/lib/meteora, donde el ingestor escribe constantemente, está en almacenamiento local sobre RAID 1, y ahora ya tienes los tres motivos técnicos por los que esa decisión es la correcta.
Errores Comunes y Consejos
Usar /dev/sdX en /etc/fstab. Los nombres del núcleo cambian con el orden de detección. Usa UUID= siempre, y recuerda que el UUID cambia al reformatear.
Editar fstab sin validar. Una línea mal escrita deja la máquina en modo de emergencia en el siguiente arranque, y si es un servidor remoto, sin acceso. Copia de seguridad, findmnt --verify y mount -a antes de reiniciar. Siempre.
Escribir en el punto de montaje antes de montar. Los ficheros quedan ocultos bajo el montaje, ocupando espacio invisible en la partición de abajo. Comprueba con un bind mount de /.
Formatear el dispositivo equivocado. mkfs no pregunta. Los tres comandos de verificación (lsblk, blkid, findmnt --source) más el simulacro con -n cuestan diez segundos y evitan el accidente más caro de la profesión.
Reducir un volumen lógico en el orden equivocado. Al ampliar: lvextend y después resize2fs. Al reducir: resize2fs primero y después lvreduce. Invertirlo al reducir corta datos. Usa lvresize -r, que lo hace bien solo.
Dejar instantáneas de LVM vivas indefinidamente. Cuestan un 20-40 % de rendimiento de escritura y, si se llenan, se invalidan y pierdes la copia. Crear, usar y eliminar.
Recurrir a umount -l como respuesta refleja al "target is busy". Oculta el problema: el sistema de archivos sigue en uso aunque haya desaparecido del árbol. Diagnostica primero con lsof o fuser, y para el servicio.
Montar sistemas de archivos de red sin nofail. Un NAS apagado bloquea el arranque del servidor. Y con hard, un servidor caído deja procesos en D que no mueren ni con kill -9.
Consejo: monta los volúmenes de datos con nosuid,nodev,noexec —tres palabras que cierran tres vectores de ataque— y usa findmnt en lugar de mount a secas, que muestra el árbol, filtra, verifica y devuelve códigos de salida útiles en scripts.
Ejercicios
Ejercicio 1: diagnosticar el árbol de montajes
En una máquina cualquiera, ejecuta lsblk -f, findmnt, blkid y cat /proc/mounts, y responde: (a) ¿cuántos sistemas de archivos hay montados y cuántos tienen un dispositivo real detrás?; (b) ¿qué opciones tiene /tmp y qué protege cada una?; (c) ¿cuánta RAM están consumiendo los tmpfs ahora mismo?; (d) crea un fichero en /dev/shm y localiza dónde aparece su memoria en free -h. Explica el resultado de (d) con lo que sabes del VFS y de la caché de páginas.
Ejercicio 2: diseñar el particionado y el fstab de un servidor
Vas a instalar un meteo-02 con un NVMe de 1 TB y dos discos SATA de 4 TB para el histórico. Diseña el esquema completo: tabla de particiones (justificando MBR o GPT), particiones con sus tamaños y sistemas de archivos, uso o no de LVM, y el /etc/fstab íntegro con los seis campos y las opciones de montaje justificadas una a una. Explica qué protege cada separación y qué pasaría si no la hicieras. El servidor ejecutará los tres servicios de Meteora y guardará cinco años de histórico.
Ejercicio 3: copia consistente con instantáneas
/var/lib/meteora está sobre un volumen lógico de 600 GB y el ingestor escribe sin parar. Escribe el script completo de copia de seguridad nocturna que produzca una copia consistente sin parar el servicio: dimensionamiento justificado de la instantánea, la secuencia de comandos con su control de errores, la comprobación de que la instantánea no se ha desbordado, y la limpieza garantizada aunque el script falle a la mitad. Explica además por qué sync antes de crear la instantánea no basta del todo y qué haría falta para una copia perfecta.
Soluciones
Solución 1
(a) wc -l < /proc/mounts da el total y grep -c '^/dev/' /proc/mounts los que tienen dispositivo real. En un sistema típico salen entre 25 y 40 montajes, de los cuales solo 3 a 6 tienen un dispositivo real; todo lo demás es procfs, sysfs, tmpfs, devtmpfs, cgroupfs, devpts, securityfs... El sistema de archivos que ves es mayoritariamente una construcción en memoria, y esa es la mejor demostración práctica de para qué sirve el VFS.
(b) findmnt /tmp da algo como rw,nosuid,nodev,noexec,relatime,size=2097152k. nosuid impide la escalada con un binario setuid depositado ahí —/tmp es escribible por todos, así que es el sitio natural para intentarlo—; nodev impide crear un /dev/sda casero y leer el disco crudo; noexec impide ejecutar directamente un binario descargado (aunque no bloquea bash script.sh); y size=2G limita cuánta RAM puede consumir.
(c) df -h -t tmpfs: la columna "Usados" de cada tmpfs es RAM ocupada ahora mismo, y suele rondar unos cientos de MiB entre /run, /dev/shm y /tmp.
(d)
free -h # anota "buff/cache" y "disponible"
dd if=/dev/zero of=/dev/shm/prueba bs=1M count=512 status=none
free -h # buff/cache sube ~512 MiB
ls -l /dev/shm/prueba # el fichero existe y mide 536870912
rm /dev/shm/prueba
free -h # baja de nuevoExplicación. tmpfs no tiene dispositivo: sus páginas son páginas de la caché de páginas (02-04), así que free las contabiliza en buff/cache. La diferencia con una caché normal es crucial: las páginas de tmpfs no se pueden descartar, porque no hay copia en ningún disco del que releerlas; solo pueden irse a swap. Por eso un tmpfs sin size= puede llegar a agotar la memoria del sistema y disparar el OOM killer de 02-04, y por eso todos los tmpfs del sistema llevan un límite.
Solución 2
Tabla de particiones: GPT, porque los discos de 4 TB superan el límite de 2 TiB de MBR; además aporta redundancia y CRC.
| Dispositivo | Tamaño | FS | Punto | Justificación |
|---|---|---|---|---|
nvme0n1p1 |
512 MiB | vfat | /boot/efi |
Exigido por UEFI |
nvme0n1p2 |
1 GiB | ext4 | /boot |
Núcleos; fuera de LVM para simplificar el arranque |
nvme0n1p3 |
16 GiB | swap | — | Con 32 GB de RAM, media para presión puntual |
nvme0n1p4 |
resto | LVM PV | — | Todo lo demás bajo LVM, para poder redimensionar |
lv_root |
40 GiB | ext4 | / |
Sistema base con holgura |
lv_var |
40 GiB | ext4 | /var |
Logs y colas aisladas de / |
lv_meteora |
600 GiB | ext4 | /var/lib/meteora |
Datos activos, con margen |
| sin asignar | ~300 GiB | — | — | Deliberado: reserva para ampliar donde haga falta |
md1 (RAID 1, 4 TB) |
3,6 TiB | ext4 | /srv/historico |
Cinco años de histórico con redundancia |
Dejar espacio sin asignar en el VG es una decisión de diseño, no un descuido: como LVM amplía en caliente, es mejor repartir cuando sepas dónde hace falta que adivinar el día de la instalación.
UUID=<efi> /boot/efi vfat umask=0077,shortname=winnt 0 2 UUID=<boot> /boot ext4 defaults,nosuid,nodev,noexec 0 2 /dev/vg0/lv_root / ext4 defaults,errors=remount-ro 0 1 /dev/vg0/lv_var /var ext4 defaults,nosuid,nodev 0 2 /dev/vg0/lv_met /var/lib/meteora ext4 noatime,nosuid,nodev,noexec 0 2 /dev/md1 /srv/historico ext4 noatime,nosuid,nodev,noexec,nofail 0 2 UUID=<swap> none swap sw 0 0 tmpfs /tmp tmpfs rw,nosuid,nodev,noexec,size=4G 0 0
Justificación de las opciones no obvias: errors=remount-ro en / hace que un error de E/S pase el volumen a solo lectura en lugar de seguir corrompiéndose; nosuid,nodev en /var porque no hay motivo legítimo para un binario setuid ahí, pero sin noexec porque algunos gestores de paquetes ejecutan cosas desde /var/lib; noexec sí en /var/lib/meteora y /srv/historico, que son datos puros; pass=1 solo en /, 2 en el resto y 0 en swap y tmpfs, que no tienen fsck; nofail en /srv/historico para que un RAID que no ensamble no impida arrancar; y /tmp como tmpfs de 4 GB, rápido, autolimpiante y con límite para que no agote la RAM.
Qué pasaría sin las separaciones. Sin /var separado, un log desbocado llenaría / y no podrías iniciar sesión para arreglarlo. Sin /var/lib/meteora separado, no podrías aplicarle noatime ni un mkfs afinado. Sin /boot separado, cifrar el disco raíz sería mucho más complicado.
Solución 3
Dimensionamiento. La instantánea almacena los bloques originales de todo lo que cambie mientras viva. Meteora escribe unos 17,3 MB al día, es decir 720 KB/hora; si la copia tarda 30 minutos, cambiarán unos 360 KB. Con 10 GB hay un factor de seguridad de 28.000× frente a un pico anómalo, y sigue siendo el 1,6 % del volumen. Sobredimensionar aquí es barato; quedarse corto significa perder la copia.
#!/bin/bash
set -euo pipefail
VG=datos ; LV=lv_meteora ; SNAP=snap_backup ; MNT=/mnt/snap
DEST=/srv/backup/meteora-$(date +%F).tar.gz
limpiar() { # limpieza GARANTIZADA, pase lo que pase
mountpoint -q "$MNT" && umount "$MNT" || true
lvs "$VG/$SNAP" &>/dev/null && lvremove -y "$VG/$SNAP" || true
}
trap limpiar EXIT
systemctl reload meteora-ingestor # 1. SIGHUP: cerrar y reabrir con fsync (03-03)
sync # volcar la caché de páginas al dispositivo
lvcreate -L 10G -s -n "$SNAP" "/dev/$VG/$LV" # 2. instantánea (<1 segundo)
mkdir -p "$MNT" && mount -o ro "/dev/$VG/$SNAP" "$MNT" # 3. montar en solo lectura
tar czf "$DEST" -C "$MNT" . # 4. copiar con calma
USO=$(lvs --noheadings -o data_percent "/dev/$VG/$SNAP" | tr -d ' %' | cut -d. -f1)
if [ "$USO" -ge 90 ]; then # 5. ¿se desbordó durante la copia?
echo "AVISO: instantánea al ${USO}% — la copia puede ser inválida" >&2
exit 1
fi
echo "Copia correcta en $DEST (instantánea al ${USO}%)"Las tres decisiones importantes del script: set -euo pipefail aborta al primer error en lugar de continuar con una copia incompleta; trap limpiar EXIT garantiza que la instantánea se elimina aunque el script falle o lo maten —sin esto, una instantánea olvidada penaliza las escrituras durante días y acaba desbordándose—; y la comprobación posterior de data_percent avisa si la instantánea se llenó durante la copia, que es lo que convierte el script en una copia de seguridad y no en una ilusión.
Por qué sync no basta del todo. sync vuelca la caché de páginas del núcleo al dispositivo, así que la instantánea recoge todo lo que el núcleo tenía pendiente. Pero no vacía los búferes de espacio de usuario: si el ingestor usa FILE* de la biblioteca C, puede tener datos en su propio búfer que aún no han llegado ni siquiera al núcleo (04-04). De ahí el systemctl reload previo, que le pide cerrar y reabrir sus ficheros con fsync(). La copia perfecta requiere además que la aplicación tenga un punto consistente —una transacción cerrada, un fichero de día completo— y no solo bytes volcados; con un formato de registros de 24 bytes añadidos al final, cualquier corte deja como mucho una lectura incompleta, que el lector detecta por el tamaño. Es la diferencia entre consistencia de bytes y consistencia de aplicación, y volveremos sobre ella en 04-05.
Conclusión
Una partición es un rango contiguo de LBA declarado como unidad independiente, y la tabla que las describe es MBR o GPT. La elección ya no es opinable: MBR topa en 2 TiB y 4 particiones primarias y no tiene redundancia; GPT llega a 8 ZiB, admite 128 particiones, guarda una copia de la tabla al final del disco verificada con CRC32 y protege del formateo accidental con un MBR protector. Se particiona para aislar el llenado, aplicar políticas distintas, usar sistemas de archivos distintos y satisfacer los requisitos de arranque, y la separación de /var tiene un argumento demoledor: un / lleno es un servidor en el que no puedes entrar a arreglarlo. LVM añade la capa que a las particiones les falta: PV, VG y LV permiten ampliar en caliente (lvextend + resize2fs, en ese orden; al revés para reducir), repartir un volumen entre discos y mover datos sin parar nada; y sus instantáneas resuelven la copia consistente de /var/lib/meteora sin detener el ingestor, a cambio de un 20-40 % de penalización de escritura y del riesgo de invalidarse si se llenan.
El montaje es la operación central del módulo: resolver el punto de montaje, leer el superbloque, comprobar el estado, crear el superblock y el vfsmount en memoria y enganchar la dentry para que la resolución de rutas salte al nuevo árbol. De ese último paso salen dos hechos: que montar sobre un directorio no vacío oculta su contenido sin borrarlo, y que la tabla de montajes de /proc/mounts es la verdad del sistema. La identificación estable es con UUID=, nunca con /dev/sdX, y /etc/fstab tiene seis campos donde pass vale 1 en la raíz, 2 en el resto y 0 en lo que no tiene fsck — con el procedimiento obligatorio de copia de seguridad, findmnt --verify y mount -a antes de reiniciar.
Las opciones de montaje son endurecimiento gratuito: nosuid corta la escalada por binario setuid, nodev impide leer el disco crudo saltándose los permisos, noexec añade una capa más, y errors=remount-ro detiene el daño de un disco moribundo. Por eso /var/lib/meteora va con noatime,nosuid,nodev,noexec. El "target is busy" tiene cuatro causas —fichero abierto, cwd, mmap y montaje encima—, se diagnostica con lsof o fuser -vm, y se resuelve parando el servicio: umount -l desengancha pero no libera, y fuser -k mata sin avisar. Los montajes bind exponen un mismo árbol en dos puntos con opciones distintas, permiten ver lo oculto bajo un montaje y son la antesala de los espacios de nombres de montaje de 06-02.
Y la explicación de fondo de todo es el VFS: cuatro objetos —superblock por montaje, inode por fichero, dentry por nombre, file por apertura— y tablas de punteros a función que hacen que vfs_read() acabe en ext4_file_read_iter, en shmem_file_read_iter o en el cliente NFS según el caso. Gracias a él, /proc puede generar sus ficheros al leerlos —de ahí el tamaño 0 y el contenido cambiante—, tmpfs puede ser un sistema de archivos cuyo almacén es la caché de páginas —y por eso /dev/shm/meteora-cache es a la vez un fichero y memoria compartida POSIX—, y NFS puede poner un sistema de archivos al otro lado de la red, con sus tres pegas: latencia por ida y vuelta, coherencia débil que rompe los bloqueos, y hard que deja procesos en D cuando el servidor cae.
Ya tenemos el mapa completo del almacenamiento: sabemos qué es un fichero, cómo se le pone nombre, y cómo se ensambla el árbol por el que lo alcanzamos. Lo que no hemos hecho todavía es usarlo desde un programa. ¿Qué ocurre exactamente cuando open() devuelve el número 3? ¿Por qué padre e hijo comparten el desplazamiento tras un fork pero dos open del mismo fichero no? ¿Cómo implementa la shell la redirección > y ese 2>&1 que todo el mundo copia sin entender? ¿Y cómo se asegura el agregador de que las medias horarias que publica nunca se lean a medio escribir?
Es lo que veremos en Gestión de Archivos.
Fundamentos de Sistemas Operativos
Módulo 1: Introducción a los Sistemas Operativos
- Conceptos Básicos de Sistemas Operativos
- Historia y Evolución de los Sistemas Operativos
- Tipos de Sistemas Operativos
- Funciones Principales de un Sistema Operativo
- Arquitectura del Núcleo: Monolítico, Microkernel e Híbrido
- Modo Usuario, Modo Núcleo y Llamadas al Sistema
Módulo 2: Gestión de Recursos
- Gestión de Procesos
- Planificación de la CPU
- Gestión de Memoria
- Memoria Virtual y Paginación
- Gestión de Almacenamiento
- Gestión de Dispositivos
- Controladores, Interrupciones y Operaciones de E/S
Módulo 3: Concurrencia
- Conceptos de Concurrencia
- Hilos y Procesos
- Comunicación entre Procesos (IPC)
- Sincronización y Exclusión Mutua
- Problemas Clásicos de Concurrencia
- Interbloqueos: Prevención, Detección y Recuperación
Módulo 4: Estructuras de Archivos
- Sistemas de Archivos
- Estructuras de Directorios
- Particiones, Montaje y Sistema de Archivos Virtual
- Gestión de Archivos
- Asignación de Espacio, Journaling e Integridad
- Seguridad y Permisos de Archivos
Módulo 5: Protección y Seguridad del Sistema
- Principios de Protección y Control de Acceso
- Usuarios, Autenticación y Escalada de Privilegios
- Amenazas Comunes y Endurecimiento del Sistema
- Auditoría, Registros y Respuesta a Incidentes
Módulo 6: Virtualización y Contenedores
- Virtualización: Hipervisores y Máquinas Virtuales
- Contenedores: Namespaces y cgroups
- El Sistema Operativo en la Nube
- Sistemas Operativos Móviles y de Tiempo Real
