0a122b
From c861019bd5799f76c3e2e42835b10baec1888293 Mon Sep 17 00:00:00 2001
0a122b
From: Kevin Wolf <kwolf@redhat.com>
0a122b
Date: Tue, 25 Mar 2014 14:23:49 +0100
0a122b
Subject: [PATCH 42/49] qcow2: Fix copy_sectors() with VM state
0a122b
0a122b
RH-Author: Kevin Wolf <kwolf@redhat.com>
0a122b
Message-id: <1395753835-7591-43-git-send-email-kwolf@redhat.com>
0a122b
Patchwork-id: n/a
0a122b
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 42/48] qcow2: Fix copy_sectors() with VM state
0a122b
Bugzilla: 1066691
0a122b
RH-Acked-by: Jeff Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
0a122b
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1066691
0a122b
Upstream status: Series embargoed
0a122b
0a122b
bs->total_sectors is not the highest possible sector number that could
0a122b
be involved in a copy on write operation: VM state is after the end of
0a122b
the virtual disk. This resulted in wrong values for the number of
0a122b
sectors to be copied (n).
0a122b
0a122b
The code that checks for the end of the image isn't required any more
0a122b
because the code hasn't been calling the block layer's bdrv_read() for a
0a122b
long time; instead, it directly calls qcow2_readv(), which doesn't error
0a122b
out on VM state sector numbers.
0a122b
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
---
0a122b
 block/qcow2-cluster.c      |    9 ---------
0a122b
 tests/qemu-iotests/029     |   22 ++++++++++++++++++++--
0a122b
 tests/qemu-iotests/029.out |   13 +++++++++++++
0a122b
 3 files changed, 33 insertions(+), 11 deletions(-)
0a122b
0a122b
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
0a122b
index 943e3c6..67f1393 100644
0a122b
--- a/block/qcow2-cluster.c
0a122b
+++ b/block/qcow2-cluster.c
0a122b
@@ -349,15 +349,6 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
0a122b
     struct iovec iov;
0a122b
     int n, ret;
0a122b
 
0a122b
-    /*
0a122b
-     * If this is the last cluster and it is only partially used, we must only
0a122b
-     * copy until the end of the image, or bdrv_check_request will fail for the
0a122b
-     * bdrv_read/write calls below.
0a122b
-     */
0a122b
-    if (start_sect + n_end > bs->total_sectors) {
0a122b
-        n_end = bs->total_sectors - start_sect;
0a122b
-    }
0a122b
-
0a122b
     n = n_end - n_start;
0a122b
     if (n <= 0) {
0a122b
         return 0;
0a122b
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
0a122b
index b424726..567e071 100755
0a122b
--- a/tests/qemu-iotests/029
0a122b
+++ b/tests/qemu-iotests/029
0a122b
@@ -1,7 +1,6 @@
0a122b
 #!/bin/bash
0a122b
 #
0a122b
-# Test loading internal snapshots where the L1 table of the snapshot
0a122b
-# is smaller than the current L1 table.
0a122b
+# qcow2 internal snapshots/VM state tests
0a122b
 #
0a122b
 # Copyright (C) 2011 Red Hat, Inc.
0a122b
 #
0a122b
@@ -45,6 +44,11 @@ _supported_fmt qcow2
0a122b
 _supported_proto generic
0a122b
 _supported_os Linux
0a122b
 
0a122b
+echo
0a122b
+echo Test loading internal snapshots where the L1 table of the snapshot
0a122b
+echo is smaller than the current L1 table.
0a122b
+echo
0a122b
+
0a122b
 CLUSTER_SIZE=65536
0a122b
 _make_test_img 64M
0a122b
 $QEMU_IMG snapshot -c foo "$TEST_IMG"
0a122b
@@ -59,6 +63,20 @@ $QEMU_IO -c 'write -b 0 4M' "$TEST_IMG" | _filter_qemu_io
0a122b
 $QEMU_IMG snapshot -a foo "$TEST_IMG"
0a122b
 _check_test_img
0a122b
 
0a122b
+
0a122b
+echo
0a122b
+echo Try using a huge VM state
0a122b
+echo
0a122b
+
0a122b
+CLUSTER_SIZE=65536
0a122b
+_make_test_img 64M
0a122b
+{ $QEMU_IO -c "write -b -P 0x11 1T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+{ $QEMU_IMG snapshot -c foo $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+{ $QEMU_IMG snapshot -a foo $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+{ $QEMU_IO -c "read -b -P 0x11 1T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+_check_test_img
0a122b
+
0a122b
+
0a122b
 # success, all done
0a122b
 echo "*** done"
0a122b
 rm -f $seq.full
0a122b
diff --git a/tests/qemu-iotests/029.out b/tests/qemu-iotests/029.out
0a122b
index 0eedb3a..9029698 100644
0a122b
--- a/tests/qemu-iotests/029.out
0a122b
+++ b/tests/qemu-iotests/029.out
0a122b
@@ -1,4 +1,8 @@
0a122b
 QA output created by 029
0a122b
+
0a122b
+Test loading internal snapshots where the L1 table of the snapshot
0a122b
+is smaller than the current L1 table.
0a122b
+
0a122b
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
0a122b
 wrote 4096/4096 bytes at offset 0
0a122b
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
0a122b
@@ -7,4 +11,13 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216
0a122b
 wrote 4194304/4194304 bytes at offset 0
0a122b
 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
0a122b
 No errors were found on the image.
0a122b
+
0a122b
+Try using a huge VM state
0a122b
+
0a122b
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
0a122b
+wrote 4096/4096 bytes at offset 1099511627776
0a122b
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
0a122b
+read 4096/4096 bytes at offset 1099511627776
0a122b
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
0a122b
+No errors were found on the image.
0a122b
 *** done
0a122b
-- 
0a122b
1.7.1
0a122b