📝 ESXi 存储一夜消失:SATA 控制器直通引发的”血案”复盘

💡 如果你的 ESXi 也出现”数据存储归零、虚拟机无效、但系统还能 SSH”——大概率不是数据丢了,先看本文第 3 节。

0. 背景

家里的 All-in-One 主机:

项目配置
平台Intel J4125(Gemini Lake)小主机
内存16 GB
系统盘金百达 512G SATA SSD(ESXi 系统盘 + datastore1)
网卡4 × Intel I226 2.5G
虚拟化VMware ESXi 8.0.2(sysin.org 打包镜像)
虚拟机爱快软路由(3 个物理网卡 PCI 直通)

某次重启 ESXi 后,打开网页:

  • 存储页面:数据存储计数 0——空空如也
  • 虚拟机页面:爱快 VM 显示「无效」,配置路径指向 /vmfs/volumes/4f02eeb0-.../iKuai/iKuai.vmx

512G 的 SSD 就装在机器里,ESXi 却像一台”没插硬盘”的裸机一样运行着。
更诡异的是:系统还能开机、SSH 能登、密码和 IP 都还在——配置没丢,只是存储消失了。

1. 诊断决策树

1
2
3
4
5
6
7
8
9
10
11
flowchart TD
A[数据存储全部消失] --> B{esxcli storage core device list}
B -->|空| C[所有磁盘设备不可见]
C --> D{adapter list / vmfs/devices/disks}
D -->|空| E[连 HBA 适配器都没有]
E --> F{lspci 看 SATA 控制器}
F -->|设备存在| G{vmkchdev -l 看归属}
G -->|passthru| H[🎯 根因:SATA 控制器被 PCI 直通层抢占]
H --> I[手动加载 vmw_ahci 驱动]
I --> J[解除直通 → 磁盘/数据存储瞬间恢复]
J --> K[修复持久化 → 重启验证]

1.1 第一层:不是”卷丢了”,是”盘丢了”

SSH 登录(幸好 SSH 和密码配置还在),三条命令定位问题层级:

1
2
3
esxcli storage filesystem list      # 输出为空!连 BOOTBANK/OSDATA 都没有
esxcli storage core device list # 为空!没有任何磁盘设备
localcli storage core adapter list # 为空!连 HBA 适配器都没注册

关键判断:如果只是 VMFS 卷损坏/未挂载,至少能看到块设备(如 t10.ATA_____xxx)。连设备节点都没有,说明问题在存储驱动层之下——要么驱动没加载,要么控制器没交给 ESXi 内核。

1.2 第二层:干扰项——VIB 签名告警

dmesg 里翻到一条触目惊心的 ALERT:

1
2
3
ALERT: Failed to verify signatures of the following vib(s):
[atlantic bcm-mpi3 bmcal bnxtnet bnxtroce brcmfcoe clusterstore
cndi-igc cpu-microcode crx drivervm-gpu-base dwi2c ...]

几乎所有 VIB 都”验签失败”?!第一反应:

  1. Secure Boot 开了,第三方打包镜像被拒?
  2. 启动分区数据损坏,签名校验不过?

逐项排除:

1
2
dmesg | grep -i secureboot
# → "UEFI Secure Boot is not enabled" ✅ 排除 1

再深挖发现 /bootbank 指向了 /tmp/_bootbankxabv0jit(内存中的降级空目录),vdf -h 里所有挂载点全是 Ramdisk——根分区、/etc、osdata、configstore 全部跑在内存里。

⚠️ 此时很容易得出错误结论:”因为启动分区坏了 → VIB 验签失败 → 驱动不加载 → 看不到盘”。
因果其实是反的,这是本次排障最大的陷阱,下一节揭晓。

1.3 第三层:实锤——PCI Passthrough 劫持了 SATA 控制器

不纠结告警,直接看”谁在管这块 SATA 控制器”:

1
2
3
4
5
6
lspci | grep -i sata
# 0000:00:12.0 SATA controller: Intel Celeron/Pentium Silver Processor SATA Controller

vmkchdev -l | grep 00:12
# 0000:00:12.0 8086:31e3 8086:7270 passthru vmhba0
# ^^^^^^^^ !!!

passthru! 这块承载着系统盘的 SATA 控制器,在开机早期被 PCI 直通层(VM Passthrough) 从 ESXi 内核手里抢走了。

内核日志给出了精确时间线:

1
2
03:09:28.869  PCI: 0000:00:12.0 named 'vmhba0' (was '')      ← 设备被枚举
03:09:29.185 PCIPassthru: Attached to device 0000:00:12.0 ← 542ms 后被直通层抢占

1.4 完整因果链(倒推)

1
2
3
4
5
6
7
8
9
10
11
12
13
(人为)在网页界面给 00:12.0 SATA 控制器开启了"直通"
↓ 提示"需重启生效",重启
开机早期:PCIPassthru 按配置抢占 SATA 控制器(早于驱动加载)
↓
系统盘所在的控制器从 ESXi 消失
↓
BOOTBANK1/2、OSDATA 分区无法挂载 → 全部降级为内存盘
↓
/etc、configstore、esx.conf 沦为"接近默认"的临时状态
↓
VIB 激活校验依赖 bootbank 中的描述文件 → 空目录 → "全部验签失败" ← 这只是【表象】
↓
数据存储 0、VM 无效、存储消失

破案补充:这台机器爱快 VM 一直用 3 个 I226 网卡直通,一切正常——因为那 3 个口上没有系统盘。某次把 SATA 控制器也加入了直通(可能是想给 NAS 虚拟机直通硬盘),重启后系统盘控制器直接消失,于是”存储一夜蒸发”。

2. 修复

2.1 运行时恢复(不重启)

1
2
3
4
5
6
7
8
9
# 1. 手动加载 AHCI 驱动(模块文件一直在内存 tardisk 里,只是没被激活)
vmkload_mod vmw_ahci
# Module vmw_ahci loaded successfully

# 2. 解除 00:12.0 的直通,立即交还内核
localcli hardware pci pcipassthru set --device-id 0000:00:12.0 --enable 0 --apply-now

# 3. 重扫
esxcli storage core adapter rescan --all

解除直通的那一秒,所有分区瞬间回归:

1
2
3
4
/vmfs/volumes/4f02eeb0-...  datastore1   VMFS-6  374467461120  353919565824  ← 数据回来了!
/vmfs/volumes/4f02eeaf-... OSDATA-... VMFSOS ...
/vmfs/volumes/f030c6aa-... BOOTBANK1 vfat ...
/vmfs/volumes/239cdbfd-... BOOTBANK2 vfat ...

爱快虚拟机也从「无效」恢复为正常,/bootbank 符号链接指回真实分区。

🐛 顺带踩了个工具坑:老牌命令 vmkchdev -v 0000:00:12.0 在 8.0.2 上有进制转换 bug——把 16 进制的槽位 12 当成 10 进制转换成了 0c,报 Did not find PCI device at 0000:00:0c.0。遇到这个错直接用上面的 localcli hardware pci pcipassthru set 即可。

2.2 持久化(否则重启复发)

运行时的修改此时只会写进内存里的临时 bootbank,重启即失。所以:

1
2
3
4
5
6
7
8
# 1. 把 bootbank 符号链接指回真实分区
rm /bootbank
ln -s /vmfs/volumes/BOOTBANK1 /bootbank

# 2. 用官方脚本把当前配置(含"解除直通")加密打包回写 BOOTBANK1
/sbin/auto-backup.sh
# 输出: Saving current state in /bootbank
# Using key ID a65e4282-... to encrypt

ESXi 8 的持久化链路:hostd/configstore(内存)→ auto-backup.sh → state.tgz(AES 加密)→ BOOTBANK1 分区,下次开机由引导程序读回。

2.3 重启验证

1
2
3
vmkchdev -l | grep 00:12
# 0000:00:12.0 8086:31e3 8086:7270 vmkernel vmhba0 ← 重启后仍是 vmkernel ✅
esxcli storage filesystem list | grep datastore1 # 自动挂载 ✅

另外两处顺手修复:

  • 系统时间停在 2012(主板纽扣电池没电的典型症状):配置 NTP esxcli system ntp set -e true -s 203.107.6.88 -s 106.55.184.199
  • /etc/vmware/passthru.map 末尾有一条手工添加的 8086 31e3 d3d0 fasle(还拼错了 false)——这条只是直通重置方式的提示表,不是本次故障根因,但留着容易误导后人,建议清理。

3. 教训与红线

  1. 系统盘所在控制器,永远不要开直通。 开直通前先 vmkchdev -l 确认设备上挂着什么。
  2. 直通的代价是”重启后才爆”: 界面上点完开关一切正常,提示”需重启”,重启完才崩——间隔让人无法把两件事关联起来。
  3. “所有 VIB 验签失败” ≠ 镜像坏了。 它可能是 bootbank 不可达的结果。看到这条 ALERT 先查 /bootbank 指向哪、vdf -h 是不是全内存盘,再下结论。
  4. 配置”还在”但 esx.conf 变干净 也是同款症状:密码/网络来自 state.tgz 的其他部分,而 esx.conf 被 configstore 同步降级成了默认值。
  5. 修完务必做持久化验证(重启一次),并留一份 state.tgz 备份到别处:
1
2
/sbin/auto-backup.sh
scp root@ESXi:/vmfs/volumes/BOOTBANK1/state.tgz ./esxi-state-backup.tgz

4. 一图总结

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────────────────────────────────────┐
│ ESXi 8.0.2 主机 │
│ │
│ 00:12.0 SATA 控制器 ──直通开启──▶ PCIPassthru 抢占 │
│ │ │
│ │ (系统盘/数据存储/BOOTBANK/OSDATA 全在这条线上) │
│ ▼ │
│ vmw_ahci 无法绑定 → 无 HBA → 无磁盘 → 无数据存储 │
│ ▼ │
│ bootbank/osdata 落内存 → 配置降级 + VIB 验签告警(假象) │
└─────────────────────────────────────────────────────┘
修复:localcli hardware pci pcipassthru set --enable 0 --apply-now
+ 修 /bootbank 软链 + auto-backup.sh 持久化

排障工具速查:lspci / vmkchdev -l(设备归属)/ vmkload_mod <mod>(手动加载驱动)/ esxcli storage core adapter rescan --all / vdf -h(看内存盘)/ dmesg(时间线)。