研究

研究

我在 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=unmapdiscard=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 版本,否则两者都应该可以工作。

例子

找到了一个精彩的演示这里

从演讲中得到的经验教训:

  1. 您必须以 root 或具有 CAP_SYS_RAWIO 权限的用户身份运行 Qemu/KVM,以便丢弃不会被 Linux 忽略。
  2. 如果你的直通设备真的是SCSI磁盘,那么应该注意真正的SCSI UNMAP和WRITE SAME命令,并且可以使用scsi-block来直通。
  3. 如果没有,你必须使用 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。

您有两个选择。

  1. 在 zfs 池中启用自动修剪,默认情况下处于关闭状态。

    zpool set autotrim=on pool
    
  2. 或者进行手动修剪。

    zpool trim pool
    

还要注意,即使启用了自动修剪,它也会跳过非常小的空白区域,因此即使使用自动修剪,偶尔进行手动修剪仍然是有益的。

答案3

discard=unmap的所有 qemu 命令行上都有这个。这是我在互联网上能找到的所有内容都建议使用的。这也是 libvirt 配置的内容。

我使用 ZFS zvols 作为后备存储。因此,当我在 Windows 中运行“优化”驱动器等操作时,我可以轻松看到所用空间减少。

相关内容