FreeBSD 14.5
ZFS FreeBSD Copia de seguridad del servidor tormenta
ZFS FreeBSD Copia de seguridad del cliente solaris
Sistema: solaris y tormenta (FreeBSD 14.5)
Método: Backup manual a disco USB (Modelo B — USB guardado fuera)
Fecha: 2026-10-03 (Actualizado tras prueba de recuperación real el 2026-10-21)
1. Introducción y filosofía
Este documento describe el sistema de backup manual a disco USB implementado en solaris y tormenta. Está diseñado para:
- Ejecutarse manualmente cuando se conecta el disco USB.
- Mantener los USB guardados fuera de las máquinas para protección ante ransomware y desastres locales.
- Ser recuperable tanto para archivos individuales como para el sistema completo.
Filosofía del Modelo B: los USB
no están conectados permanentemente. Se conectan solo cuando se va a hacer el backup, y después se guardan en otro lugar. Esto protege contra:
- Ransomware que cifraría también el USB conectado.
- Robo o incendio que afectaría a máquina y backup a la vez.
- Errores humanos que borrarían el backup por accidente.
Estado del sistema
| Elemento | solaris | tormenta |
| Pool origen | zroot | zroot |
| Pool destino (USB) | zbackup | zbk |
| Dataset destino | zbackup/recovery/solaris | zbk/tormenta |
| Etiqueta USB | ZFSBACKUP | backup1tb |
| Tamaño del pool origen | ~220 GB | ~312 GB |
| Script | /root/bin/zfs-backup.sh | /root/bin/zfs-backup.sh |
| Log | /var/log/zfs-backup.log | /var/log/zfs-backup.log |
| Retención origen | 7 snapshots | 7 snapshots |
| Retención destino | 30 snapshots | 30 snapshots |
2. El script zfs-backup.sh
Script único que funciona en ambas máquinas, detectando automáticamente el hostname. Versión 2.4.
Ubicación
/root/bin/zfs-backup.sh
Contenido completo
#!/bin/sh
# zfs-backup.sh - Backup incremental de zroot a pool USB
# Versión: 2.4 (snapshot por dataset + export en error)
# Uso: sh /root/bin/zfs-backup.sh
set -e
# ========== CONFIGURACIÓN SEGÚN MÁQUINA ==========
HOSTNAME=$(hostname -s)
case "$HOSTNAME" in
solaris)
SRC_POOL="zroot"
DST_POOL="zbackup"
DST_DATASET="zbackup/recovery/solaris"
USB_DEV="/dev/gpt/ZFSBACKUP"
RETENTION_SRC=7
RETENTION_DST=30
;;
tormenta)
SRC_POOL="zroot"
DST_POOL="zbk"
DST_DATASET="zbk/tormenta"
USB_DEV="/dev/gpt/backup1tb"
RETENTION_SRC=7
RETENTION_DST=30
;;
*)
echo "Hostname no reconocido: $HOSTNAME" >&2
exit 1
;;
esac
SNAP_PREFIX="snap"
SNAP_TODAY="${SNAP_PREFIX}-$(date +%Y%m%d)"
LOG="/var/log/zfs-backup.log"
LOCKFILE="/var/run/zfs-backup.lock"
# ========== VARIABLES DE ESTADO ==========
IMPORTED_BY_US=0
# ========== FUNCIONES ==========
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG"
}
die() {
log "ERROR: $*"
if [ "${IMPORTED_BY_US:-0}" -eq 1 ]; then
log "Exportando pool $DST_POOL antes de salir..."
zpool export "$DST_POOL" >> "$LOG" 2>&1 || log "Aviso: no se pudo exportar"
fi
rm -f "$LOCKFILE"
exit 1
}
# ========== BLOQUEO ==========
if [ -f "$LOCKFILE" ]; then
PID=$(cat "$LOCKFILE" 2>/dev/null)
if kill -0 "$PID" 2>/dev/null; then
echo "Ya hay una ejecución en curso (PID $PID)"
exit 0
fi
rm -f "$LOCKFILE"
fi
echo $ > "$LOCKFILE"
log "=========================================="
log "Iniciando backup en $HOSTNAME"
log "=========================================="
# ========== VERIFICAR POOL USB ==========
if ! zpool list "$DST_POOL" >/dev/null 2>&1; then
log "Pool $DST_POOL no está importado. Intentando importar..."
if [ ! -e "$USB_DEV" ]; then
die "Disco USB $USB_DEV no encontrado. ¿Está conectado?"
fi
if ! zpool import "$DST_POOL" 2>>"$LOG"; then
die "No se pudo importar el pool $DST_POOL"
fi
log "Pool $DST_POOL importado correctamente"
IMPORTED_BY_US=1
else
log "Pool $DST_POOL ya estaba importado"
IMPORTED_BY_US=0
fi
# ========== CREAR SNAPSHOT DE HOY (dataset por dataset) ==========
log "Creando snapshot $SNAP_TODAY en todos los datasets (los que falten)..."
CREATED=0
SKIPPED=0
FAILED=0
for ds in $(zfs list -H -o name -r "$SRC_POOL" 2>/dev/null); do
if zfs list -t snapshot "$ds@$SNAP_TODAY" >/dev/null 2>&1; then
SKIPPED=$((SKIPPED + 1))
else
if zfs snapshot "$ds@$SNAP_TODAY" >> "$LOG" 2>&1; then
CREATED=$((CREATED + 1))
else
log " → error al crear $ds@$SNAP_TODAY"
FAILED=$((FAILED + 1))
fi
fi
done
log "Snapshots: creados=$CREATED, ya existían=$SKIPPED, fallos=$FAILED"
if [ "$FAILED" -gt 0 ]; then
log "AVISO: hubo $FAILED fallos al crear snapshots (se continúa)"
fi
# ========== DETECTAR ÚLTIMA SNAPSHOT EN DESTINO ==========
LAST_DST_SNAP=$(zfs list -t snapshot -H -o name -r "$DST_DATASET" 2>/dev/null \
| grep '@snap-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] \
| sort -r \
| head -1 \
| sed 's/.*@//')
if [ -z "$LAST_DST_SNAP" ]; then
log "No hay snapshots previas en destino. Envío COMPLETO."
zfs send -Rwcv "$SRC_POOL@$SNAP_TODAY" \
| zfs receive -Fsuv -x mountpoint "$DST_DATASET" >> "$LOG" 2>&1 \
|| die "Error en el envío completo"
elif [ "$LAST_DST_SNAP" = "$SNAP_TODAY" ]; then
log "Última snapshot en destino: $LAST_DST_SNAP"
log "La snapshot $SNAP_TODAY ya está replicada. Nada que enviar."
elif ! zfs list -t snapshot "$SRC_POOL@$LAST_DST_SNAP" >/dev/null 2>&1; then
log "AVISO: $LAST_DST_SNAP no existe en origen. Envío COMPLETO."
zfs send -Rwcv "$SRC_POOL@$SNAP_TODAY" \
| zfs receive -Fsuv -x mountpoint "$DST_DATASET" >> "$LOG" 2>&1 \
|| die "Error en el envío completo"
else
log "Enviando incremental desde $LAST_DST_SNAP hasta $SNAP_TODAY"
zfs send -Rwcv -i "$SRC_POOL@$LAST_DST_SNAP" "$SRC_POOL@$SNAP_TODAY" \
| zfs receive -Fsuv -x mountpoint "$DST_DATASET" >> "$LOG" 2>&1 \
|| die "Error en el envío incremental"
fi
log "Envío completado correctamente"
# ========== FUNCIÓN DE RETENCIÓN ==========
apply_retention() {
local root="$1"
local label="$2"
local ret="$3"
log "Aplicando retención de $ret snapshots en $label..."
zfs list -t snapshot -H -o name -r "$root" 2>/dev/null \
| grep '@snap-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] \
| sort -t@ -k1,1 -k2,2r \
| awk -F@ -v r="$ret" '
{
ds = $1
if (ds != prev_ds) { count = 0; prev_ds = ds }
count++
if (count > r) print $0
}' \
| while read snap; do
log "Borrando $snap"
zfs destroy "$snap" >> "$LOG" 2>&1 || log " → error al borrar"
done
log "Retención en $label aplicada"
}
# ========== RETENCIÓN EN DESTINO (30 snapshots) ==========
apply_retention "$DST_DATASET" "destino" "$RETENTION_DST"
# ========== RETENCIÓN EN ORIGEN (7 snapshots) ==========
apply_retention "$SRC_POOL" "origen" "$RETENTION_SRC"
# ========== EXPORTAR POOL ==========
if [ "$IMPORTED_BY_US" -eq 1 ]; then
log "Exportando pool $DST_POOL"
zpool export "$DST_POOL" >> "$LOG" 2>&1 || log "Aviso: no se pudo exportar"
log "Ya puedes desconectar el USB de forma segura"
fi
log "Backup completado con éxito"
log "=========================================="
rm -f "$LOCKFILE"
Características clave
| Elemento | Descripción |
| Detección automática | Usa el hostname para elegir el pool y dataset correctos |
| Snapshot dataset por dataset | Evita el fallo atómico de zfs snapshot -r |
| Detección de sincronización | Si ya está todo replicado, no envía nada |
| Incremental automático | Detecta la última snapshot en destino y envía solo diferencias |
| Fallback a full send | Si no hay base común, hace envío completo automáticamente |
| Retención independiente | 7 snapshots en origen, 30 en destino |
| Export automático | Si el script importó el USB, lo exporta al terminar |
| Logging completo | Todo se registra en /var/log/zfs-backup.log |
| Lockfile | Evita ejecuciones simultáneas |
3. Ejecución manual paso a paso
Cuándo ejecutar: semanalmente (recomendado domingo por la tarde), o siempre que haya cambios importantes que se quieran respaldar.
Paso 1 — Conectar el USB
Conectar el disco USB (ZFSBACKUP en solaris, backup1tb en tormenta) a la máquina correspondiente. Esperar unos segundos a que el sistema lo detecte.
ls -la /dev/gpt/ZFSBACKUP # En solaris
ls -la /dev/gpt/backup1tb # En tormenta
Debe aparecer el device node. Si no aparece, probar con otro puerto USB o revisar dmesg:
dmesg | tail -20
Paso 2 — Ejecutar el script
sh /root/bin/zfs-backup.sh
Importante: NO ejecutar el script si no se está seguro de que el USB está conectado. Si no lo está, el script fallará limpiamente sin tocar nada.
Paso 3 — Verificar el resultado
tail -30 /var/log/zfs-backup.log
Debe verse al final:
[XX:XX:XX] Backup completado con éxito
[XX:XX:XX] ==========================================
Paso 4 — Desconectar el USB
Si el script importó el pool, lo habrá exportado automáticamente. Se verá en el log:
[XX:XX:XX] Ya se puede desconectar el USB de forma segura
Verificar que el pool está exportado:
zpool list
El pool de backup (zbackup o zbk) no debe aparecer en la lista. Si aparece, exportarlo manualmente antes de desconectar:
zpool export zbackup # En solaris
zpool export zbk # En tormenta
sync
Paso 5 — Guardar el USB en lugar seguro
Una vez exportado y sincronizado, se puede retirar el cable USB y guardarlo donde corresponda (fuera de casa, caja fuerte, casa de un familiar, etc.).
¡Backup completado! El proceso completo tarda típicamente entre 1 y 15 minutos dependiendo de cuántos datos hayan cambiado desde el último backup.
4. Interpretación del log
Ejemplo de ejecución exitosa (con cambios)
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Iniciando backup en solaris
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Pool zbackup no está importado. Intentando importar...
[2026-10-03 18:30:02] Pool zbackup importado correctamente
[2026-10-03 18:30:02] Creando snapshot snap-20261003 en todos los datasets (los que falten)...
[2026-10-03 18:30:02] Snapshots: creados=18, ya existían=0, fallos=0
[2026-10-03 18:30:03] Última snapshot en destino: snap-20261002
[2026-10-03 18:30:03] Enviando incremental desde snap-20261002 hasta snap-20261003
[2026-10-03 18:32:15] Envío completado correctamente
[2026-10-03 18:32:15] Aplicando retención de 30 snapshots en destino...
[2026-10-03 18:32:15] Retención en destino aplicada
[2026-10-03 18:32:15] Aplicando retención de 7 snapshots en origen...
[2026-10-03 18:32:15] Retención en origen aplicada
[2026-10-03 18:32:15] Exportando pool zbackup
[2026-10-03 18:32:16] Ya puedes desconectar el USB de forma segura
[2026-10-03 18:32:16] Backup completado con éxito
[2026-10-03 18:32:16] ==========================================
Ejemplo de ejecución sin cambios
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Iniciando backup en solaris
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Pool zbackup ya estaba importado
[2026-10-03 18:30:00] Creando snapshot snap-20261003 en todos los datasets (los que falten)...
[2026-10-03 18:30:00] Snapshots: creados=18, ya existían=0, fallos=0
[2026-10-03 18:30:00] Última snapshot en destino: snap-20261003
[2026-10-03 18:30:00] La snapshot snap-20261003 ya está replicada. Nada que enviar.
[2026-10-03 18:30:00] Envío completado correctamente
[2026-10-03 18:30:00] Aplicando retención de 30 snapshots en destino...
[2026-10-03 18:30:00] Retención en destino aplicada
[2026-10-03 18:30:00] Aplicando retención de 7 snapshots en origen...
[2026-10-03 18:30:00] Retención en origen aplicada
[2026-10-03 18:30:00] Backup completado con éxito
[2026-10-03 18:30:00] ==========================================
Ejemplo de error (USB no conectado)
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Iniciando backup en solaris
[2026-10-03 18:30:00] ==========================================
[2026-10-03 18:30:00] Pool zbackup no está importado. Intentando importar...
[2026-10-03 18:30:00] ERROR: Disco USB /dev/gpt/ZFSBACKUP no encontrado. ¿Está conectado?
Este error es normal si se ejecuta el script sin el USB conectado. No corrompe nada. Simplemente conectar el USB y volver a ejecutar.
5. Política de retención
El script aplica automáticamente dos políticas distintas:
| Ubicación | Snapshots conservados | Razón |
Origen (zroot) | 7 | Liberar espacio en el NVMe. Solo se necesitan los últimos días para incrementales. |
| Destino (USB) | 30 | Histórico más largo. El USB tiene más espacio y es el "archivo". |
Ajustar la retención
Si se quieren cambiar los valores, editar el script:
ee /root/bin/zfs-backup.sh
Buscar las líneas:
RETENTION_SRC=7
RETENTION_DST=30
Y modifícalas a los valores de preferencia. Por ejemplo, para guardar más histórico en el USB:
RETENTION_SRC=7
RETENTION_DST=60
Espacio: cada snapshot diaria ocupa entre 50 MB y varios GB según lo que cambie. Con 30 snapshots en destino, asegurarse de que el USB tiene espacio suficiente (consultar con zpool list).
6. Recuperación de archivos individuales
Escenario: se ha borrado un archivo por error o se quiere recuperar una versión anterior de algo.
Paso 1 — Conectar el USB y localizar el snapshot
# Conectar el USB de backup
zpool import zbackup # En solaris
zpool import zbk # En tormenta
# Ver snapshots disponibles
zfs list -t snapshot -r zbackup/recovery/solaris | grep 'snap-2026'
Paso 2 — Montar el snapshot en un punto temporal
mkdir -p /mnt/snap
mount -t zfs zbackup/recovery/solaris/home/carlos@snap-20261002 /mnt/snap
Ahora /mnt/snap contiene el contenido de /home/carlos tal como estaba en esa fecha.
Paso 3 — Buscar y copiar el archivo
# Ver qué hay
ls -la /mnt/snap/
# Copiar el archivo deseado
cp /mnt/snap/documento.txt /home/carlos/documento_recuperado.txt
Paso 4 — Desmontar y exportar
umount /mnt/snap
rmdir /mnt/snap
zpool export zbackup # En solaris
zpool export zbk # En tormenta
sync
Ventaja sobre el método .gz: con el backup ZFS solo montas el snapshot y accedes a los archivos directamente. No hay que descomprimir 300 GB para sacar un documento.
7. Recuperación completa del sistema (Probado en real)
Escenario: el NVMe del sistema ha fallado o necesitas reinstalar FreeBSD desde cero. Este procedimiento está validado en una prueba real de Disaster Recovery y tiene en cuenta los problemas típicos de un entorno Live (read-only, altroot, etc.).
ATENCIÓN: Este procedimiento borra todo el contenido del disco actual. Asegurarse de tener el backup antes de empezar.
Paso 1 — Arrancar desde USB de FreeBSD
Insertar el USB de instalación, arrancar la máquina desde él, y elegir "Shell" en lugar de instalar.
Paso 2 — Identificar discos
geom disk list
gpart show
Identifica el disco destino (ej. nda0 o da1) y el USB de backup (da0).
Paso 3 — Preparar el disco destino
gpart destroy -F nda0
gpart create -s gpt nda0
gpart add -t efi -a 1m -s 260m -l efi0 nda0
gpart add -t freebsd-boot -a 1m -s 512k -l boot0 nda0
gpart add -t freebsd-swap -a 1m -s 16g -l swap0 nda0
gpart add -t freebsd-zfs -a 1m -l zfs0 nda0
newfs_msdos -F 32 -c 1 /dev/nda0p1
Paso 4 — Crear el pool zroot
zpool create -o ashift=12 \
-O compression=lz4 \
-O atime=off \
-O mountpoint=none \
zroot /dev/gpt/zfs0
Paso 5 — Importar el USB de backup
zpool import zbackup
Verifica el snapshot más reciente que vas a restaurar:
zfs list -t snapshot zbackup/recovery/solaris | tail -5
Paso 6 — Restaurar el sistema
Importante: Usamos el flag -w (raw) porque tenemos datasets cifrados. NO usamos el flag -d para que la estructura caiga directamente en zroot/ROOT/default y no se anide en zroot/Solaris/ROOT/default.
# Sustituye snap-XXXX por el nombre exacto del snapshot
zfs send -Rwcv zbackup/recovery/solaris@snap-XXXX | zfs receive -Fuv zroot
Paso 7 — Configurar el Boot Environment
zpool set bootfs=zroot/ROOT/default zroot
zpool get bootfs zroot
Paso 8 — Copiar el cargador UEFI (Solución a "Read-only file system")
El entorno Live no permite crear carpetas en /mnt porque la raíz es de solo lectura. Además, la partición EFI puede estar "sucia" y montarse en Read-only. Usaremos /tmp (que está en RAM) y forzaremos el montaje:
# 1. Crear puntos de montaje temporales en RAM
mkdir -p /tmp/myroot /tmp/myefi
# 2. Montar el sistema restaurado para acceder al loader.efi
mount -t zfs zroot/ROOT/default /tmp/myroot
# 3. Reparar la partición EFI por si tiene flags de "sucio"
fsck_msdosfs -f /dev/nda0p1
# 4. Montar la EFI explícitamente en modo escritura
mount -t msdosfs -o rw /dev/nda0p1 /tmp/myefi
# 5. Crear la estructura y copiar el cargador
mkdir -p /tmp/myefi/efi/boot
cp /tmp/myroot/boot/loader.efi /tmp/myefi/efi/boot/bootx64.efi
# 6. Sincronizar y desmontar
sync
umount /tmp/myefi
umount /tmp/myroot
Paso 9 — Ajustar propiedades de montaje (El truco del -u)
No intentes usar zpool set altroot= zroot, ya que dará error "can only be set during pool creation". Tampoco puedes desmontar la raíz. Debemos usar zfs set -u para actualizar las propiedades de montaje sin intentar montar en caliente:
zfs set -u mountpoint=/ zroot/ROOT/default
zfs set -u mountpoint=/home zroot/home
zfs set -u mountpoint=/usr zroot/usr
zfs set -u mountpoint=/var zroot/var
zfs set -u mountpoint=/tmp zroot/tmp
zfs set -u mountpoint=none zroot
zfs set -u mountpoint=none zroot/ROOT
Paso 10 — Regenerar base de datos de usuarios
Para evitar el bucle de login (donde el sistema autentica pero rebota al usuario porque el home no estaba montado), regeneramos las contraseñas:
pwd_mkdb -p /etc/master.passwd
Paso 11 — Exportar y reiniciar
zpool export zbackup
zpool export zroot
reboot
Al reiniciar, el sistema leerá las propiedades corregidas en el Paso 9, montará todo en su sitio y podrás iniciar sesión con normalidad.
8. Recuperación del dataset cifrado
El dataset zroot/nfsv4/secifrado en tormenta está cifrado con ZFS native encryption.
Guardar la clave en al menos 3 sitios distintos:
- Gestor de contraseñas (Bitwarden, KeePass, etc.).
- Papel en caja fuerte.
- USB de emergencia separado del USB de backup.
Ver el contenido de la clave
base64 /etc/zfs/secifrado.key
Restaurar la clave
echo 'TU_CLAVE_EN_BASE64' | base64 -d > /etc/zfs/secifrado.key
chmod 400 /etc/zfs/secifrado.key
chown root:wheel /etc/zfs/secifrado.key
ls -la /etc/zfs/secifrado.key
Montar el dataset cifrado
zfs mount zroot/nfsv4/secifrado
ls -la /nfsv4/secifrado/
Recomendación: una vez al año, haz una prueba real de recuperación del dataset cifrado en una máquina de prueba.
9. Checklist y rutinas
Rutina semanal (domingo)
- [ ] Conectar USB
ZFSBACKUP a solaris
- [ ] Ejecutar
sh /root/bin/zfs-backup.sh
- [ ] Verificar log:
tail -20 /var/log/zfs-backup.log
- [ ] Confirmar "Backup completado con éxito"
- [ ] Desconectar USB y guardarlo en lugar seguro
- [ ] Repetir con USB
backup1tb en tormenta
Rutina mensual
- [ ] Verificar snapshots recientes en los USB
- [ ] Comprobar espacio disponible:
zpool list
- [ ] Revisar el log en busca de errores:
grep "ERROR" /var/log/zfs-backup.log
Rutina semestral
- [ ] Prueba de restauración de un archivo aleatorio.
- [ ] Verificar integridad del pool USB:
zpool scrub zbackup
- [ ] Comprobar que las claves de cifrado siguen accesibles.
Apéndice A — Comandos útiles
Ver estado de los pools
zpool list
zpool status
zpool status -v
Ver snapshots
# Todos los snapshots del pool
zfs list -t snapshot -r zroot
# Solo los snapshots diarios (formato snap-YYYYMMDD)
zfs list -t snapshot -r zroot | grep 'snap-2026'
# Contar snapshots por dataset
zfs list -t snapshot -r zroot | awk -F@ '{print $1}' | sort | uniq -c
Comprobar integridad
zpool scrub zroot
zpool scrub zbackup
zpool status
Ver procesos de backup en curso
ps aux | grep -E "zfs (send|receive)" | grep -v grep
tmux ls
Reconectar a una sesión tmux
tmux attach -t backup_usb
Apéndice B — Solución de problemas
Error: "Pool zbackup no está importado"
ls -la /dev/gpt/ZFSBACKUP
zpool import zbackup
sh /root/bin/zfs-backup.sh
Error: "cannot create snapshot ... dataset already exists"
Causa: alguno de los datasets ya tiene la snapshot de hoy. La versión 2.4 del script ya maneja esto dataset por dataset.
Error: "cannot send ... encrypted dataset"
Causa: falta el flag -w en zfs send.
Solución: usar -Rwcv en lugar de -Rcv.
El USB no se puede exportar (pool is busy)
lsof | grep zbackup
fuser -m /zbackup
zfs unmount -a
zpool export -f zbackup
Backup incompleto o corrupto
zpool scrub zbackup
zpool status zbackup
Apéndice C — Glosario
| Término | Significado |
| Pool | Conjunto de discos gestionados por ZFS como una unidad |
| Dataset | Sistema de archivos dentro de un pool |
| Snapshot | Imagen inmutable de un dataset en un momento concreto |
| Full send | Envío completo de un dataset a otro pool |
| Incremental send | Envío solo de los cambios desde una snapshot base |
| Retención | Número de snapshots que se conservan antes de borrar las más antiguas |
| ashift | Tamaño de sector usado por ZFS (12 = 4096 bytes) |
| -w (raw) | Envío de bloques cifrados sin descifrar |
| BE | Boot Environment — entorno de arranque de FreeBSD |
| tmux | Multiplexor de terminal (permite sesiones persistentes) |
Apéndice D — Lecciones aprendidas (Disaster Recovery)
Esta sección documenta los problemas reales que surgieron al realizar una prueba de recuperación en un disco de 250 GB desde el Live CD de FreeBSD. Es vital conocerlos para futuras recuperaciones:
- El entorno Live es read-only: No se puede usar
mkdir /mnt/efi. Usar siempre /tmp/ para los puntos de montaje temporales.
- El comando
zpool set altroot= falla: Esta propiedad solo se puede tocar al importar. Para corregir los puntos de montaje en caliente, usar el flag -u en zfs set -u mountpoint=/....
- Bucle de login: Si el sistema arranca pero te rebota al login (o el comando
su da error "cannot open"), es porque el directorio /home/ no se montó bien. Se soluciona regenerando las contraseñas con pwd_mkdb -p /etc/master.passwd.
- El snapshot Base es sagrado: El snapshot
snap-14.4-RELEASE-p8-casa.lan-2026-28-sept-2026 es el cimiento de todos los incrementales. Si se borra, ZFS forzará un envío completo (Full Send) de 200 GB en el próximo backup.
FreeBSD es genial!.