[libvirt] [PATCH 7/7] qemu: Fix GetBlockInfo setting allocation from wr_highest_offset

John Ferlan jferlan at redhat.com
Fri Dec 2 00:39:47 UTC 2016

The libvirt-domain.h documentation indicates that for a qcow2 file
in a filesystem being used for a backing store should report the disk
space occupied by a file; however, commit id '15fa84ac' altered the
code to trust that the wr_highest_offset should be used whenever
wr_highest_offset_valid was set.

As it turns out this will lead to indeterminite results. For an active
domain when qemu hasn't yet had the need to find the wr_highest_offset
value, qemu will report 0 even though qemu-img will report the proper
disk size. This causes reporting of the following XML:

  <disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='/path/to/test-1g.qcow2'/>

to be as follows:

Capacity:       1073741824
Allocation:     0
Physical:       1074139136

with qemu-img indicating:

image: /path/to/test-1g.qcow2
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 1.0G

Once the backing source file is opened on the guest, then wr_highest_offset
is updated, but only to the high water mark and not the size of the file.

This patch will adjust the logic to check for the file backed qcow2 image
and enforce setting the allocation to the returned 'physical' value, which
is the 'actual-size' value from a 'query-block' operation.

NB: The other consumer of the wr_highest_offset output (GetAllDomainStats)
has a contract that indicates 'allocation' is the offset of the highest
written sector, so it doesn't need adjustment.

Signed-off-by: John Ferlan <jferlan at redhat.com>
 src/qemu/qemu_driver.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f508872..61171cb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11790,7 +11790,11 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
         info->allocation = entry->physical;
     } else {
-        info->allocation = entry->wr_highest_offset;
+        if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_FILE &&
+            disk->src->format == VIR_STORAGE_FILE_QCOW2)
+            info->allocation = entry->physical;
+        else
+            info->allocation = entry->wr_highest_offset;
     if (entry->physical) {

More information about the libvir-list mailing list