Being previously a VirtualBox user, I moved to KVM(QEMU/libvirt or whatever it's called) recently. I know that in VirtualBox, when you add a new storage device to the VM, there is a checkbox labeled Solid-state Drive, if checked, the guest system will see the virtual disk as a solid-state device. This is very useful as it can inform the guest system (i.e. Windows) to disable defragment. I wonder whether this is possible in KVM or not, because I couldn't find anything related on the internet?


Solution 1:

You do not need to care about defragmentation in windows, because if belive to some sources defragmentation in Windows don't fully switching off at SSD drives:

If you disable defragmentation completely, you are taking a risk that your filesystem metadata could reach maximum fragmentation and get you potentially in trouble.

What really can be important is enable TRIM support inside VM. You can achive this with virtio-scsi that support TRIM command.

Change your VM configuration to set up controller model to virtio-scsi:

<controller type='scsi' index='0' model='virtio-scsi'>

And change each disk to enable unmap option:

<disk type='file' device='disk'>
 <driver name='qemu' type='qcow2' discard='unmap'/>

Solution 2:

There is no mechanism in QEMU today to mark a SCSI, ATA or VirtioBlk disk as being backed by non-rotational storage. So the guest OS wouldn't do the optimal settings out of the box. As a workaround, for Linux you can override this by unsetting the 'rotational' flag for the block device in sysfs for any disks backed by SSD. I'm talking to people to find out if it is possible to add this feature to QEMU to make it 'just work' in future releases.

Solution 3:

You don't need to do anything at all with current versions of qemu. If the virtual disk is a QCOW2 image, or is on thin provisioned media such as SAN storage or a sparse LVM or ZFS volume, then it will be presented appropriately as a thin provisioned volume to Windows.

This disk is on a QCOW2 disk image on local SSD storage.

Thin provisioned volume

This will cause Windows to only issue TRIM commands, and not to attempt to defragment the drive.

Clicking Optimize results in:

Optimize trims the disk

Solution 4:

To add emulated SSD disk in KVM/libvirt, follow the below steps:

1) Simply add a drive to your guest as you normally would, on the bus you want to use (for example, SCSI or SATA). In my test case, I created SATA disk.

ie: After adding the disk, the xml file would be like this:

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/home/VM-images/nvme-ssd1.qcow2'/>
  <target dev='sdb' bus='scsi'/>
  <address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>

2) Then, start the machine/domain and determine the exact name for your drive by querying the guest with virsh qemu-monitor-command:

# virsh qemu-monitor-command <domain>  --hmp "info qtree" | grep sata
          dev: ide-hd, id "sata0-0-1"  <<===
            drive = "drive-sata0-0-1"
          dev: ide-cd, id "sata0-0-0"
            drive = "drive-sata0-0-0"

3) Then, add the required set command to set rotational speed to make it an SSD (note that you set it to 1 in qemu, which sets it to 0 in Linux).

# virsh edit <domain>

[...]

<qemu:commandline>
    <qemu:arg value='-set'/>
    <qemu:arg value='device.sata0-0-1.rotation_rate=1'/>
  </qemu:commandline>
</domain>

4) Replace the header/below-line in XML-file describing your VM(virsh edit ):

domain type='kvm'

to

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

5) Restart the domain and once the vm booted up, verify the device using the below commands:

# lsblk -d -o name,rota
# smartctl -i /dev/sdXX

Solution 5:

Recent versions of QEMU (I tried with 2.12.0) support a rotation_rate parameter. If you set it to 1, the guest should treat the disk as an SSD. Currently, libvirt does not support this parameter in its XML format directly, so you have to pass it in as a qemu:commandline parameter.

Here are the relevant bits of a libvirt configuration that I use for an OSX guest:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  …
  <devices>
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native' discard='unmap'/>
      <source dev='/dev/vg1/osx'/>
      <target dev='sda' bus='sata'/>
      <boot order='2'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    …
  </devices>
  <qemu:commandline>
    …
    <qemu:arg value='-set'/>
    <qemu:arg value='device.sata0-0-0.rotation_rate=1'/>
  </qemu:commandline>
</domain>