Lvm – (QEMU) Setup Windows 10 VM on a thinly-provisioned LVM device with discards (a.k.a. trim)

kvm-virtualizationlvmqemuthin-provisioningvirtio

I'm trying to set up a Windows 10 VM using QEMU and I want to use a thinly-provisioned LVM volume and be able to "retrim" the drive in Windows. I created the device with:

-drive index=0,media=disk,if=virtio,format=raw,file=/dev/vg0/myvol,

But when I run Optimize-Volume -DriveLetter c -Defrag -ReTrim in Windows PowerShell, it claims that the backing device does not support trim. How can I get this to work?

Best Answer

So forgive me, but I'm going to answer my own question because I spent almost two days on this and there needs to be an answer somewhere online!

The ChangeLog for the virtio drivers states that they added "preliminary support for discard (unmap) command" to viostor in 0.1.172-1, but it still failed -- this is an unstable release anyway.

I found the my answer here, which was to essentially replace this:

qemu-system-x86_64 --enable-kvm \
    < ... other options ... > \
    -drive index=0,format=raw,if=virtio,media=disk,file=/dev/vg0/myvol

with this:

qemu-system-x86_64 --enable-kvm \
    < ... other options ... > \
    -device virtio-scsi-pci,id=scsi0 \
    -device scsi-hd,drive=mydrive0 \
    -drive index=0,format=raw,if=none,id=mydrive0,file=/dev/vg0/myvol

To summarize the whole process:

  • Download the Windows 10 iso
  • Download the signed virtio driver iso for Windows
  • Create an LVM thin pool (e.g., lvcreate -L 1t --thinpool tpool vg0)
  • Create a thin volume in that pool (e.g., lvcreate --verbose --thin vg0/tpool --virtualsize 128G --name win10)
  • Boot the qemu vm with something like the below:
#!/bin/bash

mem=8G
cores=8
threads=1
name=win10

   WINVOLC=/dev/vg0/${name}
 WIN10_ISO='~/dl/m$/Win10_1903_V2_English_x64.iso'
VIRTIO_ISO=~/dl/virtio-win-0.1.173.iso
  rdp_port=12345
  ssh_port=12346
spice_port=12347
 spice_pwd=like_so_secret

qemu-system-x86_64 --enable-kvm
    -name "${name}" \
    -monitor stdio \
    -cpu host -smp cores=${cores},threads=${threads} -m ${mem} \
    -rtc base=localtime,clock=host \
    -net nic,id=vmnet0,model=virtio \
    -net user,id=vmnet1,hostfwd=tcp::${ssh_port}-:22,hostfwd=tcp::${rdp_port}-:3389 \
    -vga vmware \
    -spice port=${spice_port},password=${spice_pwd} \
    -device virtio-serial-pci \
    -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
    -chardev spicevmc,id=spicechannel0,name=vdagent \
    -device virtio-scsi-pci,id=scsi0 \
    -device scsi-hd,drive=winvolc \
    -drive index=0,if=none,id=winvolc,format=raw,file=${WINVOLC} \
    -drive index=1,media=cdrom,file=${WIN10_ISO} \
    -drive index=2,media=cdrom,file=${VIRTIO_ISO} \
    -boot order="cd"
  • Run spicy -p 12347 -h localhost -w like_so_secret
  • Choose keyboard layout
  • Click "Install Now"
  • Click "I don't have a product key" or enter one if you do (you can add this later as well)
  • Select Windows edition and choose "Custom" install
  • Click "Load driver" and browse your CD (will probably be e:\vioscsi\w10\amd64)
  • When prompted, click on "I don't have the Internet"
  • When the Windows install completes, browse the virtio CD and run the installer: e:\virtio-win-gt-x64.msi. It will want to finish the windows setup after it gets a network card, but you can skip it.
  • Probably reboot Windows
  • Run a superuser "powershell" (click start --> Windows PowerShell --> right click on the "Windows PowerShell" sub-entry --> more --> Run as administrator)
  • In the powershell, run Optimize-Volume -DriveLetter c -Degrag -ReTrim -Verbose

If all goes well, you won't get an error message and blocks no longer used by the NTFS file system will be discarded and returned back to the LVM thin pool. If you omit -Verbose, it prints a pretty progress bar in the top of the powershell, but doesn't print the result because they suck like that. You can select the System Reserved partition as well by replacing -DriveLetter c with -FileSystemLabel "System Reserved".

I should probably note that I'm using gtk-spice -- the reference implementation for the spice protocol (also the only one I know of). I set up the ssh port so I can setup cygwin and run sshd.

Related Topic