前言:一个强迫症引发的血案

最近发现我的 Home Assistant (HAOS) 虚拟机在 Proxmox VE (PVE) 里的硬盘占用有点奇怪。

我在当初创建虚拟机时分配了 64GB 的空间。随着使用,我在 HAOS 内部通过 df -h 查看,明明只用了 18.7GB

codeBash

➜  ~ df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                  62.3G     18.7G     41.0G  31% /
/dev/sda8                62.3G     18.7G     41.0G  31% /data
...

但是,当我回到 PVE 的 Shell 里检查 LVM-Thin 存储池时,却发现它实打实地占用了 54GB

codeBash

root@pve:~# lvs -a
LV              ...  LSize    ... Data% 
vm-103-disk-1   ...  64.00g   ... 85.03  <-- 实际占用高达 85% (约54G)

这就出现了 35GB 的“幽灵占用”。这通常是因为删除了文件,但虚拟机没有通知底层 PVE 释放空间(Dirty Blocks)。

起初我想“缩小”虚拟硬盘(Shrink),但查阅资料后发现直接缩小分区风险极高,很容易导致系统崩溃。对于 LVM-Thin 这种精简置备存储,正确的做法不是“缩小”,而是 “回收空间” (TRIM/Discard)

但这波操作可谓是一波三折,特此记录,希望能帮到遇到同样报错的朋友。


核心报错:The discard operation is not supported

我想通过 fstrim 命令手动回收空间,结果一路报错:

  1. 报错一Not a tty(在 HA 网页终端里执行)。

  2. 报错二the discard operation is not supported(进入底层后依然不支持)。

经过一系列排查,最终锁定了两个核心原因:

  1. PVE 硬件配置不当(总线不支持 TRIM)。

  2. HAOS 文件系统特性(试图 TRIM 一个 Overlay 层)。

以下是完整的完美解决方案。


步骤一:正确的 PVE 硬件设置(关键!)

TRIM 指令要生效,必须保证从物理盘 -> PVE -> 虚拟机驱动 -> 文件系统,这条链路是通的。

⚠️ 注意:操作前请务必对虚拟机进行全量备份!

1. 检查物理盘支持

在 PVE Shell 中输入 lsblk -D,确认 DISC-GRAN 不是 0B,证明物理层没问题。

2. 修改虚拟机硬件(SATA 必须换 SCSI)

很多教程只让你勾选 Discard,但如果你的硬盘总线是 SATA 或 IDE,TRIM 指令往往无法传递。必须使用 SCSI (VirtIO SCSI)。

  • 关机:先将 HAOS 虚拟机彻底关机(Shutdown)。

  • 分离硬盘:在“硬件”选项卡,选中硬盘,点击“分离 (Detach)”。

  • 重新挂载:双击生成的“未使用的磁盘 0”,设置如下:

    • 总线/设备SCSI

    • Discard (丢弃):✅ 勾选(核心)

    • SSD Emulation (SSD 仿真):✅ 勾选(推荐)

    • IO Thread:✅ 勾选

  • 检查控制器:确保“SCSI 控制器”类型为 VirtIO SCSIVirtIO SCSI Single

3. 修正启动顺序

因为换了总线,记得去 选项 (Options) -> 引导顺序 (Boot Order) 里,把新的 scsi0 勾选并拖到第一位,否则开不了机。

4. 冷启动

点击 PVE 的“启动”按钮(注意:必须是关机后的冷启动,重启可能不生效)。


步骤二:正确的执行姿势(避坑指南)

坑点 1:不要用网页终端插件

Home Assistant 里的 "Terminal & SSH" 插件是一个 Docker 容器,它没有权限直接操作底层磁盘。
正确做法:使用 PVE 的 控制台 (Console),看到 ha > 提示符后,输入 login 进入真正的宿主机 Shell(提示符变为 #)。

坑点 2:不要 TRIM 根目录 /

这是我卡最久的地方。进入底层 Shell 后,我习惯性输入:

codeBash

fstrim -v /

结果依然报错 Operation not supported!哪怕硬件设置全对了也报错。

原因:HAOS 的根目录 / 是一个 OverlayFS(只读系统+可写层的混合体)。Overlay 文件系统本身是不支持 TRIM 操作的。

正确做法:直接 TRIM 真正的物理数据挂载点 /data


最终解决方案

进入 HAOS 底层 Shell (login),输入:

codeBash

fstrim -v /data

这次终于没有报错,屏幕显示:

codeText

/data: 35.2 GiB (37795712000 bytes) trimmed

成功! 回收了 35GB 的空间。

回到 PVE Shell 再次检查:

codeBash

lvs -a

发现 vm-103-disk-1Data% 已经从 85% 降到了 30% 左右。


总结

如果你也想给 PVE 上的 HAOS 瘦身,请记住:

  1. 不要缩小硬盘 (Shrink),那是自找麻烦。用 LVM-Thin + Discard 才是正道。

  2. SATA 总线可能不支持 TRIM,请大胆切换到 SCSI (VirtIO)

  3. 一定要冷启动虚拟机让硬件设置生效。

  4. fstrim 要对准 /data,而不是 /

只要做好这几步,那个看着碍眼的 64GB 占用,其实只是个数字游戏,并不会真的吃掉你宝贵的 SSD 空间。