/srv/tramontana/backups lleva semanas creciendo. Cada madrugada, a las 4:20, respaldo_tramontana.sh deja allí una copia nueva sin que nadie haya calculado cuánto cabe, y el disco raíz de 23 GB va por el 30 %. La pregunta no es si se llenará, sino cuándo — y qué pasará con la aplicación cuando ocurra, porque un / lleno no es «va lento»: es una máquina que no puede ni escribir un log ni completar una transacción. En esta lección bajas por fin al hardware: verás la pila completa desde el disco físico hasta el punto de montaje, particionarás, formatearás, entenderás /etc/fstab campo a campo (y por qué una línea mal escrita impide arrancar), y montarás LVM, que es lo que un servidor de verdad usa. Al final, /srv/tramontana/backups vivirá en su propio volumen lógico ampliable en caliente.

Contenido

  1. La pila de almacenamiento, de arriba abajo
  2. Identificar el hardware: lsblk, blkid, fdisk -l
  3. Tablas de particiones: MBR frente a GPT
  4. Particionar con fdisk y parted
  5. Sistemas de ficheros comparados, e inodos revisitados
  6. Montar: mount, opciones, bind y findmnt
  7. /etc/fstab campo a campo y la red de seguridad
  8. Espacio: df, du, y el fichero borrado que no lo libera
  9. Swap: partición, fichero y cuánta hace falta
  10. LVM: PV, VG, LV, ampliar en caliente y snapshots
  11. RAID por software con mdadm
  12. Cuotas de disco
  13. Caso Tramontana: un disco nuevo para las copias

  1. La pila de almacenamiento, de arriba abajo

Entre el plato (o la celda NAND) y el cat fichero.txt que escribes hay cinco o seis capas. Confundirlas es la causa del 90 % de los errores de almacenamiento.

flowchart TD
    D["Disco físico<br/>/dev/sdb — 20 GiB"] --> T["Tabla de particiones GPT"]
    T --> P1["Partición /dev/sdb1"]
    P1 --> PV["PV — pvcreate"]
    PV --> VG["VG vg-datos<br/>agrupa PVs, 5G libres"]
    VG --> LV1["LV lv-backups 15G"]
    LV1 --> FS["Sistema de ficheros<br/>mkfs.ext4 — UUID"]
    FS --> M["Punto de montaje<br/>/srv/tramontana/backups"]

Las capas de LVM son opcionales —sin ellas la partición se formatea directamente—, pero resuelven el peor problema de todos: una partición no se puede ampliar si el espacio libre no está justo detrás; un volumen lógico sí, aunque el espacio esté en otro disco.

  1. Identificar el hardware: lsblk, blkid, fdisk -l

$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda      8:0    0   25G  0 disk
├─sda1   8:1    0    1M  0 part
├─sda2   8:2    0    2G  0 part /boot
└─sda3   8:3    0   23G  0 part /
sdb      8:16   0   20G  0 disk    # el disco nuevo, aún sin tabla de particiones
$ lsblk -f
NAME   FSTYPE LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda3   ext4   raiz   3f0a91c4-8d2e-4b17-9c55-0a7ce31f77b2   14,8G    30% /
sdb

lsblk -f es el comando que más veces usarás: dice el tipo de sistema de ficheros, la etiqueta, el UUID y el uso real.

$ sudo blkid /dev/sda3
/dev/sda3: LABEL="raiz" UUID="3f0a91c4-8d2e-..." TYPE="ext4" PARTUUID="a1b2c3d4-03"
$ sudo fdisk -l /dev/sda | sed -n '1,2p;5p'
Disco /dev/sda: 25 GiB, 26843545600 bytes, 52428800 sectores
Tipo de etiqueta de disco: gpt
Prefijo Qué es Dónde aparece
/dev/sda, sdb… SATA, SAS, USB y la mayoría de los virtuales VirtualBox, físicos
/dev/nvme0n1 (particiones p1) SSD NVMe Servidores y portátiles modernos
/dev/vda Disco paravirtualizado virtio KVM, cloud (AWS, OpenStack)

Y el detalle crítico: estos nombres pueden cambiar entre arranques. Basta con añadir un disco, cambiar el orden de los controladores o que el kernel detecte los dispositivos en otro orden para que el sdb de hoy sea el sdc de mañana. Por eso jamás se monta por nombre de dispositivo en fstab: se monta por UUID o por LABEL, que viajan dentro del propio sistema de ficheros.

  1. Tablas de particiones: MBR frente a GPT

Aspecto MBR (msdos) GPT
Antigüedad 1983 2000, parte de UEFI
Tamaño máximo de disco 2 TiB 8 ZiB (sin límite práctico)
Número de particiones 4 primarias (o 3 + extendida) 128 por defecto
Redundancia e integridad Ninguna: un sector dañado y adiós Copia al final del disco y CRC32
Arranque BIOS heredada UEFI (y BIOS con partición bios_grub)

Para cualquier disco nuevo hoy: GPT, sin excepciones que merezcan discusión. La partición de 1 MiB que ves en sda1 es precisamente la bios_grub que GRUB necesita en un GPT arrancado por BIOS heredada; su papel se explica en 07-01.

  1. Particionar con fdisk y parted

fdisk es interactivo y cómodo; parted admite órdenes en una línea, lo que lo hace apto para scripts. Preparamos /dev/sdb con una única partición que ocupe el disco entero:

$ sudo parted -s /dev/sdb mklabel gpt
$ sudo parted -s /dev/sdb mkpart datos 1MiB 100%
$ sudo parted -s /dev/sdb set 1 lvm on
$ sudo parted -s /dev/sdb print | tail -3
Tabla de particiones: gpt
Numero  Inicio  Fin     Tamaño  Nombre  Banderas
 1      1049kB  21,5GB  21,5GB  datos   lvm

El 1MiB de inicio no es capricho: alinea la partición con los bloques físicos y evita una penalización de rendimiento notable en SSD y en cabinas.

En fdisk la sesión equivalente sería g (crear GPT), n (nueva partición), Intro tres veces, t y 31 (tipo Linux LVM) y w para escribir. Nada se escribe hasta la w: q te saca sin tocar nada, y esa es la red de seguridad de fdisk.

Si el kernel no se entera de la nueva tabla —típico cuando el disco tiene alguna partición montada—, sudo partprobe /dev/sdb la relee, y lsblk /dev/sdb confirma que aparece sdb1.

  1. Sistemas de ficheros comparados, e inodos revisitados

FS Madurez Ampliar / Reducir Snapshots Cuándo elegirlo
ext4 Máxima; por defecto en Ubuntu Sí / sí, desmontado No (los da LVM) La opción segura para casi todo
XFS Muy alta; por defecto en RHEL En caliente / no No Ficheros grandes, escritura paralela
Btrfs Estable en usos comunes Sí / sí Sí, nativos Instantáneas frecuentes, checksums
ZFS Muy alta, integrado en Ubuntu Sí / según diseño Sí, y envío/recepción RAID + FS unificados; exige RAM

Regla práctica para un servidor Ubuntu convencional: ext4 sobre LVM. Tienes redimensionado, snapshots (los del LVM) y el sistema de ficheros más probado que existe.

$ sudo mkfs.ext4 -L backups /dev/vg-datos/lv-backups
Creando sistema de ficheros con 3932160 bloques de 4k y 983040 nodos-i
UUID del sistema de ficheros: 9d4f2b70-6c1a-4e8b-b3f7-52a0c9e14d68
$ sudo tune2fs -l /dev/vg-datos/lv-backups | grep -E 'Volume name|Inode count'
Volume name:              backups
Inode count:              983040

tune2fs permite cambiar la etiqueta (-L), el intervalo de comprobación (-i) y, muy útil en un volumen de datos, el 5 % reservado para root: sudo tune2fs -m 1 /dev/vg-datos/lv-backups recupera unos 600 MiB en 15 GiB. Ese 5 % tiene sentido en / —evita que un disco lleno impida a root arreglar la situación—, pero en un volumen dedicado a copias es espacio tirado.

Inodos: el otro límite

En 02-06 viste que el inodo guarda los metadatos y que el nombre es solo una entrada de directorio. Aquí llega la consecuencia operativa: el número de inodos se fija al formatear y no crece. Un directorio con millones de ficheros diminutos puede agotarlos con el disco medio vacío, y el error es desconcertante:

$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups  15G   6,1G  8,2G  43% /srv/tramontana/backups
$ df -i /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups  983040  983021      19  100% /srv/tramontana/backups

43 % de espacio libre y No queda espacio en el dispositivo al crear un fichero. Ante ese error, df -i es la segunda comprobación obligatoria. La solución pasa por borrar ficheros pequeños o reformatear con más inodos (mkfs.ext4 -i 8192).

  1. Montar: mount, opciones, bind y findmnt

sudo mkdir -p /mnt/pruebas && sudo mount /dev/vg-datos/lv-backups /mnt/pruebas
sudo mount -o remount,ro /mnt/pruebas   # cambiar opciones sin desmontar; umount para soltar

Si umount responde «objetivo ocupado», retoma lsof y fuser de 03-06:

$ sudo fuser -vm /mnt/pruebas
                     USUARIO    PID ACCESO COMANDO
/mnt/pruebas:        operador  2841 ..c..  bash

Alguien —tú, probablemente— tiene ahí su directorio de trabajo. umount -l (lazy) desmonta cuando se libere, pero es un parche.

Opción Qué hace Cuándo usarla
defaults rw,suid,dev,exec,auto,nouser,async Punto de partida
noatime No actualiza la marca de último acceso Siempre en servidores: ahorra escrituras
nodev / nosuid Ignora ficheros de dispositivo / bits SUID Cualquier volumen de datos: cierra la vía de 05-02
noexec / ro Prohíbe ejecutar binarios / solo lectura Copias, /tmp, subidas; forense
nofail El arranque continúa si falta el dispositivo Todo disco que no sea /
$ findmnt -no SOURCE,FSTYPE,OPTIONS /srv/tramontana/backups
/dev/mapper/vg--datos-lv--backups ext4 rw,noatime,nodev,nosuid

findmnt es infinitamente más legible que mount sin argumentos, y findmnt --verify valida el fstab sin montar nada. Un montaje bind (sudo mount --bind /srv/tramontana/backups/envios /opt/tramontana/salida) hace aparecer un directorio existente en otro punto del árbol sin copiar nada: es la forma limpia de exponer una carpeta a un servicio confinado, y en 05-05 verás que systemd hace lo mismo con BindPaths.

  1. /etc/fstab campo a campo y la red de seguridad

# /etc/fstab
# <dispositivo>                              <punto>                  <tipo> <opciones>                  <dump> <fsck>
UUID=3f0a91c4-8d2e-4b17-9c55-0a7ce31f77b2    /                        ext4   defaults,noatime             0      1
UUID=b7e12a55-0c4d-4e39-8a61-3f9d2b70c1a8    /boot                    ext4   defaults,noatime             0      2
/dev/mapper/vg--datos-lv--backups            /srv/tramontana/backups  ext4   defaults,noatime,nodev,nosuid,nofail  0  2
Campo Contenido Notas
1 Dispositivo UUID= o LABEL=, nunca /dev/sdb1
2 y 3 Punto de montaje y tipo El directorio debe existir; ext4, xfs, swap, auto
4 Opciones Separadas por comas, sin espacios
5 y 6 dump y fsck El 5 es una reliquia (siempre 0); el 6 vale 1 para /, 2 para el resto y 0 para no comprobar

Por qué un fstab mal escrito impide arrancar

En el arranque, systemd convierte cada línea de fstab en una unidad .mount y las hace dependencia de local-fs.target. Si un dispositivo no aparece, el arranque espera 90 segundos y luego cae a modo de emergencia pidiendo la contraseña de root — que en Ubuntu está bloqueada. Un servidor remoto en ese estado es un servidor perdido hasta que alguien abra la consola.

Por eso hay dos reglas innegociables:

sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F)   # copia previa, como siempre
sudo vim /etc/fstab && sudo diff -u /etc/fstab.bak-$(date +%F) /etc/fstab
sudo findmnt --verify --verbose                    # validación sintáctica
sudo mount -a                                      # montar TODO lo del fstab AHORA

mount -a antes de reiniciar no es opcional. Si falla, lo arreglas con el servidor en pie; si no lo ejecutas, lo descubrirás con el servidor caído. Y añade nofail a todo lo que no sea /: convierte un fallo de arranque en un aviso en el log.

  1. Espacio: df, du, y el fichero borrado que no lo libera

$ df -h --total | tail -1
total             25G   6,9G   17G  30%
$ sudo du -sh --max-depth=1 /srv/tramontana 2>/dev/null | sort -h
4,8G	/srv/tramontana/backups
6,1G	/srv/tramontana

ncdu hace lo mismo de forma interactiva y es lo que usarás cuando busques al culpable con prisa. Recuerda de 02-03 que du mide espacio ocupado en bloques y ls -l el tamaño lógico: no tienen por qué coincidir.

El clásico: df dice lleno, du dice vacío

$ df -h / | tail -1
/dev/sda3         23G    23G     0  100% /
$ sudo du -sh /var
2,1G	/var

Faltan gigas que nadie ve. La explicación conecta directamente con los inodos de 02-06: cuando borras un fichero que un proceso tiene abierto, desaparece el nombre del directorio, pero el inodo y sus bloques siguen vivos hasta que el último descriptor se cierre. Alguien hizo rm sobre un log gigante y el proceso sigue escribiendo en un fichero sin nombre.

$ sudo lsof +L1
COMMAND    PID           USER  FD TYPE  SIZE/OFF NLINK   NODE NAME
tramonta  1284 svc-tramontana  3w  REG 16106127360   0 262147 /var/log/tramontana/acceso.log (deleted)

NLINK 0 y (deleted) son la firma del problema. Las dos salidas: reiniciar el proceso (systemctl restart, que veremos en 05-05) o, si no puedes, truncar el fichero por su descriptor con sudo truncate -s 0 /proc/1284/fd/3, que libera el espacio sin matarlo.

Y la lección de fondo: un log no se borra, se rota — que es exactamente lo que montaremos en 05-06.

  1. Swap: partición, fichero y cuánta hace falta

La swap es espacio de disco que el kernel usa para descargar páginas de memoria poco usadas. Hoy se prefiere un fichero de swap a una partición: se redimensiona sin tocar la tabla de particiones.

$ sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
$ sudo mkswap /swapfile && sudo swapon /swapfile && swapon --show
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2

Con su línea en fstab (/swapfile none swap sw 0 0). El chmod 600 es obligatorio: el contenido de la swap incluye trozos de memoria de procesos, y eso incluye secretos.

vm.swappiness (0–200, por defecto 60) decide cuánta prisa se da el kernel en usarla; bajarlo a 10 es lo habitual en un servidor de aplicación. El ajuste fino de este y otros parámetros del kernel es materia de 07-03. ¿Cuánta swap? Con 3,8 GB de RAM, entre 2 y 4 GB es razonable: no como sustituto de memoria —si el servidor swapea constantemente, va a ir muy lento igual—, sino como colchón que evita que el OOM killer mate la aplicación ante un pico puntual.

  1. LVM: PV, VG, LV, ampliar en caliente y snapshots

LVM introduce tres niveles: los PV (particiones o discos enteros entregados a LVM), el VG (una bolsa de espacio formada por uno o varios PV) y los LV (los «discos virtuales» que se formatean y montan). El VG se divide en extents de 4 MiB, y un LV es simplemente un conjunto de extents, que no tienen por qué ser contiguos ni estar en el mismo disco. De ahí viene todo el poder de LVM.

$ sudo pvcreate /dev/sdb1 && sudo vgcreate vg-datos /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.
  Volume group "vg-datos" successfully created
$ sudo lvcreate -L 15G -n lv-backups vg-datos
  Logical volume "lv-backups" created.
$ sudo vgs && sudo lvs
  VG       #PV #LV #SN Attr   VSize   VFree
  vg-datos   1   1   0 wz--n- <20,00g <5,00g
  LV         VG       Attr       LSize
  lv-backups vg-datos -wi-a----- 15,00g

Fíjate en que hemos dejado 5 GiB libres en el VG a propósito: son el margen para ampliar el volumen y, sobre todo, para poder crear un snapshot. Un VG al 100 % es un VG sin maniobra.

Ampliar en caliente, con el volumen montado y en uso:

$ sudo lvextend -L +3G -r /dev/vg-datos/lv-backups
  Size of logical volume vg-datos/lv-backups changed from 15,00 GiB to 18,00 GiB.
  El sistema de ficheros tiene ahora 4718592 bloques.

La opción -r (--resizefs) es la clave: amplía el LV y el sistema de ficheros de encima en un solo paso. Sin ella tendrías un volumen mayor y un df idéntico, que es el error más frecuente de quien empieza con LVM. lvextend -l +100%FREE -r se come todo el espacio libre del VG.

Reducir es otra historia. Hay que hacerlo al revés (primero el sistema de ficheros, luego el LV), con el volumen desmontado, y XFS directamente no se puede reducir. Un error de orden aquí destruye datos. Regla: crea los LV pequeños y amplía cuando haga falta; nunca al revés.

Snapshots LVM

Un snapshot es un LV que guarda las diferencias respecto al original desde el instante de su creación. Se crea en segundos y permite copiar un volumen en un estado congelado y coherente mientras la aplicación sigue escribiendo:

$ sudo lvcreate -L 2G -s -n snap-pre-despliegue /dev/vg-datos/lv-backups
  Logical volume "snap-pre-despliegue" created.
$ sudo mount -o ro /dev/vg-datos/snap-pre-despliegue /mnt/snapshot   # copiar de aquí
$ sudo umount /mnt/snapshot && sudo lvremove -y /dev/vg-datos/snap-pre-despliegue

Dos advertencias imprescindibles: el snapshot se llena si el original cambia más de lo que su tamaño permite, y cuando se llena se invalida y se pierde. Y no es una copia de seguridad: vive en el mismo VG, en el mismo disco. Es una herramienta de consistencia, y así la usaremos en 05-08.

  1. RAID por software con mdadm

Nivel Discos mín. Capacidad útil Tolera Escritura
0 (striping) 2 100 % Nada: un disco cae y se pierde todo Muy rápida
1 (espejo) 2 50 % 1 disco Normal
5 / 6 3 / 4 n−1 / n−2 1 / 2 discos Penalizada por la paridad
10 (1+0) 4 50 % 1 por espejo Rápida; la elección para bases de datos
$ sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdc1 /dev/sdd1
mdadm: array /dev/md0 started.
$ cat /proc/mdstat | tail -1
      20955136 blocks super 1.2 [2/2] [UU]
$ sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf && sudo update-initramfs -u

[UU] significa los dos discos sanos; un [U_] es un disco caído y hay que actuar hoy, no la semana que viene. Sobre /dev/md0 se pone después un PV de LVM, y así se combinan redundancia y flexibilidad.

RAID no es una copia de seguridad. RAID protege de que un disco se rompa. No protege de un rm -rf (se replica al instante en el espejo), ni de un cifrado por ransomware, ni de un fallo del controlador que corrompa ambos discos, ni de un incendio en la sala. La copia de seguridad es 05-08, y son cosas distintas y complementarias.

  1. Cuotas de disco

Cuando varios usuarios comparten un volumen, las cuotas limitan cuánto ocupa cada uno. Se activan con usrquota,grpquota en fstab, se inicializan con quotacheck -cug y se fijan con edquota -u usuario o sin interacción: sudo setquota -u luis 5G 6G 0 0 /srv/tramontana/backups (blando 5G, duro 6G), y sudo repquota -s /srv/tramontana/backups da el informe de uso. El límite blando puede superarse durante un periodo de gracia; el duro no se supera nunca. En un servidor de aplicación con un único usuario de servicio son poco útiles; en uno compartido son la diferencia entre un incidente y una llamada a las tres de la mañana.

  1. Caso Tramontana: un disco nuevo para las copias

Marta aprueba añadir un disco de 20 GiB a la VM. El objetivo: que /srv/tramontana/backups deje de competir por el espacio de /, sin perder ni un byte de las copias existentes y sin que respaldo_tramontana.sh se entere.

Paso 1 — Añadir el disco. Con la VM apagada, VirtualBox → Almacenamiento → disco de 20 GiB. Al arrancar, lsblk debe mostrar sdb sin particiones.

Paso 2 — Partición, PV, VG y LV: los comandos de los apartados 4 y 10, ya ejecutados. Resultado: vg-datos de 20 GiB con lv-backups de 15 GiB y 5 GiB de margen.

Paso 3 — Formatear y montar en un punto temporal.

sudo mkfs.ext4 -L backups /dev/vg-datos/lv-backups && sudo tune2fs -m 1 /dev/vg-datos/lv-backups
sudo mkdir -p /mnt/nuevo && sudo mount /dev/vg-datos/lv-backups /mnt/nuevo

Paso 4 — Copiar preservándolo todo. rsync -aHAX no es lujo: -a conserva permisos y propietarios (el operador:tramontana de 05-01), -H los enlaces duros, -A las ACL de 05-02 y -X los atributos extendidos.

$ sudo rsync -aHAX --info=progress2 /srv/tramontana/backups/ /mnt/nuevo/
$ sudo diff -qr /srv/tramontana/backups /mnt/nuevo && echo "Contenido idéntico"
Contenido idéntico
$ sudo du -sh /srv/tramontana/backups /mnt/nuevo
4,8G	/srv/tramontana/backups
4,8G	/mnt/nuevo

(Antes de copiar, comenta la línea de cron de la copia para que no entre una a media faena.)

Paso 5 — Intercambiar, con red de seguridad. No borramos el original: lo renombramos, y así el rollback es instantáneo. sudo umount /mnt/nuevo && sudo mv /srv/tramontana/backups /srv/tramontana/backups.viejo && sudo mkdir /srv/tramontana/backups.

Paso 6 — fstab, con las tres protecciones.

$ sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F)
$ echo "UUID=$(sudo blkid -s UUID -o value /dev/vg-datos/lv-backups) /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2" | sudo tee -a /etc/fstab
$ sudo diff -u /etc/fstab.bak-$(date +%F) /etc/fstab | tail -1
+UUID=9d4f2b70-... /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2
$ sudo mount -a && findmnt -no SOURCE,OPTIONS /srv/tramontana/backups
/dev/mapper/vg--datos-lv--backups rw,nosuid,nodev,noatime

nosuid y nodev porque en un volumen de copias no debe haber nunca un binario SUID ni un fichero de dispositivo; nofail porque un fallo de este disco no puede impedir que arranque el servidor.

Paso 7 — Restaurar propiedad, verificar y limpiar.

$ sudo chown -R operador:tramontana /srv/tramontana/backups
$ sudo chmod 2770 /srv/tramontana/backups          # SGID de 05-02: grupo heredado
$ sudo -u operador /home/operador/scripts/respaldo_tramontana.sh --dry-run
[2026-08-18T11:04:12+02:00] simulacion: destino /srv/tramontana/backups (9,4G libres)
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups   15G   4,9G  9,4G  35% /srv/tramontana/backups

Solo cuando una copia real haya funcionado y se haya verificado su sha256sum se borra /srv/tramontana/backups.viejo, y se anota todo:

sudo tee -a /opt/tramontana/HISTORIAL >/dev/null <<'FIN'
2026-08-18  Disco de copias (operador)
  - sdb 20G -> GPT + PV + vg-datos (5G libres para snapshots) + lv-backups 15G ext4
  - rsync -aHAX, fstab por UUID con nofail/nodev/nosuid, mount -a OK
  - backups.viejo conservado hasta la primera copia verificada
FIN

Errores Comunes y Consejos

  • Montar por /dev/sdb1 en fstab. El día que el orden de detección cambie, arrancará el disco equivocado o ninguno. UUID o LABEL, siempre.
  • Reiniciar sin mount -a. Es la causa número uno de servidores que no vuelven. Y nofail en todo lo que no sea /.
  • lvextend sin -r. El volumen crece, df no cambia y pierdes media hora. Con -r, el sistema de ficheros crece con él. Y no llenes el VG al 100 %: sin espacio libre no hay snapshot ni margen para ampliar.
  • Confiar en RAID como copia de seguridad. No lo es, y descubrirlo el día del borrado accidental es caro.
  • rm sobre un log en uso. El espacio no se libera hasta que el proceso cierre el descriptor: lsof +L1 lo delata. Los logs se rotan (05-06).
  • Copiar datos con cp -r en vez de rsync -aHAX: pierdes propietarios, enlaces duros, ACL y atributos, y luego los permisos de 05-01 no cuadran.
  • Consejo: guarda lsblk -f, vgs, lvs y una copia del fstab junto al HISTORIAL. Reconstruir de memoria la disposición de discos, con el servidor caído, no es un plan.

Ejercicios

  1. Diagnóstico de disco lleno. df -h / marca 100 %, pero du -sh / suma bastante menos. Enumera las tres causas posibles en orden de probabilidad y el comando que confirma cada una.
  2. Ampliar en caliente. lv-backups (15 GiB) se ha quedado corto y el VG tiene 5 GiB libres. Amplíalo 3 GiB sin desmontar, verifica que el espacio es visible para df y explica qué habría pasado sin -r.
  3. Entrada de fstab segura. Escribe la línea de fstab para un volumen de subidas de usuarios montado en /opt/tramontana/shared/uploads, con las opciones que un directorio donde escriben terceros debe tener, y describe cómo la validarías antes de reiniciar.

Soluciones

1. Por orden de probabilidad:

sudo lsof +L1     # (a) fichero borrado con un proceso que lo mantiene abierto
df -i /           # (b) inodos agotados: hay espacio pero no se puede crear nada
sudo mount --bind / /mnt/raiz && sudo du -sh /mnt/raiz/*   # (c) datos bajo un montaje

La tercera es la más traicionera: si alguien escribió en /srv/tramontana/backups antes de montar el volumen encima, esos ficheros siguen ocupando espacio en / pero son invisibles porque el montaje los tapa. El bind mount de / en otro punto los deja a la vista. Es el riesgo del paso 5 del caso Tramontana, y por eso creamos el directorio vacío en lugar de reutilizar el que tenía datos.

2.

$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups   15G   4,9G  9,4G  35% /srv/tramontana/backups
$ sudo lvextend -L +3G -r /dev/vg-datos/lv-backups
  Size of logical volume vg-datos/lv-backups changed from 15,00 GiB to 18,00 GiB.
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups   18G   4,9G   12G  29% /srv/tramontana/backups

Sin -r, lvs mostraría 18 GiB y df seguiría diciendo 15 GiB: el sistema de ficheros ext4 no sabe que el dispositivo por debajo ha crecido hasta que se le dice con resize2fs. La operación es segura en caliente porque ext4 admite crecer montado; reducir exigiría desmontar y hacerlo en el orden inverso.

3.

LABEL=uploads  /opt/tramontana/shared/uploads  ext4  defaults,noatime,nodev,nosuid,noexec,nofail  0  2

noexec es el añadido clave respecto al volumen de copias: en un directorio donde escriben terceros, impedir la ejecución de binarios corta en seco que una subida maliciosa se convierta en código en marcha. nodev y nosuid cierran las otras dos vías, y nofail evita que un problema con este volumen impida arrancar. Validación antes de reiniciar:

sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F)   # copia previa
sudo findmnt --verify --verbose                    # sintaxis y coherencia
sudo mount -a && findmnt /opt/tramontana/shared/uploads   # montar y ver opciones efectivas

Nótese que findmnt al final muestra las opciones efectivas: es la única prueba de que lo que escribiste es lo que el kernel aplicó.

Conclusión

Ya no hay una capa opaca entre tus ficheros y el hardware. Recorres la pila entera —disco, tabla de particiones, partición, PV, VG, LV, sistema de ficheros, punto de montaje— y sabes qué problema resuelve cada peldaño; identificas el hardware con lsblk -f, blkid y fdisk -l, y sabes por qué los nombres /dev/sdX no son de fiar y el UUID sí; eliges GPT sin dudarlo, particionas con parted en una línea y con fdisk sabiendo que nada se escribe hasta la w; comparas ext4, XFS, Btrfs y ZFS con criterio, ajustas con tune2fs y reconoces el desconcierto de un df -h con sitio y un df -i al 100 %.

Montas con las opciones que un servidor necesita —noatime, nodev, nosuid, noexec, nofail—, lees /etc/fstab campo a campo y sabes que mount -a antes de reiniciar es la diferencia entre un ajuste y una noche perdida. Diagnosticas el disco lleno en sus tres variantes, incluido el fichero borrado que lsof +L1 delata. Y dominas LVM: creas PV, VG y LV, amplías en caliente con lvextend -r, sabes por qué reducir es peligroso y usas snapshots para congelar un estado coherente. Conoces mdadm y sus niveles, y tienes grabado que RAID no es una copia de seguridad.

Sobre todo, /srv/tramontana/backups vive ya en su propio volumen lógico de 15 GiB, ampliable en caliente, montado por UUID con nofail, con las copias migradas byte a byte con rsync -aHAX y verificadas, y con 5 GiB de margen en el VG reservados para snapshots.

Y llegamos al núcleo del módulo. Tienes identidades, permisos, paquetes y disco, pero la aplicación de Tramontana sigue arrancándose a mano: si el servidor se reinicia, no vuelve; si el proceso muere, nadie lo levanta; desplegar.sh cambia el enlace simbólico y sigue sin reiniciar nada; y la copia de las 4:20 depende de una línea de cron sin control real de solapamiento ni registro decente. En systemd y la Gestión de Servicios se acaba todo eso: escribirás tramontana.service desde cero y endurecido, entenderás la diferencia real entre orden y dependencia, convertirás respaldo_tramontana.sh en un .service con su .timer y Persistent=true, y desplegar.sh hará por fin el systemctl restart que le faltaba.

Curso de Linux: De Principiante a Administrador de Sistemas

Módulo 1: Introducción a Linux

Módulo 2: Comandos Básicos de Linux

Módulo 3: Habilidades Avanzadas en la Línea de Comandos

Módulo 4: Scripting en Shell

Módulo 5: Administración del Sistema

Módulo 6: Redes y Seguridad

Módulo 7: Temas Avanzados

Módulo 8: Proyectos Prácticos

© Copyright 2026. Todos los derechos reservados