![研究](https://linux22.com/image/717390/%E7%A0%94%E7%A9%B6.png)
我在 Qemu/KVM 中运行 Windows 7,它带有一个直通 GPU,我用它来处理与工作相关的事务。最近,我厌倦了它前所未有的缓慢,因为它运行在机械驱动器上,所以我在我的盒子里添加了一个 SSD 来“提供给”我的 Windows-KVM。我对“直通”磁盘使用以下 qemu 命令行选项:
-drive file=/dev/disk/by-id/wwn-0x5002538d4002d61f,if=none,id=drive-scsi0-0-0-0,format=raw,discard=on" \ -device virtio-scsi-pci,id=scsi0" \ -device scsi-hd,bus=scsi0.0,drive=drive-scsi0-0-0-0"
我希望客户操作系统 TRIM 命令能够真正传递到主机上的物理驱动器,但事实似乎并非如此。
“discard=on” 是否只影响由映像文件支持的驱动器,而不影响由实际物理 SSD 支持的驱动器?如果是这样,我如何才能完成对客户操作系统上的设备的 TRIM 命令,并将其传递给主机上的物理设备?使用主机上的映像文件是唯一的解决方案吗?我希望有更好的解决方案,因为在该磁盘上安装文件系统只会产生开销,而我不需要它来做其他任何事情。
答案1
研究
Qemu 对待discard=unmap
和discard=on
在其源代码中看到的是相同的:
block.c
(L 1102):if (!strcmp(mode, "on") || !strcmp(mode, "unmap"))
它似乎还支持多个 Linux ioctl,如下所述 这里在块级别写入或丢弃零:
block/file-posix.c
(L 744):if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg)
block/file-posix.c
(L L1621):if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0)
block/file-posix.c
(L1788):if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0)
因此基于此,使用选项阻止通过 SCSI 仿真的直通discard=unmap,detect-zeroes=unmap
,除非您使用的是旧的 Qemu 机器类型或有缺陷的 Qemu 版本,否则两者都应该可以工作。
例子
找到了一个精彩的演示这里。
从演讲中得到的经验教训:
- 您必须以 root 或具有 CAP_SYS_RAWIO 权限的用户身份运行 Qemu/KVM,以便丢弃不会被 Linux 忽略。
- 如果你的直通设备真的是SCSI磁盘,那么应该注意真正的SCSI UNMAP和WRITE SAME命令,并且可以使用scsi-block来直通。
- 如果没有,你必须使用 scsi-hd 模拟 SCSI 磁盘,它将通过 Qemu 将丢弃命令发送到 Linux 块层
对我来说,虽然使用 scsi-block 直通允许访问真实设备的统计数据和 SMART 信息,并且常规 IO 运行良好,但不支持丢弃命令。
由于我的后备设备实际上是 SATA,所以是 IDE,而不是 SCSI LUN,我猜测这就是这种方式不支持丢弃的原因。
从 scsi-block 切换到 scsi-hd,您将丢失统计数据和 SMART 信息,但会获得丢弃...因此这是一种权衡。
就我个人而言,从“真正的直通”到“模拟直通”并没有遇到任何明显的性能下降。
以下是带有模拟 SCSI 和支持块设备的 Virtio SCSI 示例:
-device virtio-scsi-pci,id=scsi \
-blockdev driver=raw,node-name=disk.0,cache.direct=on,discard=unmap,file.driver=host_device,file.aio=native,file.filename=/dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L \
-device scsi-hd,drive=disk.0,bus=scsi.0
您在 Qemu 文档中找不到的部分是该file.driver=host_device
部分..它是 scsi-block 工作所必需的,并且当我们使用真正的块设备而不是主机文件系统上的文件时,它似乎也不会损害 scsi-hd。
测试
我用来测试 Linux 块级函数调用的 blktrace 工具有文档记录这里。
您可以同时运行 blktrace 和 blkparse 程序来拦截丢弃调用:
blktrace -a discard -d /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L -o - | blkparse -i -
现在,当您运行defrag /L c:
或fstrim -v /
在虚拟机中时,您将看到主机上打印了大量丢弃信息。输出中的示例片段:
8,0 1 493 0.641661863 3118 Q DS 45458024 + 728 [qemu-system-x86]
8,0 1 494 0.641664662 3118 G DS 45458024 + 728 [qemu-system-x86]
8,0 1 495 0.641665920 3118 I DS 45458024 + 728 [qemu-system-x86]
8,0 1 496 0.641669312 3118 D DS 45458024 + 728 [qemu-system-x86]
所以这足以证明丢弃是有效的。
答案2
您没有提供有关主机系统的信息,但例如如果您使用 zfs 来备份主机存储,则 discard 将不会自动修剪您的物理 ssd。
您有两个选择。
在 zfs 池中启用自动修剪,默认情况下处于关闭状态。
zpool set autotrim=on pool
或者进行手动修剪。
zpool trim pool
还要注意,即使启用了自动修剪,它也会跳过非常小的空白区域,因此即使使用自动修剪,偶尔进行手动修剪仍然是有益的。
答案3
我discard=unmap
的所有 qemu 命令行上都有这个。这是我在互联网上能找到的所有内容都建议使用的。这也是 libvirt 配置的内容。
我使用 ZFS zvols 作为后备存储。因此,当我在 Windows 中运行“优化”驱动器等操作时,我可以轻松看到所用空间减少。