El passthrough USB en Proxmox funciona muy bien… hasta que deja de hacerlo. Un minuto tu coordinador Zigbee está activo, tu UPS informa correctamente o tu SSD externo sirve copias de seguridad. Al minuto siguiente: el dispositivo desaparece, los logs de la VM se llenan de reconexiones y la automatización en la que confiabas empieza a comportarse como si tuviera voluntad propia.
Normalmente esto no es “un bug de Proxmox”. Es energía, gestión de energía en tiempo de ejecución, reinicios del controlador, hubs defectuosos o un desajuste sutil entre cómo pasaste el dispositivo y cómo espera Linux que se comporte bajo carga. La buena noticia: puedes volver a hacer que el USB sea aburrido. La mejor noticia: puedes probar qué capa está fallando antes de cambiar nada.
Guía de diagnóstico rápido
Cuando el passthrough USB falla en producción, no tienes tiempo para danza interpretativa. Necesitas una secuencia ajustada que separe: fallo del dispositivo, problemas de energía, gestión de energía del kernel, comportamiento de reinicio del controlador y la tubería de virtualización.
Primero: determina dónde ocurre la desconexión
- ¿Sólo en el host? Los logs del kernel del host muestran desconexiones y reenumeraciones. La VM/contenedor sólo ve “dispositivo desaparecido”. Arregla primero energía/PM/controlador en el host.
- ¿Sólo en el invitado? El host ve USB estable, pero el driver del invitado se reinicia. Enfócate en el kernel del invitado, la elección de emulación USB de QEMU y cómo pasaste el dispositivo.
- ¿Sólo físico? LED del dispositivo parpadea/se resetea, clics del hub u otros dispositivos en el mismo hub también caen. Arregla energía, cable, hub o puerto.
Segundo: captura la evidencia mientras sucede
- Ejecuta
dmesg -Twen el host Proxmox durante una caída. - Revisa los logs del invitado en la misma marca temporal.
- Correlaciona si el bus se reinicia (
usb X-Y: reset) o si el dispositivo se desconecta (disconnect).
Tercero: clasifica el modo de fallo
- Brownout / subtensión: desconexiones bajo carga; el hub o el puerto muestran eventos de energía; múltiples dispositivos pueden caer juntos.
- Autosuspend: caídas tras un periodo de inactividad; intervalo recurrente; despierta con tráfico y hace flapping.
- Quirks de reinicio xHCI: “xHCI host controller not responding” o frecuentes “reset SuperSpeed Gen 1 USB device”.
- Enfoque de passthrough inadecuado: passthrough de dispositivo a QEMU funciona hasta que el dispositivo se re-enumeriza con una ruta distinta; es necesario pasar por bus/puerto o controlador.
Cuarto: aplica la solución mínima efectiva
- Cambia cable/puerto/hub y utiliza un hub alimentado cuando corresponda.
- Desactiva autosuspend para ese dispositivo (no globalmente, salvo que estés desesperado).
- Si es un problema crónico de reinicios xHCI: pasa todo el controlador USB vía PCIe (IOMMU), o aplica quirks conservadores del kernel.
Cómo falla realmente el passthrough USB (y por qué no es aleatorio)
USB parece simple a nivel humano: enchufar y funciona. Bajo el capó es una negociación entre dispositivo, hub, controlador host, drivers del kernel y políticas de energía. Añade virtualización y ahora hay dos kernels y un hipervisor implicados en esa negociación.
La mayoría de las desconexiones “aleatorias” de USB siguen unos pocos patrones previsibles:
- Inestabilidad de enumeración: el dispositivo se desconecta y vuelve con una dirección distinta. Si tu passthrough estaba anclado a un identificador frágil, el invitado lo pierde.
- Gestión de energía en tiempo de ejecución: Linux intenta ahorrar energía suspendiendo el dispositivo. Algunos dispositivos interpretan eso como “hora de entrar en pánico”.
- Integridad de señal: cables marginales, extensiones sin blindaje y hubs sobrecargados crean errores CRC y reinicios, especialmente a velocidades USB 3.x.
- Comportamiento de reinicio del controlador: los controladores xHCI pueden entrar en tormentas de reinicio en ciertas condiciones, y la lógica de recuperación del kernel no siempre es amable con sesiones de larga duración.
- Temporización y buffering virtualizados: los drivers del invitado a veces se comportan distinto cuando el transporte USB es emulado o mediado por QEMU en lugar de ser nativo.
También hay una verdad dura: muchos dongles populares (sticks Zigbee, Z-Wave, RTL-SDR) fueron diseñados para escritorios de aficionado, no para servidores siempre encendidos detrás de un hub ruidoso en una estantería. Aún puedes hacerlos fiables. Solo necesitas tratarlos como dependencias de producción, no como accesorios bonitos.
Idea parafraseada de Werner Vogels (CTO de Amazon): construyes fiabilidad asumiendo que las cosas fallarán y diseñando para que los fallos no se conviertan en outages.
Un chiste, ya que vamos a leer logs un rato: USB significa “Unexpected Sudden Bye-bye”. No es oficial, pero encaja con los tickets.
Hechos interesantes y contexto histórico
- Autosuspend USB ha sido una característica de Linux por años, y se ha vuelto más agresiva al imponerse defaults de ahorro por portátiles. Los servidores heredan esos valores por defecto a menos que los sobrescribas.
- xHCI reemplazó a EHCI/OHCI/UHCI cuando llegó USB 3.x, consolidando complejidad en un solo modelo de controlador. Excelente para funcionalidades; ocasionalmente complicado para la estabilidad.
- Las direcciones de dispositivo USB no son identificadores estables. Se asignan durante la enumeración y pueden cambiar tras un reset. Si tu configuración depende de una dirección cambiante, fallará eventualmente.
- Algunos puertos “USB 3” comparten hubs internos en placas base, lo que significa que dos puertos físicos pueden ser un hub raíz lógico. Un reinicio puede tumbar ambos.
- El passthrough USB en VMs comenzó con controladores emulados (UHCI/OHCI/EHCI en QEMU). Las configuraciones modernas prefieren passthrough de dispositivo host o de controlador entero para mayor fiabilidad.
- Selective suspend en Windows y autosuspend en Linux resuelven problemas similares con ajustes distintos. Muchos dispositivos se prueban contra defaults de Windows, no contra cargas de servidores Linux.
- USB 3.x usa pares “SuperSpeed” adicionales más allá de los cables de USB 2.0. Un cable que “funciona bien” a USB 2.0 puede fallar estrepitosamente a velocidades USB 3.x.
- El passthrough PCIe de un controlador USB suele arreglar la inestabilidad al eliminar la capa de emulación y dar al invitado control nativo—con el coste de flexibilidad.
Tareas prácticas: comandos, salidas y la decisión que tomas
Estas son operaciones reales que puedes ejecutar en un host Proxmox. Cada tarea incluye: comando, qué buscas y qué decisión tomas a continuación. Ejecútalas durante operación normal y durante una falla si puedes.
Task 1: Watch host kernel events live
cr0x@server:~$ sudo dmesg -Tw
[Thu Dec 26 11:18:02 2025] usb 2-2: USB disconnect, device number 7
[Thu Dec 26 11:18:03 2025] usb 2-2: new full-speed USB device number 8 using xhci_hcd
[Thu Dec 26 11:18:03 2025] usb 2-2: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
[Thu Dec 26 11:18:03 2025] usb 2-2: Product: CP2102N USB to UART Bridge Controller
Qué significa: El host perdió el dispositivo y lo reenumeró. Esto no es “sólo invitado”.
Decisión: Enfócate en la gestión de energía del host, cableado, hub y reinicios del controlador. La afinación del invitado sola no arreglará desconexiones físicas.
Task 2: Confirm what Proxmox thinks is attached (VID:PID and path)
cr0x@server:~$ lsusb
Bus 002 Device 008: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
Bus 002 Device 002: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1d6b:0002 Linux Foundation 2.0 root hub
Qué significa: Tienes un dispositivo CP210x en Bus 002. El número de dispositivo puede cambiar. Vendor/product es estable.
Decisión: Prefiere pasar por vendor/product y ruta de puerto físico (bus/port) en vez de por número de dispositivo.
Task 3: Get a stable physical topology (find the port chain)
cr0x@server:~$ lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/8p, 5000M
|__ Port 2: Dev 8, If 0, Class=Vendor Specific Class, Driver=cp210x, 12M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/14p, 480M
Qué significa: El dispositivo está en Bus 02, Puerto 2 del hub raíz. Esa relación física es el ancla que quieres.
Decisión: Si puedes mantenerlo en el mismo puerto/cadena de hub, puedes escribir reglas udev deterministas y configuraciones de passthrough en Proxmox.
Task 4: Inspect USB power control state for the device
cr0x@server:~$ DEVPATH=$(udevadm info -q path -n /dev/ttyUSB0); echo "$DEVPATH"
/devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0
cr0x@server:~$ cat /sys$DEVPATH/power/control
auto
Qué significa: Runtime PM está habilitado (auto). El kernel puede autosuspender esta interfaz.
Decisión: Si ves desconexiones tras inactividad, establece esto a on vía regla udev (específica del dispositivo) o desactiva autosuspend.
Task 5: Check autosuspend delay for the interface
cr0x@server:~$ cat /sys$DEVPATH/power/autosuspend_delay_ms
2000
Qué significa: El sistema está dispuesto a autosuspender después de 2 segundos de inactividad. A muchos dongles no les gusta esto.
Decisión: Para adaptadores seriales, coordinadores, HID de UPS y SDRs: desactiva autosuspend para ese dispositivo.
Task 6: Verify the USB controller and its driver (xHCI, etc.)
cr0x@server:~$ lspci -nnk | grep -A3 -i usb
00:14.0 USB controller [0c03]: Intel Corporation Device [8086:a36d] (rev 10)
Subsystem: Intel Corporation Device [8086:7270]
Kernel driver in use: xhci_hcd
Kernel modules: xhci_pci
Qué significa: Tu controlador USB es Intel xHCI en 00:14.0.
Decisión: Si luego eliges passthrough PCI del controlador, este es el dispositivo que deberías aislar y pasar (si está en su propio grupo IOMMU seguro).
Task 7: Check IOMMU enablement (required for PCIe controller passthrough)
cr0x@server:~$ dmesg | grep -E "DMAR|IOMMU" | head
[ 0.812345] DMAR: IOMMU enabled
[ 0.812678] DMAR: Host address width 39
[ 0.813210] DMAR: DRHD base: 0x000000fed91000 flags: 0x0
Qué significa: VT-d/IOMMU está activado y el kernel lo detecta.
Decisión: Puedes considerar pasar todo un controlador USB si está en un grupo IOMMU sensato.
Task 8: Determine IOMMU group for the USB controller
cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do
if [[ "$d" == *"0000:00:14.0"* ]]; then echo "USB controller is in: ${d%/*}"; fi
done
USB controller is in: /sys/kernel/iommu_groups/5/devices
Qué significa: El controlador está en el grupo 5. Debes confirmar que el grupo 5 no incluya dispositivos que no puedas ceder a una VM (como SATA o la NIC).
Decisión: Si el grupo incluye dispositivos críticos, no pases ese controlador; usa una tarjeta PCIe USB separada en su lugar.
Task 9: List everything in the same IOMMU group
cr0x@server:~$ ls -1 /sys/kernel/iommu_groups/5/devices
0000:00:14.0
0000:00:14.2
Qué significa: Hay otro dispositivo (00:14.2) en el grupo. Necesitas identificarlo antes de cualquier passthrough.
Decisión: Si es algo como Intel PCH thermal o MEI, podrías decidir; si es almacenamiento/NIC, detente.
Task 10: Inspect Proxmox VM config for fragile USB mapping
cr0x@server:~$ sudo cat /etc/pve/qemu-server/101.conf
agent: 1
boot: order=scsi0;net0
cores: 4
memory: 4096
net0: virtio=DE:AD:BE:EF:00:01,bridge=vmbr0
scsi0: local-lvm:vm-101-disk-0,iothread=1,size=32G
usb0: host=10c4:ea60
Qué significa: Esta VM pasa el dispositivo por VID:PID, lo cual suele ser bueno. Pero si tienes múltiples dongles idénticos, puede seleccionar el equivocado.
Decisión: Si tienes más de un dispositivo coincidente, pasa por bus/port (o usa udev para crear symlinks estables y enlazar por serial/ruta).
Task 11: Confirm if the device has a serial number you can pin to
cr0x@server:~$ sudo udevadm info -a -n /dev/ttyUSB0 | grep -E "serial|idVendor|idProduct" | head -n 10
ATTRS{idVendor}=="10c4"
ATTRS{idProduct}=="ea60"
ATTRS{serial}=="01A2B3C4"
Qué significa: Genial: se expone un serial estable. Esto es oro para reglas y asignación estable.
Decisión: Escribe reglas udev para ajustar power/control y crear symlinks estables basados en serial.
Task 12: Check if usbcore autosuspend is globally enabled via kernel cmdline
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-4-pve root=/dev/mapper/pve-root ro quiet intel_iommu=on
Qué significa: No hay un ajuste explícito de usbcore autosuspend. Aplican los valores por defecto (a menudo autosuspend activado).
Decisión: Prefiere soluciones específicas por dispositivo, pero si estás depurando puedes temporalmente probar con usbcore.autosuspend=-1 para verificar la hipótesis.
Task 13: Validate whether runtime PM is actually suspending the device
cr0x@server:~$ cat /sys$DEVPATH/power/runtime_status
suspended
Qué significa: La interfaz está suspendida ahora. Si tu servicio espera presencia constante, esto es una señal de alerta.
Decisión: Desactiva autosuspend para el dispositivo y observa si las desconexiones cesan.
Task 14: Check for xHCI “controller not responding” patterns
cr0x@server:~$ journalctl -k -b | grep -i -E "xhci|host controller|not responding|reset" | tail -n 12
Dec 26 10:55:14 server kernel: xhci_hcd 0000:00:14.0: xHCI host controller not responding, assume dead
Dec 26 10:55:14 server kernel: xhci_hcd 0000:00:14.0: HC died; cleaning up
Dec 26 10:55:15 server kernel: usb 2-2: USB disconnect, device number 7
Dec 26 10:55:17 server kernel: xhci_hcd 0000:00:14.0: xHCI Host Controller
Dec 26 10:55:17 server kernel: xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 2
Qué significa: Esto es un reinicio a nivel de controlador. Todo lo que esté bajo ese controlador caerá, no sólo tu dongle.
Decisión: Deja de perder tiempo en ajustes por dispositivo. Añade un controlador USB dedicado (PCIe) o pásalo entero por PCI a la VM.
Energía e integridad de señal: la causa raíz poco glamurosa
Si quieres passthrough USB estable, comienza asumiendo que tu instalación está subalimentada o eléctricamente desordenada. Esa suposición suele ser correcta, y es más barato que perseguir bugs fantasma.
Patrones comunes relacionados con la energía
- “Se desconecta bajo carga”: el SSD externo cae cuando comienza la copia; el dongle SDR cae cuando aumenta el muestreo; el stick Zigbee cae cuando la radio transmite más.
- “Varios dispositivos caen juntos”: indica reinicio del hub o controlador, o caída de la línea de alimentación compartida.
- “Funciona en escritorio, falla en servidor”: los puertos de escritorio suelen tener topología de hub distinta y a veces mejor cableado frontal que ese adaptador de header interno que usaste en el servidor.
Qué hacer (opinión personal)
Usa un hub alimentado para dongles de baja calidad y cualquier tramo de cable largo. Sí, incluso si el dispositivo “debería” consumir poco. Muchos dongles están bien en promedio pero pican en momentos molestos. El regulador del hub y la capacitancia de reserva suelen marcar la diferencia.
Evita cables USB 3 baratos. La integridad de señal en USB 3 es menos tolerante. Si necesitas una carrera larga, usa un cable de alta calidad o mantén USB 2 cuando sea posible.
Prefiere los puertos traseros directamente en la placa base. Los headers del panel frontal y los cables internos de bracket son un impuesto a la fiabilidad.
Cómo probar que es energía
- Las desconexiones se correlacionan con la actividad del dispositivo, no con el tiempo.
- Mover el dispositivo a un hub alimentado o a otro puerto reduce o elimina las caídas.
- Ves mensajes de “over-current” o “power surge” (menos comunes, pero muy reveladores).
Segundo chiste (y el último): un hub alimentado es básicamente una carta de disculpa a la física con un transformador adjunto.
Autosuspend y runtime PM: el asesino silencioso de dispositivos
La gestión de energía en tiempo de ejecución de Linux es una buena idea con una mala costumbre: asume que los dispositivos implementan la especificación correctamente. Muchos lo hacen. Algunos no lo hacen en absoluto. Para adaptadores seriales USB, coordinadores de radio y dispositivos tipo HID que actúan como simples, autosuspend puede provocar flapping o “device vanished” que parece fallo de hardware.
Tres enfoques, de mejor a peor
1) Desactivar autosuspend por dispositivo vía udev (preferido)
Encuentra atributos identificadores (vendor/product, serial o interfaz) y fuerza power/control=on para ese dispositivo. Esto mantiene runtime PM habilitado para todo lo demás.
cr0x@server:~$ sudo tee /etc/udev/rules.d/99-usb-no-autosuspend.rules > /dev/null <<'EOF'
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="10c4", ATTR{idProduct}=="ea60", TEST=="power/control", ATTR{power/control}="on"
EOF
cr0x@server:~$ sudo udevadm control --reload-rules
cr0x@server:~$ sudo udevadm trigger
Qué significa: Los nuevos dispositivos que coincidan con VID:PID tendrán runtime PM forzado a on.
Decisión: Si tu dispositivo cae tras inactividad, esto suele ser la primera solución duradera.
2) Desactivar autosuspend globalmente (usar para pruebas; evitar como hábito)
Configurar usbcore.autosuspend=-1 desactiva autosuspend globalmente. Útil para probar causalidad rápidamente durante un incidente. Pero es un martillo.
cr0x@server:~$ sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="usbcore.autosuspend=-1 /' /etc/default/grub
cr0x@server:~$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.8.12-4-pve
done
Qué significa: El siguiente arranque desactivará globalmente el autosuspend de USB.
Decisión: Si la estabilidad mejora de inmediato, vuelve atrás e implementa reglas udev por dispositivo en lugar de dejar esto para siempre.
3) Tráfico keep-alive (a veces necesario, a menudo feo)
Algunos usuarios ejecutan lecturas/escrituras periódicas o polling para mantener despiertos los dispositivos. Es un paliativo cuando el firmware del dispositivo es frágil. También es como terminas con un cron que se convierte en “infraestructura crítica”.
Decisión: Usa keep-alives sólo cuando hayas demostrado que autosuspend es el disparador y los controles de energía por udev no lo doman.
Reinicios xHCI, quirks y soluciones a nivel de controlador
Si tus logs muestran que el controlador xHCI muere y vuelve, ya no estás tratando con “un dongle inestable”. Estás frente al controlador host o su interacción con el firmware, la gestión de energía PCIe o una combinación mala de dispositivos en el bus.
Reconocer reinicios de controlador
Estos patrones importan:
xHCI host controller not responding, assume deadHC died; cleaning up- Números de bus reasignados tras el reinicio
- Múltiples dispositivos USB desconectándose a la vez
Jerarquía de arreglos (haz esto en orden)
1) Sanidad de firmware/BIOS
- Actualiza BIOS/UEFI de la placa base. Los bugs de estabilidad USB en firmware son tristemente comunes.
- Desactiva “ErP” o funciones de sueño profundo que interfieran con las líneas de alimentación USB, si aplica.
- Considera desactivar PCIe ASPM en servidores que no lo necesitan. ASPM puede interactuar mal con algunos controladores.
2) Añadir un controlador USB PCIe dedicado (mi opción preferida)
Una tarjeta PCIe USB de $20–$50 con un chipset razonable puede aislar tus dispositivos problemáticos del controlador integrado PCH. Entonces puedes pasar ese controlador o mantenerlo en el host con ajustes de energía afinados.
Decisión: Si los reinicios de controlador matan la disponibilidad, compra aislamiento. Es más barato que tu tiempo.
3) Passthrough del controlador entero (PCI)
Para dispositivos que odian el passthrough mediado, dar al invitado control directo sobre el controlador USB suele ser la solución final. El invitado ve hardware nativo; reinicios y reenumeraciones permanecen dentro del invitado.
Contras: pierdes acceso del host a esos puertos y debes gestionar grupos IOMMU correctamente. Además: la migración en vivo puede complicarse o volverse imposible según tu configuración.
4) Parámetros del kernel y quirks (quirúrgico, pero hazlo con cuidado)
En ocasiones puedes mitigar la inestabilidad con parámetros del kernel que afectan xHCI o el comportamiento del core USB. Aquí debes mantener control de cambios estricto porque afectan al host.
Decisión: Si un controlador dedicado lo arregla, no te pongas creativo con quirks. Si debes usar quirks, documenta la justificación y los patrones de logs observados.
Elegir el modo de passthrough correcto (dispositivo vs puerto vs controlador)
La mayoría del dolor de passthrough USB en Proxmox es autoinfligido al elegir la granularidad equivocada. La elección correcta depende de cómo se comporta el dispositivo cuando se desconecta y re-enumeriza.
Opción A: Passthrough de un dispositivo USB (VID:PID)
Bueno para: dispositivos únicos con identidad estable, donde la re-enumeración no confunde el mapeo.
Malo para: múltiples dispositivos idénticos, o dispositivos que cambian de comportamiento entre modos (bootloader vs runtime) y presentan IDs distintos.
Modo de fallo: el dispositivo equivocado se conecta después de un reinicio, o el dispositivo desaparece y vuelve con un ID distinto y nunca se vuelve a adjuntar.
Opción B: Passthrough por ruta de bus/puerto
Esto es más determinista si el dispositivo permanece físicamente en el mismo puerto. También es menos flexible si mueves cables.
Bueno para: laboratorios y servidores donde el dongle es “parte de la máquina”, no un accesorio movible.
Opción C: Passthrough del controlador entero (PCI)
Bueno para: dispositivos que necesitan acceso a bajo nivel, dispositivos que re-enumerizan de forma problemática y configuraciones donde el invitado debe poseer la pila USB de extremo a extremo (VMs de Home Assistant son comunes aquí).
Malo para: hosts que necesitan esos puertos para funciones del host, o donde la agrupación IOMMU impide un aislamiento seguro.
VM vs LXC: qué cambia y qué no
Proxmox te da dos consumidores principales de USB: VMs QEMU y contenedores LXC. Las realidades hardware no cambian: la energía es energía, el controlador host es el controlador host y el kernel del host sigue en el loop a menos que pases un controlador PCI.
QEMU VMs
- Puedes adjuntar dispositivos USB a la VM vía passthrough del host.
- Si el host pierde el dispositivo, la VM también lo perderá.
- Pásar el controlador entero vía PCIe da al invitado enumeración nativa y suele ofrecer la mejor estabilidad.
LXC containers
- LXC comparte el kernel del host. No estás virtualizando la pila USB; estás otorgando acceso a nodos de dispositivo.
- Autosuspend y runtime PM son comportamientos del host. Arréglalos en el host.
- Permisos y reglas de cgroup de dispositivos importan: una “desconexión” puede ser en realidad “el nodo de dispositivo cambió y el contenedor no puede abrirlo”.
Regla de decisión: Si necesitas que un dispositivo USB delicado sea estable, una VM con passthrough PCIe del controlador USB suele ser la arquitectura más limpia. LXC es excelente, pero no es una frontera de aislamiento USB.
Errores comunes: síntoma → causa raíz → solución
1) El dispositivo cae exactamente tras unos segundos/minutos de inactividad
Síntoma: Funciona cuando se usa activamente; cae cuando está quieto; se reconecta cuando vuelve el tráfico; a veces la app del invitado nunca se recupera.
Causa raíz: USB autosuspend/runtime PM suspendiendo un dispositivo que no puede reanudar correctamente.
Solución: regla udev: establecer power/control=on para ese VID:PID o serial; opcionalmente probar con usbcore.autosuspend=-1.
2) Varios dispositivos USB desaparecen simultáneamente
Síntoma: stick Zigbee, cable UPS y teclado caen al mismo tiempo. Números de bus se resetean.
Causa raíz: reinicio del controlador xHCI o caída de la línea de alimentación afectando un hub/controlador compartido.
Solución: mueve el dispositivo crítico a un controlador dedicado; añade tarjeta PCIe USB; actualiza BIOS; evita hubs sobrecargados.
3) Disco USB externo cae durante trabajos de backup
Síntoma: Errores I/O en invitado o host, seguidos de reenumeración del dispositivo; ZFS o el job de backup falla.
Causa raíz: problemas de energía/cable; quirks UAS; firmware de la carcasa; brownout del hub.
Solución: hub alimentado o puerto directo; cable más corto; considerar desactivar UAS para la carcasa (específico del dispositivo); preferir SATA/NVMe para objetivos de backup serios.
4) El passthrough funciona hasta que el dispositivo entra en modo de actualización de firmware
Síntoma: Flasheas un dongle; desaparece; vuelve con un USB ID diferente; la VM ya no lo captura.
Causa raíz: el bootloader se enumera con un VID:PID distinto y tu mapeo es demasiado estrecho.
Solución: temporalmente pasa por ruta de puerto físico; o pasa el controlador; o incluye ambos IDs si los conoces.
5) Dos dongles idénticos intercambian lugares tras un reboot
Síntoma: La VM recibe “el stick equivocado” y todo falla de forma sutil.
Causa raíz: mapeo por VID:PID sin serial único; cambia el orden de enumeración.
Solución: fijar por serial vía udev; o usar mapeo por puerto físico; etiqueta cables como un adulto.
6) El contenedor LXC pierde el dispositivo tras una reconexión
Síntoma: El contenedor tenía /dev/ttyUSB0, luego tras reconexión pasa a /dev/ttyUSB1; la app falla.
Causa raíz: cambia la asignación de nodos; permisos/cgroup del contenedor no coinciden con el nuevo nodo.
Solución: crea symlink estable en /dev/serial/by-id o /dev/serial/by-path; bind-mount la ruta estable en el contenedor; asegúrate de que los permisos de cgroup permitan su uso.
7) “La solución” fue desactivar autosuspend globalmente y ahora otros USB se comportan raro
Síntoma: Aumenta el consumo de energía; algunos dispositivos se comportan distinto; características de ahorro de portátiles se vuelven irrelevantes, pero estás en un servidor de todos modos.
Causa raíz: martillo global usado para un problema por dispositivo.
Solución: revierte la configuración global; implementa la regla udev específica; confirma que runtime_status permanezca activo solo para ese dispositivo.
Listas de verificación / plan paso a paso
Plan de endurecimiento paso a paso (apto para producción)
- Captura evidencia: registra la salida de
dmesg -Twdel host durante al menos una desconexión; guarda las líneas relevantes dejournalctl -k. - Confirma topología: ejecuta
lsusb -t; apunta la cadena bus/puerto. Si no puedes describir dónde está enchufado, no puedes hacerlo estable. - Base de energía: mueve el dispositivo a un puerto trasero de la placa; elimina cables de extensión; prueba con un hub alimentado si es un dongle.
- Desactiva autosuspend por dispositivo: implementa regla udev para VID:PID (y serial si disponible). Reenchufa y verifica que
power/controlmuestreon. - Verifica estabilidad en reposo: déjalo inactivo por más tiempo que la ventana de fallo previa; confirma que no hay desconexiones en
journalctl -k. - Somete a estrés el dispositivo: genera tráfico realista (actividad de radio, I/O de disco, sondeo UPS). Observa reinicios.
- Si aparecen reinicios de controlador: detente. Añade un controlador USB PCIe dedicado o aísla mediante passthrough PCI.
- Elige la granularidad de passthrough: passthrough por dispositivo si es único y estable; por puerto/ruta si está fijo físicamente; passthrough de controlador para dispositivos quisquillosos.
- Fija identidad: usa symlinks estables en
/dev/serial/by-ido by-path; evita numeración frágil como/dev/ttyUSB0. - Anótalo: documenta qué puerto, qué regla y qué línea de config de VM. El tú del futuro agradecerá.
- Monitorea: añade una comprobación ligera que alerte sobre mensajes de desconexión en el kernel o nodos de dispositivo faltantes.
Checklist de rollback (porque lo necesitarás)
- Mantén una copia del
/etc/default/gruboriginal y de los archivos de reglas udev. - Aplica un cambio a la vez cuando sea posible. Si cambias hub + parámetros del kernel + modo de passthrough, no sabrás qué lo arregló.
- Planifica reinicios: algunos ajustes de PM USB requieren reinicio para asentarse por completo; las reglas udev no siempre bastan.
Tres mini-historias corporativas desde el campo
Incidente por una suposición errónea: “Está en la VM, así que es problema de la VM”
En una empresa mediana, un equipo operaba un cluster Proxmox que soportaba servicios “pequeños pero críticos”. Uno de ellos: una VM que hablaba con un UPS conectado por USB para señales de apagado seguro. Pasaron el dispositivo HID USB a la VM y siguieron con su vida.
Meses después vieron errores esporádicos del lado de la VM: el software del UPS perdía el dispositivo por segundos y luego se reconectaba. El equipo asumió que era un fallo del driver del invitado porque los logs de la VM mostraban el síntoma primero. Actualizaron el kernel del invitado, fijaron paquetes e incluso cambiaron el software del UPS. No mejoró nada.
Durante una caída más larga, alguien finalmente siguió dmesg en el host mientras reproducían el problema. El host registraba desconexiones USB en las mismas marcas temporales. No era la VM. Era el host suspendiendo el dispositivo y a veces fallando al reanudarlo correctamente.
La solución fue aburrida: una regla udev forzó power/control=on para ese VID:PID, y el dispositivo se mantuvo despierto. También movieron el cable del UPS a un puerto trasero, alejado de un hub ruidoso usado para equipo de laboratorio. El informe del incidente llevó una corrección clave: “Siempre demuestra qué kernel registró la desconexión primero”.
Optimización que salió mal: “Ahorro de energía por todos lados”
En otra organización, alguien quiso ser agresivo con la eficiencia energética. Era un rack de pequeños servidores en una oficina con refrigeración limitada. Habilitaron un conjunto de tweaks de ahorro, incluyendo estados C más profundos y políticas de runtime PM más agresivas.
Las bajas por passthrough USB empezaron en silencio: un coordinador Zigbee en una VM de domótica caía una vez al día. Luego un SSD USB externo usado para una exportación semanal empezó a mostrar errores I/O bajo escritura sostenida. No fallaba en laboratorio; fallaba en oficina a las 2 a.m., que es la hora tradicional de sorpresas.
Los ingenieros persiguieron problemas de aplicación, luego de la pila de almacenamiento, luego de QEMU. El factor común era “transiciones inactividad→actividad”. Autosuspend y runtime PM estaban ahorrando energía tomando siestas en el peor momento.
Retrogradaron el comportamiento agresivo de autosuspend dispositivo a dispositivo en lugar de globalmente, y mantuvieron el ahorro de CPU porque no estaba implicado. La lección no fue “ahorro de energía es malo”. Fue “el ahorro de energía necesita excepciones por dispositivo cuando periféricos USB son parte de tu cadena de fiabilidad”.
Práctica aburrida pero correcta que salvó el día: controladores dedicados y cableado determinista
Una compañía cercana a finanzas tenía un host Proxmox corriendo varios servicios, incluyendo una VM que gestionaba un módulo de seguridad hardware conectado por USB. No era un dongle de consumo; seguía siendo USB y delicado.
Lo trataron como cualquier otra dependencia de producción. El dispositivo USB vivía en un controlador PCIe USB dedicado. Ese controlador fue pasado a la VM vía passthrough PCI. El puerto físico estaba etiquetado, el cable era corto y conocido, y había un hub alimentado solo donde aportaba estabilidad eléctrica (no por falta de puertos).
Cuando el host recibió actualizaciones de kernel, un puñado de dispositivos USB no relacionados en los puertos de la placa empezaron a mostrar reinicios ocasionales. A nadie le importó. La cadena USB crítica estaba aislada. La VM conservó su controlador, su dispositivo y su estabilidad.
La práctica fue aburrida porque requería planificación, no heroísmo. También significó que los incidentes trataban sobre la aplicación real, no sobre si un dongle decidió re-enumerizar hoy.
Preguntas frecuentes
1) ¿Debería desactivar globalmente el autosuspend USB en Proxmox?
Sólo como prueba diagnóstica corta. Si ayuda, implementa una regla udev por dispositivo que fuerce power/control=on. Desactivar globalmente es una herramienta tosca.
2) ¿Por qué fallará pasar por “Bus 002 Device 008” después?
Porque el número “Device 008” se asigna en la enumeración y cambia tras desconexiones/restarts. Usa VID:PID, serial, by-path o pasa todo el controlador.
3) Mi stick Zigbee/Z-Wave se reinicia cuando lo conecto a un puerto USB 3. ¿Por qué?
Los puertos USB 3 pueden ser más ruidosos eléctricamente y suelen compartir hubs de forma diferente. Algunas radios de 2.4 GHz son sensibles a interferencias, y algunos dongles se comportan mejor en USB 2. Usa una extensión USB 2 o un hub alimentado que lo mantenga alejado del host.
4) ¿El passthrough PCI siempre es mejor?
Suele ser lo más estable, pero no siempre lo más conveniente. Reduce flexibilidad (el host no puede usar esos puertos) y puede complicar migraciones. Úsalo cuando el passthrough por dispositivo siga fallando.
5) ¿Cómo sé si es energía y no la gestión de energía de Linux?
Los problemas de energía se correlacionan con la carga y pueden afectar múltiples dispositivos; autosuspend se correlaciona con el tiempo de inactividad y muestra runtime_status=suspended. Logs más el timing cuentan la historia.
6) ¿Por qué mi contenedor LXC pierde /dev/ttyUSB0 tras una reconexión?
Porque el kernel puede reasignar el nodo como /dev/ttyUSB1, etc. Usa symlinks estables en /dev/serial/by-id o by-path y haz bind-mount de esos en el contenedor.
7) ¿Pueden los hubs causar desconexiones aunque el dispositivo consuma muy poca energía?
Sí. Los hubs pueden ser inestables por mala regulación de energía, quirks de firmware o problemas de integridad de señal. Un hub alimentado y de buena calidad suele arreglar desconexiones “misteriosas”.
8) Mi dispositivo tiene dos VID:PID según el modo. ¿Cómo manejo el passthrough?
O pasa por puerto físico/by-path para que la re-enumeración siga siendo capturada, o incluye ambos IDs, o usa passthrough de controlador durante actualizaciones de firmware.
9) ¿Es esto un problema de Proxmox o del kernel de Linux?
La mayoría de las veces no es ninguno de los dos: es hardware, defaults de gestión de energía o comportamiento del controlador. Proxmox corre sobre el kernel de Linux; los logs del host son el árbitro.
10) ¿Cuál es la configuración más fiable para un dispositivo USB “que no debe caer”?
Controlador PCIe USB dedicado, controlador pasado vía PCI al invitado, autosuspend desactivado específicamente si el host aún lo toca, cable corto y conocido, y puerto etiquetado de forma determinista.
Conclusión: próximos pasos que realmente funcionan
Si peleas con desconexiones de passthrough USB en Proxmox, no empieces con flags exóticos del kernel. Comienza con pruebas, luego aplica correcciones que sobrevivan reinicios y actualizaciones.
- Demuestra dónde ocurre la desconexión:
dmesg -Twen el host es tu primera fuente de verdad. - Estabiliza la capa física: puerto trasero, buen cable, hub alimentado si hace falta.
- Elimina autosuspend para el dispositivo específico usando una regla udev; verifica
power/controlyruntime_status. - Si el controlador se reinicia: aísla con un controlador USB PCIe dedicado y considera passthrough PCI.
- Haz la identidad determinista: serial/by-id/by-path, no numeración tty.
- Documenta y monitorea: la mejor solución es la que puedas explicar en un incidente a las 3 a.m.
USB puede ser estable en un hipervisor. Solo necesita el mismo respeto que das a discos y redes: alimentación limpia, cableado determinista y configuraciones que asumen que el dispositivo se comportará mal eventualmente.