Pesquisa
O Qemu trata discard=unmap
e discard=on
da mesma forma:
block.c (linha 773):
} else if (!strcmp(mode, "on") || !strcmp(mode, "unmap")) {
Ele também parece suportar vários dos ioctls do Linux, conforme descrito aqui para escrever ou descartar zeros no nível do bloco:
bloco / arquivo-posix.c (linha 581):
if (ioctl(s->fd, BLKDISCARDZEROES, &arg) == 0 && arg) {
bloco / arquivo-posix.c (linha 1374):
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
bloco / arquivo-posix.c (linha 1509):
if (ioctl(aiocb->aio_fildes, BLKDISCARD, range) == 0) {
Portanto, com base nisso, bloqueie a passagem com emulação SCSI usando as opções discard=unmap,detect-zeroes=unmap
, a menos que você esteja usando um tipo de máquina Qemu antigo ou uma versão com bugs do Qemu, ambos devem funcionar.
Exemplo
Encontrou uma excelente apresentação aqui .
Lições aprendidas da apresentação:
- Você deve estar executando o Qemu / KVM como root ou um usuário com permissão CAP_SYS_RAWIO para descartar para não ser ignorado pelo Linux.
- Se o seu dispositivo de passagem for realmente um disco SCSI, ele deve prestar atenção aos comandos reais SCSI UNMAP e WRITE SAME, e você pode usar scsi-block para repasse.
- Se não, você terá que emular um disco SCSI com scsi-hd, que enviará os comandos de descarte pelo Qemu para a camada de bloco do Linux
Para mim, embora o uso de scsi-block para passagem permitisse acesso a estatísticas e informações SMART para o dispositivo real e o IO normal funcionasse bem, o comando de descarte não era suportado.
Como meu dispositivo de apoio é realmente SATA, portanto, IDE, não SCSI LUN, acredito que esse seja o motivo de não haver suporte a descarte dessa maneira.
Mudando de scsi-block para scsi-hd, você perderá estatísticas e informações SMART, mas ganhe o descarte ... então, um trade off.
Pessoalmente, não tive nenhuma queda de desempenho notável, passando de "true passthrough" para "emulado com passagem" para minhas necessidades.
Aqui está um exemplo de VirtSI SCSI com SCSI emulado e um dispositivo de bloco de apoio:
-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
A parte que você não encontrará na documentação do Qemu é a seção file.driver=host_device
. é necessário que o scsi-block funcione, e parece não ferir o scsi-hd também, quando estamos usando um dispositivo de bloco real, não é um arquivo no sistema de arquivos do host.
Teste
A ferramenta blktrace que eu usei para testar as chamadas de função de nível de bloco do Linux está documentada aqui .
Você pode executar os programas blktrace e blkparse juntos para interceptar chamadas de descarte:
blktrace -a discard -d /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S12PNEAD233247L -o - | blkparse -i -
Agora, quando você executar defrag /L c:
ou fstrim -v /
em sua VM, verá muitos descartes sendo impressos no host. Exemplo de snippet da saída:
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]
Então, isso é prova suficiente para mim de que o descarte está funcionando.