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