69f47505ee
drv_co_block_status digs bs->file for additional, more accurate search
for hole inside region, reported as DATA by bs since 5daa74a6eb
.
This accuracy is not free: assume we have qcow2 disk. Actually, qcow2
knows, where are holes and where is data. But every block_status
request calls lseek additionally. Assume a big disk, full of
data, in any iterative copying block job (or img convert) we'll call
lseek(HOLE) on every iteration, and each of these lseeks will have to
iterate through all metadata up to the end of file. It's obviously
ineffective behavior. And for many scenarios we don't need this lseek
at all.
However, lseek is needed when we have metadata-preallocated image.
So, let's detect metadata-preallocation case and don't dig qcow2's
protocol file in other cases.
The idea is to compare allocation size in POV of filesystem with
allocations size in POV of Qcow2 (by refcounts). If allocation in fs is
significantly lower, consider it as metadata-preallocation case.
102 iotest changed, as our detector can't detect shrinked file as
metadata-preallocation, which don't seem to be wrong, as with metadata
preallocation we always have valid file length.
Two other iotests have a slight change in their QMP output sequence:
Active 'block-commit' returns earlier because the job coroutine yields
earlier on a blocking operation. This operation is loading the refcount
blocks in qcow2_detect_metadata_preallocation().
Suggested-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
85 lines
2.3 KiB
Bash
Executable File
85 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Test case for qemu-io -c map and qemu-img map
|
|
#
|
|
# Copyright (C) 2014 Red Hat, Inc.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
# creator
|
|
owner=mreitz@redhat.com
|
|
|
|
seq=$(basename $0)
|
|
echo "QA output created by $seq"
|
|
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
_cleanup_qemu
|
|
_cleanup_test_img
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and qemu instance handling
|
|
. ./common.rc
|
|
. ./common.filter
|
|
. ./common.qemu
|
|
|
|
_supported_fmt qcow2
|
|
_supported_proto file
|
|
|
|
IMG_SIZE=64K
|
|
|
|
echo
|
|
echo '=== Testing map command on truncated image ==='
|
|
echo
|
|
|
|
_make_test_img $IMG_SIZE
|
|
# Create cluster
|
|
$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
# Remove data cluster from image (first cluster: image header, second: reftable,
|
|
# third: refblock, fourth: L1 table, fifth: L2 table)
|
|
$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
|
|
|
|
$QEMU_IO -c map "$TEST_IMG"
|
|
$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
|
|
|
|
echo
|
|
echo '=== Testing map on an image file truncated outside of qemu ==='
|
|
echo
|
|
|
|
# Same as above, only now we concurrently truncate and map the image
|
|
_make_test_img $IMG_SIZE
|
|
$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
|
|
|
|
qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0
|
|
|
|
# Wait for a prompt to appear (so we know qemu has opened the image)
|
|
_send_qemu_cmd '' '(qemu)'
|
|
|
|
$QEMU_IMG resize --shrink --image-opts \
|
|
"driver=raw,file.driver=file,file.filename=$TEST_IMG,file.locking=off" \
|
|
$((5 * 64 * 1024))
|
|
|
|
_send_qemu_cmd $QEMU_HANDLE 'qemu-io drv0 map' 'allocated' \
|
|
| sed -e 's/^(qemu).*qemu-io drv0 map...$/(qemu) qemu-io drv0 map/'
|
|
_send_qemu_cmd $QEMU_HANDLE 'quit' ''
|
|
|
|
# success, all done
|
|
echo '*** done'
|
|
rm -f $seq.full
|
|
status=0
|