How to Create a Preallocated (Non-Thin Provisioned) qcow2 Disk Image in KVM


19 views

The qcow2 format is thin-provisioned by default, which explains why your initial command creates a small metadata file:

qemu-img create -f qcow2 /var/lib/libvirt/images/urb-dat0.qcow2 10G

This results in a minimal file (typically ~196KB) that grows dynamically as the guest OS writes data. While efficient for storage, some use cases require full preallocation.

QEMU provides multiple preallocation modes for qcow2:

qemu-img create -f qcow2 -o preallocation=full /var/lib/libvirt/images/prealloc.qcow2 10G

Alternative preallocation options include:

  • preallocation=off (default thin provisioning)
  • preallocation=metadata (allocates metadata only)
  • preallocation=falloc (faster but less thorough than full)

Full preallocation has distinct characteristics:

# Time comparison:
time qemu-img create -f qcow2 thin.qcow2 10G        # ~0.01s
time qemu-img create -f qcow2 -o preallocation=full thick.qcow2 10G  # ~10-30s

The preallocated file immediately consumes 10GB plus small metadata overhead:

ls -lh thick.qcow2
# -rw-r--r-- 1 user user 11G Aug 1 10:00 thick.qcow2

After creation, verify the disk appears correctly in the guest:

# On host:
qemu-img info thick.qcow2

# Inside guest:
fdisk -l /dev/vdb
# Should show full 10GB capacity

For scenarios where qcow2 preallocation isn't suitable:

  1. Use raw format for maximum performance:
    qemu-img create -f raw /var/lib/libvirt/images/raw-disk.img 10G
    
  2. Combine with fallocate for instant allocation:
    fallocate -l 10G raw-disk.img
    

Remember that raw format lacks qcow2 features like snapshots and compression.


The QCOW2 format supports both thin provisioning (sparse allocation) and preallocation modes. When you create a standard qcow2 image with:

qemu-img create -f qcow2 image.qcow2 10G

It creates a metadata-only file that grows as data is written (thin provisioning). This explains why your initial file shows only 196KB.

QEMU provides several preallocation methods through the -o preallocation= parameter:

  • metadata: Only allocates metadata (default thin provisioning)
  • falloc: Allocates space by posix_fallocate()
  • full: Fully allocates space and zeroes it

To create a non-thin provisioned 10GB image that immediately consumes disk space:

qemu-img create -f qcow2 -o preallocation=full /var/lib/libvirt/images/urb-dat0.qcow2 10G

After creation, verify the allocation:

du -hsc /var/lib/libvirt/images/urb-dat0.qcow2

You should see approximately 10GB allocated (plus minimal metadata overhead).

For maximum compatibility and performance, some administrators prefer:

# Create raw image
qemu-img create -f raw temp.raw 10G
# Convert to qcow2
qemu-img convert -f raw -O qcow2 -o preallocation=metadata temp.raw urb-dat0.qcow2
rm temp.raw

After attaching to a KVM guest, the disk should now show the full capacity:

fdisk -l /dev/vdb
# Expected output:
Disk /dev/vdb: 10 GiB, 10737418240 bytes, 20971520 sectors

Fully allocated qcow2 images offer several advantages:

  • Eliminates allocation overhead during write operations
  • Prevents storage overcommitment
  • Provides consistent performance characteristics

The trade-off is immediate disk space consumption during creation.

When using libvirt XML definitions, specify preallocation:

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2' preallocation='full'/>
  <source file='/var/lib/libvirt/images/urb-dat0.qcow2'/>
  <target dev='vdb' bus='virtio'/>
</disk>