Running fstrim on guests

Apr 26, 2018
111
10
23
Is there a preferred or recommended way to run fstrim on both LXC and KVM guests? Should fstrim be run from the host or inside guests? How often? Daily? Just before a vzdump? Do guests need to be shutdown when shrinking virtual disks? Browsing the forum and admin guide left me uncertain.

What about legacy KVMs such as XP? Is sdelete recommended or can fstrim be run through virtio?

Thank you!
 
Last edited:
In general make sure to test trim so it works, there are two methods.

On the fly trim, or periodic. I prefer the first one.

Periodic would mean u run sdelete on windows or fstrim on linux regulary.

On the fly trim is only supported by modern os, not on windows xp.

On the fly works with virtio scsi without any modification with win8+, in case of linux you have to enable discard within the guest. It also differs depending on the used file system in linux, for zfs u have to enable autotrim, for others add "discard" to /etc/fstab options.


To test generate a file with random bytes of size 1-2gb, or download a linux iso of your favorite distro. Check used disk space on hypervisor, delete the file, on the fly should free the space within 30 seconds. For periodic let sdelete or fstrim run, this will take much longer, check after it run if the disk space got freed on the hypervisor. If it does not work for you, troubleshoot disk bus and guest options.


For lxc you would need to enable trim on the hypervisor, depends on the filesystem used again.. But its not really needed in that case for thin provisioning, except you want to forward trim to your hardware backed storage, which only is needed for ssd's. Most people will probably let it disabled, there is only a small performance benefit with it. For encrypted storage do not enable discard it will reduce the security.
 
Last edited:
Thank you for replying.

As far as I can tell from browsing the web and this thread, running fstrim inside a container is not recommended. Instead virtual disk space should be reclaimed from the host side. Something like this in a daily or weekly cron job:

for ct in $(pct list | awk '/^[0-9]/ {print $1}'); do pct fstrim $ct; done

That leaves KVM virtual disks, which are not the same as container virtual disks.

Windows 7, 8, and 10 support in place trimming. This requires using the virtio-scsi controller in the guest.

Windows XP does not support in place trimming, which means using sdelete. While unused space can be zeroed out through sdelete, there needs to be a way to compact the virtual disk after clearing unused space. The XP KVM must be shut down, then the virtual disk copied and converted back.

cp image.qcow2 image.qcow2_backup

qemu-img convert -O qcow2 -c image.qcow2_backup image.qcow2
 
While unused space can be zeroed out through sdelete, there needs to be a way to compact the virtual disk after clearing unused space. The XP KVM must be shut down, then the virtual disk copied and converted back.

cp image.qcow2 image.qcow2_backup

qemu-img convert -O qcow2 -c image.qcow2_backup image.qcow2

That is one way, another is to use a storage backend, that already supports TRIM natively, so that you don't need to shrink stuff afterwards, ZFS is an example of that. The container TRIM is also not necessary on ZFS. If you use other storage backends, you need to jump all those loops you identified.
 
I know this is an old thread, but still, I've got here searching for a solution to trimming guests. And as an addition to all that was written, I will let a solution to trimming running KVM guests, IF your VMs are using qemu-guest-agent.
ZFS is not used.

Do containers need to be shut down before trimming?
For containers, no, it's working on running containers.
On KVM, it highly depended on your configuration. If you are doing the image convert as described above, yes, the guest must be shut down. If you are using qemu-guest-agent - it is installed, active and running inside the VM - then you can use qm commands to control the fstrim on running VMs. Here's an example on how to do that:
Bash:
for vm in $(qm list | grep running | awk '{print $1}'); do qm guest cmd $vm fstrim; done
Note this will take some time to complete, especially if you have many running VMs.
 
Last edited: