Commit d40593dd authored by Kevin Wolf's avatar Kevin Wolf
Browse files

block/backup: Fix hang for unaligned image size



When doing a block backup of an image with an unaligned size (with
respect to the BACKUP_CLUSTER_SIZE), qemu would check the allocation
status of sectors after the end of the image. bdrv_is_allocated()
returns a result that is valid for 0 sectors in this case, so the backup
job ran into an endless loop.

Stop looping when seeing a result valid for 0 sectors, we're at EOF then.

The test case looks somewhat unrelated at first sight because I
originally tried to reproduce a different suspected bug that turned out
to not exist. Still a good test case and it accidentally found this one.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent 675879f6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ static void coroutine_fn backup_run(void *opaque)
                                BACKUP_SECTORS_PER_CLUSTER - i, &n);
                    i += n;

                    if (alloced == 1) {
                    if (alloced == 1 || n == 0) {
                        break;
                    }
                }
+26 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ status=1 # failure is the default!

_cleanup()
{
    rm -f "${TEST_IMG}.copy"
    _cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -41,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.rc
. ./common.filter
. ./common.pattern
. ./common.qemu

# Any format supporting backing files except vmdk and qcow which do not support
# smaller backing files.
@@ -99,6 +101,29 @@ _check_test_img
# Rebase it on top of its base image
$QEMU_IMG rebase -b "$TEST_IMG.base" "$TEST_IMG"

echo
echo block-backup
echo

qemu_comm_method="monitor"
_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
h=$QEMU_HANDLE
QEMU_COMM_TIMEOUT=1

_send_qemu_cmd $h "drive_backup disk ${TEST_IMG}.copy" "(qemu)"
qemu_cmd_repeat=20 _send_qemu_cmd $h "info block-jobs" "No active jobs"
_send_qemu_cmd $h 'quit' ""

# Base image sectors
TEST_IMG="${TEST_IMG}.copy" io readv $(( offset )) 512 1024 32

# Image sectors
TEST_IMG="${TEST_IMG}.copy" io readv $(( offset + 512 )) 512 1024 64

# Zero sectors beyond end of base image
TEST_IMG="${TEST_IMG}.copy" io_zero readv $(( offset + 32 * 1024 )) 512 1024 32


_check_test_img

# success, all done
+269 −0

File changed.

Preview size limit exceeded, changes collapsed.