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: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
675879f6f3
commit
d40593dd90
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user