QEMU – Why Disable Copy-On-Write When Creating Images

btrfsqemu

The arch wiki recommends that images have Copy-On-Write disabled on the directory when using btfs. I do see that it would be a good idea if you had a lot of file read/writes. This question explores this idea. I know that VMWare will grow into different files and will write snapshots out which could be problematic when using Copy-On-Write.

For QEMU the file is left open for the VMs existance so there is a potential problem in the write after the VM is shutdown, but I would see slow I/O after a VM is shutdown not being an issue. What pitfalls would I be avoiding by performing this step for QEMU.

Additionally:
I have assumed that the image is raw for this question. Is there a possible stability issue as qcow2 already has copy-on write.

Best Answer

The performance degradation with VM images on BTRFS is not merely due to a lot of file writes; as far as BTRFS is concerned the writes are to the same file. The issue arises from a lot of random writes to the same file. These are writes which occur throughout the file.

In a nutshell, random writes interfere with BTRFS' COW resulting in file fragmentation, which in turn causes read performance degradation. If you have an image file on hand, you can check for file fragmentation with filefrag.

Note this is not an issue with just VM images. It affects any file written to at random file offsets, such as the SQLite databases used by Firefox.

Solutions/work-arounds

There are a few things you can do about file fragmentation on BTRFS. Choose one of the following:

  1. Mount the filesystem with nodatacow, which disables COW through the entire filesystem. Although really, it avoids using COW unless it absolutely has to (such as creating a snapshot).
  2. Use chattr to disable COW on the directory containing the files in question, and then recreate the files since the chattr doesn't apply to existing files.
  3. Periodically run btrfs fi defrag against the files in question.
  4. Mount the filesystem with autodefrag to automatically defrag the filesystem.

The first two options disables COW while the last two allows COW but cleans things up after-the-fact. The BTRFS COW and the QEMU COW should not interfere, it'd just be extra slow :)

My personal experience

In my experience with SQLite database files ...

  1. nodatacow - Haven't tried it.
  2. chattr - I ended up with fragmented files anyway.
  3. btrfs fi defrag - I did this for a while to test the concept.
  4. autodefrag - I've been using this quite successfully.

For QEMU images, I use LVM volumes instead of image files. So I don't deal with the COW issue at all.

Resources

Recommended reading to get a better sense of how COW works on BTRFS.

Related Question