Deadlock de nfsd: causa raíz de los cuelgues del NAS (2026-07-26)¶
Nota (registro histórico): el NAS pasó de
192.168.0.237a192.168.0.20en la renumeración IP cerrada el 2026-07-31, unos días después de este incidente. Las IPs.237de las pilas de kernel capturadas abajo son las que eran ciertas en el momento del incidente — no se han tocado. Ver nas-reboot.md para el runbook vivo con la IP actual.
Investigación que cerró un problema abierto desde el 2026-07-14. Incluye las hipótesis falsas porque cada una costó tiempo y conviene no repetirlas.
La causa raíz¶
Deadlock del nfsd de Linux al destruir sesiones NFSv4. Capturado en vivo con pilas de
kernel de ambos extremos:
NAS (servidor)
nfsd wchan=__flush_workqueue
__flush_workqueue <- nfsd4_destroy_session (espera vaciar la cola de callbacks)
kworker/u8:N+nfsd4_callbacks wchan=rpc_shutdown_client
rpc_shutdown_client <- nfsd4_process_cb_update <- nfsd4_run_cb_work (trabajo EN esa cola)
208 (cliente)
192.168.0.237-manager wchan=rpc_wait_bit_killable
rpc_call_sync <- nfs4_proc_destroy_session (esperando al servidor)
Se esperan mutuamente. Cada episodio pierde un hilo nfsd para siempre (D-state, no se
mata ni con kill -9). Se acumulan de uno en uno; cuando caen los 8, el NFS muere.
El estrés de E/S no cuelga el NAS directamente: hace que los clientes NFSv4 agoten su timeout, y es la reconexión la que dispara el bug. Por eso correlacionaba con el backup de PBS (06:40) y con el borrado de snapshots (03:00) sin que ninguno fuera la causa.
Kernel afectado: 6.1.120+ (TOS 6.0.794).
Corrección 2026-08-04: este runbook decía que TOS 7 traía el kernel 6.12 y que la actualización era por tanto un arreglo dirigido. Es falso, o al menos no verificado. TOS 7 se anunció en beta con 6.12, pero la página oficial del release final da un kernel en la rama 6.1.x (string mal formateado en el marketing de TerraMaster, no se pudo confirmar el punto exacto) — es decir, TerraMaster probablemente volvió atrás de 6.12 a un 6.1.x más probado antes del lanzamiento. No asumir que TOS 7 arregla esto sin confirmar el build de kernel exacto primero. Ver la sección de actualización más abajo para el objetivo real.
Cómo reconocerlo¶
| Señal | Valor |
|---|---|
load1 |
clavado en un entero plano (1 por hilo perdido) |
disco / red / nfsd req |
cero |
procs_blocked |
0 ← la clave |
procs_running |
1 |
procs_blocked cuenta sólo iowait; el load cuenta toda tarea en D. Si el load es 10
y los bloqueados 0, hay diez tareas en sueño ininterrumpible que no esperan disco:
esperan un cerrojo. Histórico: 26-jul load=2 (2 hilos), 14-jul load=10 (8 hilos + 2).
Hipótesis falsas (y por qué cayeron)¶
| Hipótesis | Cómo se descartó |
|---|---|
Backup de appdata satura el nfsd con 3 h de escritura |
Medido: escribía 18 GB en 20 min; las otras 3 h leía agujeros de un fichero sparse. Ver abajo. |
gzip es el cuello del backup |
42 MB/s → explicaría 11 min de 209 |
| El NFS es lento | 111 MB/s, satura la gigabit |
| Falta de RAM en el 208 | PSI de memoria ≈1 %; el swap estaba rancio, no activo |
| Muchos ficheros pequeños | 25 641 ficheros / 6,2 GB en 55 s |
btrfs subvolume delete / snapshots / fichero CoW de 875 GB |
Amplifican el estrés, no son la causa |
| Un trabajo semanal los lunes a las 07:30 | Artefacto del método: min_over_time[30m] recortaba el inicio real |
| Scrub de BTRFS | El último fue el 16-may y quedó aborted |
Lección de método: una ventana de agregación puede fabricar patrones inexistentes. Para fechar el inicio de un episodio, consultar a paso de 60 s.
Hallazgo colateral: backup de appdata, 3h29m → 18m33s¶
appdata ocupa 28 GB reales pero 2,1 TB aparentes:
appdata/tunarr/data.ms/indexes/*/data.mdb es la LMDB de Meilisearch con max_map_size
de 2 TiB y 287 MB asignados. du cuenta bloques; tar leía el tamaño aparente y se
tragaba 2 TiB de ceros cada noche.
Cura: tar -S/--sparse (GNU tar ≥1.29 usa SEEK_HOLE). Sobre tunarr solo: 2,3 s
frente a horas. Verificado que restaura el fichero con sus agujeros intactos
(aparente=2199023255552 bloques_512=586928, idénticos).
Ante un backup absurdamente lento, el primer comando no es
timeal compresor:
También se corrigió un livelock de la API .backup() de sqlite: reinicia la copia cada
vez que un escritor toca la DB origen; con Music Assistant escribiendo no terminaba nunca
(3h20m atascado, .snapshot a 0 bytes, sin llegar al tar). Cura: VACUUM INTO + timeout.
Automatización añadida¶
| Qué | Dónde | Detalle |
|---|---|---|
| Captura forense | NAS /usr/local/bin/nas-hang-forensics.sh + cron 1 min |
Tareas en D con pila de kernel; dmesg incremental. Escribe en /root (persiste); nunca toca /Volume1 para no colgarse con él. |
| Auto-reboot por deadlock | NAS nas-volume-selfheal.sh |
≥50 % hilos nfsd en D sostenido 10 min → sysrq-b. 1-2 hilos = sólo registra. |
| Reconciliación | 208 nfs-health-monitor.sh |
Foto de contenedores NFS vivos → congelada al primer fallo → restaurados al volver el NFS. Inerte en operación normal. |
| Replicación de logs | 208 pull-nas-forensics.sh cron 10 min |
Copia el log del NAS al 208 con timeout. |
Por qué el "sostenido 10 min" no es negociable¶
El 26-jul a las 19:41 los 8 hilos entraron en D a la vez por una tormenta de E/S y 6 se recuperaron en un minuto. Un disparo instantáneo habría reiniciado el NAS sin necesidad. Probado en simulacro con 6 casos, incluido ese.
Por qué la reconciliación no levanta "todo lo parado"¶
Sablier para contenedores a propósito (lazy-start), y trip-planner está en la lista de
contenedores NFS. Un reconciliador ingenuo se pelearía con él cada 2 minutos.
Trampas de systemd encontradas¶
OnUnitActiveSecen un watchdog es una bomba. Se ancla a la ejecución anterior: si el servicio se cuelga (justo cuando hace falta), no hay ancla y al morir el timer se apaga y no vuelve. Caso real: 19:41:54 arrancó sobre un NFS colgado, systemd lo mató a las 20:04:57, y quedóinactive1 h 43 min → 19 contenedores caídos 2 horas. → Para vigilantes usar SIEMPREOnCalendar+TimeoutStartSec.- Un
TimeoutStartSeccorto mata recuperaciones legítimas.recover_nfshaceMAX_RETRIES=30 × 20 s= hasta 10 min válidos. Poner 90 s (error cometido y corregido) las abortaría. Valor actual: 900 s.
Actualización 2026-08-04: el vigilante se disparó de verdad, cascada a pmx-50, y mitigación NFSv3¶
Dos meses de convivencia con el bug (automatización de más arriba) fueron suficientes
mientras los episodios eran raros y se autorrecuperaban. Dejaron de serlo: el NAS se
reinició dos mañanas seguidas (node_boot_time_seconds en Prometheus, no inferido):
3-ago 07:50 y 4-ago 06:59, tras una semana entera estable (26-jul → 3-ago). El
nas-volume-selfheal.sh (vigilante B) se disparó de verdad ambas veces, exactamente
como estaba diseñado: nfsd crítico (≥50 % en D) sostenido >10 min → sysrq-b. Cierra el
punto abierto de que "nunca se ha ejecutado de verdad".
Hallazgo nuevo: la cascada se lleva por delante a pmx-50¶
El 4-ago, mientras el NAS estaba en el deadlock (06:33–06:57), pmx-50 (el hipervisor
físico) también se reinició en seco (06:44:49 → 06:45:35, arranque startall de
VM208+PBS+ha-ml juntos). Su log de systemd se corta en seco a las 06:44:49 sin secuencia de
apagado — nada de shutdown.target — justo después de 2+ minutos de pvestatd fallando en
bucle contra el storage terramaster (unable to activate storage 'terramaster' -
directory... unreachable). wdctl confirma que pmx-50 tiene un watchdog hardware SP5100
TCO armado con timeout de 10 segundos, alimentado por watchdog-mux de la HA de Proxmox
(ha-manager status → fencing armed (CRM watchdog active)). La hipótesis mejor sostenida
(no probada con una línea de log literal — un reset por watchdog no llega a volcar el log
final) es auto-fencing de la HA de Proxmox: el atasco de E/S generalizado impidió que
pve-ha-crm/lrm refrescaran el watchdog a tiempo. VM208 volvió a las 06:45 y arrancó
contra un NAS que seguía colgado hasta las 06:59 — cascada plausible hacia el cuelgue de
dockerd de 9h+ que reportó Vera ese mismo día.
El arreglo de fondo real: no es TOS 7, es Linux 6.1.129¶
Investigado en el tracker de Debian (bug #1071562),
firma idéntica (nfsd4_destroy_session → __flush_workqueue deadlock). Confirmado roto
en 6.1.85–6.1.119, arreglado en 6.1.129 — dentro de la misma rama 6.1.x que ya corre TOS,
sin necesitar el salto a TOS 7. TerraMaster ya ha movido este punto antes sin salto de
versión mayor (TOS 6.0.650 subió 6.1.58→6.1.120). El objetivo real a vigilar en changelog de
TOS 6.0.8xx+ es kernel ≥6.1.129, no "TOS 7".
No intentar sustituir el kernel a mano. TOS es un appliance con parches de vendor sobre BTRFS/RAID/hardware; un kernel fuera de su flujo de actualización firmado arriesga romper esa integración en una caja con el único RAID5 de casa detrás.
Due diligence sobre TOS 7 en el foro oficial (2026-08-04) — más riesgo del esperado¶
Leído el hilo oficial de release (forum.terra-master.com t=10183) y el de compatibilidad F4-423/NVMe (t=9591, buscar "kernel version load"). Tres hechos nuevos, dos buenos y uno que pesa más que el resto:
- Paquete exacto:
TOS 7.0.0747(MD5ba39bd4b7df89998d12af118beb3eba9) es el update real desde TOS 6.0.794 — no7.0.0746, que es sólo para quien ya estaba en la beta. TM Support no publica el kernel exacto en las notas de este release (la página desupport.terra-master.comcon el changelog completo devolvió 500 al intentar leerla) — sigue sin confirmar si trae ≥6.1.129. No asumir nada sin volver a intentarlo antes de actualizar. - Bueno: el gotcha de BIOS/NVMe no aplica aquí. El F4-423 está en la lista de modelos
que necesitan reordenar el boot de BIOS si el disco de sistema TOS vive en el M.2 NVMe.
Verificado en vivo (
lsblk+findmnt /): el/de este NAS está enmd9, RAID1 sobre las tres HDD SATA (sda2/sdb2/sdc2) — el Crucial P310 NVMe es sólo la capa HyperCache (vg0-fc1_cpool), no el disco de sistema. El paso de BIOS del foro no aplica. - Malo: riesgo real y confirmado de romper permisos NFS/SMB, no sólo teórico. Las notas
oficiales avisan de una "conversión de permisos" obligatoria post-update (400.000 carpetas
≈ 3h) y de que hay que reconfigurar shared folders creados por Snapshot. Un usuario
real del foro (
Schnorra, 20-jul-2026, mismo hilo del gotcha BIOS) confirma el problema en producción: "Upgraded to TOS7 no problem, BUT all my SMB/share permissions are borked and now all my media streaming libraries are broken" — TM Support responde que es el comportamiento esperado de la conversión y que hay que reconfigurar a mano. Este NAS depende de un export NFS conanonuid=1001,anongid=997+ ACLs manuales (setfacl -R -m u:1000:rwx) para salvar el mismatch uid 0↔1000 con media-208 — es exactamente el tipo de configuración "no estándar" con más probabilidad de no sobrevivir una conversión automática. Un TOS7 fallido en la conversión de permisos rompería el acceso de todos los clientes NFS a la vez, incluidos los 3 que ya se movieron a NFSv3 hoy. - Sin confirmar, pero avisado en notas oficiales: "After the update, the device IP
address may change". Este NAS tiene IP estática
.20desde la renumeración del 2026-07-31, referenciada por IP literal enstorage.cfgde pmx-50/51, el autofs de VM208, y los dos mounts de Supervisor de HA. Un cambio de IP durante el update rompería los cuatro a la vez. Verificar esto explícitamente (o fijarla de nuevo tras el update) antes de dar por buena cualquier futura actualización a TOS7.
Conclusión revisada: el caso para TOS 7 es más débil de lo que parecía el 4-ago por la mañana — no sólo el beneficio del kernel sigue sin confirmarse, sino que ahora hay un riesgo concreto y reportado de romper la configuración de permisos NFS que sostiene todo el media stack. Con la mitigación NFSv3 ya desplegada en 3/4 clientes sin tocar el NAS para nada, no hay prisa — esperar a que el kernel real de un TOS 6.0.8xx o TOS7 posterior se confirme ≥6.1.129 antes de considerar cualquier actualización mayor.
Mitigación desplegada: NFSv3 en 3 de 4 clientes¶
nfsd4_destroy_session no existe en NFSv3 (protocolo sin estado, sin sesiones ni canal
de callback — son conceptos de NFSv4.1+). Cambiar de versión de protocolo evita la clase
entera de bug sin esperar al parche de kernel. Confirmado servidor: rpcinfo -p en el NAS
ya anunciaba v3 y v4 a la vez, sin tocar /etc/nfs.conf.
Pilotado con un mount de prueba en paralelo (lectura + escritura + limpieza, sin tocar producción) antes de aplicar en real. Desplegado 2026-08-04:
| Cliente | Mount | Antes | Después |
|---|---|---|---|
| pmx-50 / pmx-51 | terramaster (storage.cfg, backend datastore PBS archive, 872 GB) |
v4.2, hard | v3, hard (sin tocar) |
| VM 208 | /mnt/nfs_media (autofs) |
v4.2, soft | v3, soft |
| HA / VM 171 | terramaster_media + terramaster_backup (Supervisor) |
v4.2, softerr | CIFS vers=2.0 — ver abajo (protocolo distinto, no NFSv3) |
Por qué terramaster (pmx) no pasó también a soft: ese mount tiene detrás
pbs-archive.img, un loop-image ext4 de 872 GB que es el datastore archive de PBS
(LXC 186, bind mount mp1: /mnt/pbs-archive). Un mount soft puede devolver error en una
escritura a mitad si el NAS se cuelga — para un filesystem-en-un-fichero de backups reales,
eso es peor que el hipervisor colgándose. Se dejó hard a propósito.
Procedimiento real usado en pmx-50 (LXC 186 tenía el bind mount activo, que ancla el
NFS — no basta con systemctl stop mnt-pbs\x2darchive.mount):
pct shutdown 186 --timeout 30 # libera el bind mount
systemctl stop "mnt-pbs\x2darchive.mount" # desmonta el loop ext4
umount /mnt/pve/terramaster # ahora sí, limpio
pvesm set terramaster --options vers=3 # storage.cfg es cluster-wide
systemctl start "mnt-pve-terramaster.mount" # remonta con v3
systemctl start "mnt-pbs\x2darchive.mount" # reengancha el loop
pct start 186
pct exec 186 -- proxmox-backup-manager prune-job run archive-prune # TASK OK, verificado
VM 208 (/etc/auto.nfs_media, -fstype=nfs4,... → -fstype=nfs,vers=3,...): el
autofs de este mount usa timeout=0 (no expira solo), así que el cambio exige desmontar a
la fuerza + retrigger. Eso deja stale los bind mounts Docker de los 21 contenedores que
montan /mnt/nfs_media (ver gotcha del 2026-07-16 más abajo en este mismo runbook set) —
se resolvió con nfs-health-monitor.sh rebind, que ya existía para exactamente este caso.
Verificado: jellyfin/sonarr/radarr/bazarr healthy, /data con el conteo de ficheros
esperado.
HA (VM 171) inicialmente se quedó en v4.2 — límite de plataforma, no elección: el mount
manager de Supervisor sólo expone --version para mounts CIFS (ha mounts update --help).
Probado además contra la API cruda (PUT /mounts/terramaster_media con "version":"3"):
responde 200 ok pero lo ignora en silencio — tras reload el mount seguía en v4.2.
Actualización (mismo día, más tarde): HA movida a SMB, no a NFSv3¶
En vez de forzar NFSv3 en un mount que Supervisor gestiona (que habría exigido salirse de
su gestión, con riesgo de que lo revirtiera en el próximo reinicio/update — sistema que
controla cosas físicas de casa, portero y calefacción), se cambió el protocolo entero:
el NAS ya exporta [Media] y [backups] por Samba (mismos paths). nfsd4_destroy_session
no existe en absoluto en Samba — es un daemon completamente distinto (smbd, no nfsd), así
que esto no es una mitigación del bug, es quitarse del código que lo tiene.
smbpasswd -s -a monxas # el usuario samba ya existía, sin password conocido
# Supervisor sólo acepta cifs vers "2.0" (no "3.0"/"3"/"3.1.1" — 400 de vuelta)
curl -X PUT .../mounts/terramaster_media -d '{"type":"cifs","share":"Media",...,"version":"2.0"}'
curl -X PUT .../mounts/terramaster_backup -d '{"type":"cifs","share":"backups",...,"version":"2.0"}'
Verificado: mount en HA muestra cifs vers=2.0, listado de /media/terramaster_media
correcto. Con esto, los 4 clientes conocidos están fuera de NFSv4 (3 en NFSv3, 1 en
CIFS) — el disparador del bug (reconexión de sesión NFSv4.1+) ya no puede venir de ningún
tráfico propio de esta casa.
Intentado y descartado: subir el pool de hilos nfsd (8→32)¶
Con el trigger casi eliminado, esto era ya sólo colchón — pero se intentó de todas formas.
No es posible sin parchear binarios propietarios. /etc/nfs.conf (threads=) y
/etc/default/nfs-kernel-server (RPCNFSDCOUNT=) se sobrescriben en cada arranque del
servicio: nfs-server.service ejecuta nfsdconf (symlink a un binario TOS allconf) que
regenera /usr/share/nfs-kernel-server/conffiles/nfs-kernel-server.default con 8
hardcodeado — no hay campo para esto en /etc/tos/config/nfs.json ni en la UI. Mismo tipo
de límite de plataforma que el de Supervisor de arriba. Revertido a estado original.
Añadido: alerta temprana antes del auto-reboot¶
Nueva métrica Prometheus nfsd_threads_dstate{host="tnas"} (collector
/usr/local/bin/nfsd-dstate-collect.sh en el NAS, cron cada minuto, mismo patrón que
smart-collect.sh) expone exactamente la señal que ya usaba nas-volume-selfheal.sh
internamente, pero ahora visible fuera del NAS. Dos alertas nuevas en el grupo nas_health:
nas_nfsd_dstate_degraded (warning, ≥1 hilo en D sostenido 2min) y
nas_nfsd_dstate_critical (critical, ≥50% sostenido 3min — el vigilante reinicia solo a
los 10min, así que esto llega antes del reboot automático, no lo sustituye). Validado
con promtool check rules antes de desplegar. Objetivo: pasar de "sorpresa a las 7am" a
"aviso con tiempo de reaccionar", aunque ahora mismo el disparador de esto ya no debería
poder venir de ningún cliente propio.
Actualización 2026-08-05: NO era el mismo bug — nuevo culpable real, y agujero de alertas cerrado¶
La noche del 4→5 de agosto el NAS volvió a tocar 8/8 hilos nfsd en D varias veces
(02:03→07:11+, dos veces 8/8 completo, llegó a 445/600s del auto-reboot a las 06:45). Con
los 4 clientes ya fuera de NFSv4 desde el día anterior, la primera lectura obvia — "el bug
volvió pese a todo" — era incorrecta. Dos hallazgos la desmienten:
- La firma del kernel es otra. Las pilas capturadas esa noche muestran
nfsdbloqueado enbtrfs_inode_lock,folio_wait_bit_common,balance_dirty_pages,btrfs_start_ordered_extent— cero apariciones denfsd4_destroy_session/rpc_shutdown_clienten toda la ventana. Contención de locks de BTRFS bajo escritura pesada, no el deadlock de sesiones NFSv4.1+. - Los hilos se recuperaban. El conteo de D subía y bajaba toda la noche (8→1→3→8→3…) en vez de solo subir — la firma de un deadlock permanente (como el de julio) es monotónica: nunca baja. Esto sí bajaba: contención transitoria, no pérdida de hilos.
Causa real, encontrada por Vera a las 07:13: el sync job de PBS main-to-archive
(LXC 186, pull de main (ZFS local) a archive (NFS sobre el NAS), schedule: 04:30)
se quedó escribiendo sin parar desde las 04:30, saturando NFS/BTRFS durante ~2.5h. Su propio
log interno de PBS marcaba TASK ERROR: sync aborted a las 05:11, pero algo por debajo
siguió escribiendo hasta que Vera lo paró a mano a las 07:13 (D-state 8→0, load 12→6, Recv-Q
drenada). Historial del job: sus últimas ejecuciones registradas (11–16 de mayo) fallaban
todas con unable to open chunk store at "/archive/.chunks" — el mismo problema de
montaje inestable de siempre — y no hay entradas entre mayo y esta madrugada. Todo apunta a
que anoche fue su primera ejecución real desde que el mount del archive se volvió fiable
(arreglo del 2026-08-04), intentando sincronizar de golpe un main con datos de meses.
Programación del sync job desactivada (sync-job update main-to-archive --delete
schedule) hasta investigarlo con calma — no es un fix de una línea, y no hace falta que
vuelva a dispararse sólo antes de mirarlo.
Agujero real: la alerta nueva de anoche no llegó a Telegram cuando más falta hacía¶
La política documentada del homelab es clara: GRAVE (riesgo de datos o caída total) →
Telegram al instante vía un carril dedicado en Alertmanager + Vera en paralelo, sin
depender de que las herramientas propias de Vera (message, PushNotification) funcionen
— precisamente para que un fallo de esas herramientas no te deje a ciegas. La alerta
nas_nfsd_dstate_critical que se añadió anoche (ver más arriba) nunca se registró en ese
carril — ni en el matcher de alertmanager.yml ni en GRAVE_ALERTS de
alert-bridge.py (LXC 100) — así que a las 06:46, cuando el NAS estaba a 445/600s del
auto-reboot, sólo se intentó avisar por message (MCP desconectado) y PushNotification
(Remote Control inactivo). Ninguno de los dos llegó. El aviso real no llegó hasta el
digest de las 6h. Corregido: nas_nfsd_dstate_critical añadido a ambos matchers, validado
con amtool check-config + amtool config routes test (resuelve a telegram-grave,vera),
desplegado y recargado en ambos servicios.
Lección: cualquier alerta critical/GRAVE nueva tiene que registrarse en los DOS
sitios (matcher de Alertmanager + GRAVE_ALERTS en el bridge) en el mismo cambio que la
crea, no después. Ver el GOTCHA ya documentado en alertas_silencio_primero.md: "si
divergen, Vera calla sobre algo que ya te avisó, o al revés" — se aplicó al revés esta vez
(Vera SÍ lo intentó, pero por el canal equivocado).
Actualización 2026-08-05 (tarde): NOCOW rebuild del archive + fencing de pmx-50 confirmado y arreglado + sync job reactivado¶
Con la causa mecánica del btrfs_inode_lock de la sección anterior ya identificada
(fragmentación CoW), esta tarde se atacó de raíz en vez de dejar el sync job apagado
indefinidamente.
1. pbs-archive.img tenía 572.988 extents. El datastore archive de PBS es un ext4
dentro de un fichero sparse de 1.65TB sobre BTRFS (pbs-archive.img, montado por loop) —
estructuralmente idéntico a una imagen de disco de VM, el patrón que peor lleva BTRFS
reescrito in-place, y nunca se le puso chattr +C (NOCOW). Reconstruido con
cp --sparse=always a un fichero nuevo con NOCOW desde el arranque, gobernador adaptativo
(pausa el cp con SIGSTOP si el D-state del NAS llega a 3, reanuda tras 20s limpios) para
no repetir el incidente mientras se reescriben ~996GB reales. Panel de seguimiento en vivo
(index.html + status.json, servido por python3 -m http.server 8765 en el NAS) —
detalle completo del proceso y las instrucciones en /root/nocow-rebuild/PLAN.md del NAS.
Verify de PBS tras el swap: 25/26 grupos limpios. El único fallo
(vm/208/2026-08-04T01:22:28Z, manifest load error) no era corrupción del rebuild — el
directorio sólo tenía .tmp sin finalizar, un snapshot a medio escribir de un intento
anterior del sync job que la copia (byte-a-byte, preserva metadatos del ext4 interno) se
limitó a heredar tal cual. Se borró (no era un snapshot válido, no hay pérdida real: el día
antes y el día después están íntegros) y se liberó pbs-archive.img.pre-nocow-backup
(~1TB) tras confirmar que el resto verificaba limpio.
2. Al reactivar el sync job sin rate-in para probar el arreglo, pmx-50 entero se cayó.
No fue el NAS esta vez — el nfsd D-state se quedó en 0-2 todo el rato, nada que ver con el
8/8 de antes. El host físico completo (con las 8 VMs/LXCs que aloja, incluida la 208) tuvo
un hard lockup y volvió por un reset, sin panic ni traza en pstore. Esto confirma, esta
vez con línea de log literal, la hipótesis abierta desde el 4-ago: a las 22:18:10, en
mitad de la sincronización del disco de la 208, el kernel de pmx-50 empezó a repetir
nfs: server 192.168.0.20 not responding, still trying — y el log de ese arranque termina
segundos después. El motivo: el storage terramaster de pmx-50 (/etc/pve/storage.cfg,
usado también por la 51 vía config de cluster) sólo tenía vers=3 — montaje hard sin
soft/timeo/retrans, a diferencia de los 4 clientes NFSv4→v3 ya endurecidos el 4-ago.
Un hard mount bloquea indefinidamente ante cualquier hipo del servidor en vez de
devolver error — con la transferencia a máxima velocidad fue suficiente para atascar el
kernel entero.
Arreglo: pct stop 186 → systemctl stop mnt-pbs\x2darchive.mount (loop) →
umount /mnt/pve/terramaster → pvesm set terramaster --options vers=3,soft,timeo=150,retrans=3
→ remount NFS → remount loop → pct start 186. (El guard timer
pbs-archive-guard.timer re-monta el loop cada 5 min si lo ve caído — hay que pararlo
mientras se hace esto a mano, si no compite con el unmount.) storage.cfg es de cluster, así
que pmx-51 recoge las mismas opciones en su próximo remount — no se ha forzado ahí porque no
aloja la 208 y no está implicado en esta caída, pero queda pendiente si algún día usa este
storage con más intensidad.
Reintento tras el arreglo: limpio. TASK OK, pasó sin incidente por el mismo snapshot
que tumbó el host la vez anterior (126.8 MiB/s), 25.57 GiB en 23.046 chunks a 82 MiB/s de
media, sin D-state, sin caída. Sync job reactivado (schedule: 04:30, sin rate-in —
no hizo falta limitarlo una vez arregladas las dos causas reales).
Qué queda abierto¶
- Kernel ≥6.1.129 (o una versión de TOS que lo traiga) sigue siendo el único arreglo de fondo real en el servidor para el bug original de julio. Del lado cliente ya no queda ninguno de los 4 conocidos tocando NFSv4 — pero un quinto cliente futuro (o alguien montando a mano) sí podría.
- El umbral del 50 % del vigilante sigue siendo un juicio, no un valor derivado de datos — aunque ahora sí sabemos que dispara correctamente en un incidente real, dos veces.
- Las dos alertas nuevas de
nfsd_threads_dstateno se han visto disparar en un incidente real — sólo verificado que cargan (promtool) y que el estado en reposo es correcto (inactive, valor 0). - La reconciliación de contenedores del 208 sigue sin verse en una avería real en la que de verdad hiciera falta (las dos de agosto se resolvieron con el reboot del NAS + rebind manual de este mismo trabajo, no con la reconciliación automática).
- Prometheus retiene "30d o 5 GiB" y manda el tamaño: los datos del NAS sólo llegan a ~20 días.