Proxmox/ZFS: NVMe some no boot (VMD/U.2) — diagnóstico e correção sem reboot
Resumo: passo-a-passo para identificar qual NVMe “sumiu”, forçar reenumeração PCIe (sem reiniciar), e recolocar o disco no rpool espelhado do ZFS. Funciona em hosts com Intel VMD e backplane U.2.
1) Pré-requisitos (uma vez)
apt-get update -qq
apt-get install -y pciutils nvme-cli smartmontools
2) Diagnóstico rápido — quem está presente e quem sumiu
Não muda nada no sistema. Só lista.
echo "=== ZFS ==="; zpool status -v
echo "=== /dev -> PCI ==="
for d in /sys/class/nvme/nvme*; do
dev=$(basename "$d"); pci=$(readlink -f "$d/device" | sed 's#.*/##')
echo "$dev -> $pci"
done 2>/dev/null
echo "=== Controladores NVMe no PCI (classe 0108) ==="
ALL=$(lspci -Dn | awk '$2 ~ /^0108/ {print $1}' | sort -u); echo "$ALL"
PRESENT=$(for d in /sys/class/nvme/nvme*; do readlink -f "$d/device" | sed 's#.*/##'; done 2>/dev/null | sort -u)
echo "PRESENT_PCI=$PRESENT"
MISSING=$(comm -23 <(echo "$ALL") <(echo "$PRESENT"))
echo "MISSING_PCI=$MISSING"
- Caso A:
MISSING_PCItem 1+ endereço(s) ⇒ o(s) controlador(es) existe(m) no PCI, mas não viraram/dev/nvmeX. - Caso B:
MISSING_PCIvazio eALLmostra só 1 endereço ⇒ o segundo NVMe nem entrou no PCI (físico/BIOS/VMD/timing).
3) Acordar somente o(s) controlador(es) ausente(s) (sem tocar no ativo)
Seguro. Faz “hotplug lógico” só em quem está ausente; caso B faz rescans seguros.
if [ -n "$MISSING" ]; then
# Caso A: hotplug só nos ausentes
for BAD in $MISSING; do
echo "Hotplug $BAD"
echo 1 > /sys/bus/pci/devices/$BAD/remove
done
echo 1 > /sys/bus/pci/rescan
else
# Caso B: só 1 controlador no PCI - rescan VMD/bridges e global
echo "Rescan VMD/bridges"
for v in $(lspci -Dn | awk '$2 ~ /^0104/ {print $1}'); do # 0104 = VMD/RAID Intel
[ -w /sys/bus/pci/devices/$v/rescan ] && echo 1 > /sys/bus/pci/devices/$v/rescan
done
for f in /sys/bus/pci/devices/*/rescan; do echo 1 > "$f"; done
echo 1 > /sys/bus/pci/rescan
fi
sleep 2
echo "=== pós-rescan ==="
dmesg -T | tail -n 120 | egrep -i 'nvme|vmd|pcie|hotplug' || true
ls -l /dev/nvme*n1 2>/dev/null || true
Sinal de sucesso: no dmesg aparece linha tipo nvme1n1: p1 p2 p3 e surgiu um novo /dev/nvmeXn1.
4) (Opcional) Automatizar até corrigir BIOS/firmware
Criar script e serviço que acorda NVMe ausente no boot.
/usr/local/sbin/nvme-rescan-missing.sh
cat >/usr/local/sbin/nvme-rescan-missing.sh <<'EOF'
#!/usr/bin/env bash
set -e
ALL=$(lspci -Dn | awk '$2 ~ /^0108/ {print $1}' | sort -u)
PRESENT=$(for d in /sys/class/nvme/nvme*; do readlink -f "$d/device" | sed 's#.*/##'; done 2>/dev/null | sort -u)
MISSING=$(comm -23 <(echo "$ALL") <(echo "$PRESENT"))
if [ -n "$MISSING" ]; then
for BAD in $MISSING; do echo 1 > /sys/bus/pci/devices/$BAD/remove; done
echo 1 > /sys/bus/pci/rescan
else
for v in $(lspci -Dn | awk '$2 ~ /^0104/ {print $1}'); do
[ -w /sys/bus/pci/devices/$v/rescan ] && echo 1 > /sys/bus/pci/devices/$v/rescan
done
echo 1 > /sys/bus/pci/rescan
fi
exit 0
EOF
chmod +x /usr/local/sbin/nvme-rescan-missing.sh
/etc/systemd/system/nvme-rescan-missing.service
cat >/etc/systemd/system/nvme-rescan-missing.service <<'EOF'
[Unit]
Description=Rescana NVMe ausente em hosts com VMD
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/nvme-rescan-missing.sh
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now nvme-rescan-missing.service
Por que isso acontece?
- Intel VMD (Volume Management Device) + backplane U.2: o controlador aparece no PCIe, mas o SSD não anuncia namespace durante o boot (log típico: “Ignoring bogus Namespace Identifiers”). O hotplug lógico corrige sem reboot.
- Sequência de energia/timing do backplane: 3.3V/Power-Good atrasa; o SSD inicializa o controlador mas não finaliza a NAND a tempo.
- BIOS/firmware desatualizados: bugs conhecidos com P4510/Intel SSDPE2KX e VMD.
Prevenção (quando tiver janela):
- Se não usa RAID Intel: desabilite VMD/RSTe/VROC e exponha NVMe direto.
- Habilite Hot-Plug nos slots NVMe/U.2 (BIOS).
- Atualize BIOS/BMC/backplane e firmware dos NVMe.
- Ajuste “PCIe link training delay” se existir.
- Revise cabos/risers/slots; se o problema “migra”, é slot/backplane.
Observação: todos os comandos acima atuam só no controlador ausente e não derrubam o NVMe ativo. Ainda assim, valide em horário seguro.