1#!/usr/bin/env bash 2# 3# Test drive-mirror with quorum 4# 5# The goal of this test is to check how the quorum driver reports 6# regions that are known to read as zeroes (BDRV_BLOCK_ZERO). The idea 7# is that drive-mirror will try the efficient representation of zeroes 8# in the destination image instead of writing actual zeroes. 9# 10# Copyright (C) 2020 Igalia, S.L. 11# Author: Alberto Garcia <berto@igalia.com> 12# 13# This program is free software; you can redistribute it and/or modify 14# it under the terms of the GNU General Public License as published by 15# the Free Software Foundation; either version 2 of the License, or 16# (at your option) any later version. 17# 18# This program is distributed in the hope that it will be useful, 19# but WITHOUT ANY WARRANTY; without even the implied warranty of 20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21# GNU General Public License for more details. 22# 23# You should have received a copy of the GNU General Public License 24# along with this program. If not, see <http://www.gnu.org/licenses/>. 25# 26 27# creator 28owner=berto@igalia.com 29 30seq=`basename $0` 31echo "QA output created by $seq" 32 33status=1 # failure is the default! 34 35_cleanup() 36{ 37 _rm_test_img "$TEST_IMG.0" 38 _rm_test_img "$TEST_IMG.1" 39 _rm_test_img "$TEST_IMG.2" 40 _rm_test_img "$TEST_IMG.3" 41 _cleanup_qemu 42} 43trap "_cleanup; exit \$status" 0 1 2 3 15 44 45# get standard environment, filters and checks 46. ./common.rc 47. ./common.filter 48. ./common.qemu 49 50_supported_fmt qcow2 51_supported_proto file 52_supported_os Linux 53_unsupported_imgopts cluster_size data_file 54 55echo 56echo '### Create all images' # three source (quorum), one destination 57echo 58TEST_IMG="$TEST_IMG.0" _make_test_img -o cluster_size=64k 10M 59TEST_IMG="$TEST_IMG.1" _make_test_img -o cluster_size=64k 10M 60TEST_IMG="$TEST_IMG.2" _make_test_img -o cluster_size=64k 10M 61TEST_IMG="$TEST_IMG.3" _make_test_img -o cluster_size=64k 10M 62 63quorum="driver=raw,file.driver=quorum,file.vote-threshold=2" 64quorum="$quorum,file.children.0.file.filename=$TEST_IMG.0" 65quorum="$quorum,file.children.1.file.filename=$TEST_IMG.1" 66quorum="$quorum,file.children.2.file.filename=$TEST_IMG.2" 67quorum="$quorum,file.children.0.driver=$IMGFMT" 68quorum="$quorum,file.children.1.driver=$IMGFMT" 69quorum="$quorum,file.children.2.driver=$IMGFMT" 70 71echo 72echo '### Output of qemu-img map (empty quorum)' 73echo 74$QEMU_IMG map --image-opts $quorum | _filter_qemu_img_map 75 76# Now we write data to the quorum. All three images will read as 77# zeroes in all cases, but with different ways to represent them 78# (unallocated clusters, zero clusters, data clusters with zeroes) 79# that will have an effect on how the data will be mirrored and the 80# output of qemu-img map on the resulting image. 81echo 82echo '### Write data to the quorum' 83echo 84# Test 1: data regions surrounded by unallocated clusters. 85# Three data regions, the largest one (0x30000) will be picked, end result: 86# offset 0x10000, length 0x30000 -> data 87$QEMU_IO -c "write -P 0 $((0x10000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io 88$QEMU_IO -c "write -P 0 $((0x10000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io 89$QEMU_IO -c "write -P 0 $((0x10000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io 90 91# Test 2: zero regions surrounded by data clusters. 92# First we allocate the data clusters. 93$QEMU_IO -c "open -o $quorum" -c "write -P 0 $((0x100000)) $((0x40000))" | _filter_qemu_io 94 95# Three zero regions, the smallest one (0x10000) will be picked, end result: 96# offset 0x100000, length 0x10000 -> data 97# offset 0x110000, length 0x10000 -> zeroes 98# offset 0x120000, length 0x20000 -> data 99$QEMU_IO -c "write -z $((0x110000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io 100$QEMU_IO -c "write -z $((0x110000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io 101$QEMU_IO -c "write -z $((0x110000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io 102 103# Test 3: zero clusters surrounded by unallocated clusters. 104# Everything reads as zeroes, no effect on the end result. 105$QEMU_IO -c "write -z $((0x150000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io 106$QEMU_IO -c "write -z $((0x150000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io 107$QEMU_IO -c "write -z $((0x150000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io 108 109# Test 4: mix of data and zero clusters. 110# The zero region will be ignored in favor of the largest data region 111# (0x20000), end result: 112# offset 0x200000, length 0x20000 -> data 113$QEMU_IO -c "write -P 0 $((0x200000)) $((0x10000))" "$TEST_IMG.0" | _filter_qemu_io 114$QEMU_IO -c "write -z $((0x200000)) $((0x30000))" "$TEST_IMG.1" | _filter_qemu_io 115$QEMU_IO -c "write -P 0 $((0x200000)) $((0x20000))" "$TEST_IMG.2" | _filter_qemu_io 116 117# Test 5: write data to a region and then zeroize it, doing it 118# directly on the quorum device instead of the individual images. 119# This has no effect on the end result but proves that the quorum driver 120# supports 'write -z'. 121$QEMU_IO -c "open -o $quorum" -c "write -P 1 $((0x250000)) $((0x10000))" | _filter_qemu_io 122# Verify the data that we just wrote 123$QEMU_IO -c "open -o $quorum" -c "read -P 1 $((0x250000)) $((0x10000))" | _filter_qemu_io 124$QEMU_IO -c "open -o $quorum" -c "write -z $((0x250000)) $((0x10000))" | _filter_qemu_io 125# Now it should read back as zeroes 126$QEMU_IO -c "open -o $quorum" -c "read -P 0 $((0x250000)) $((0x10000))" | _filter_qemu_io 127 128echo 129echo '### Launch the drive-mirror job' 130echo 131qemu_comm_method="qmp" _launch_qemu -drive if=virtio,"$quorum" 132h=$QEMU_HANDLE 133_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" 'return' 134 135_send_qemu_cmd $h \ 136 "{'execute': 'drive-mirror', 137 'arguments': {'device': 'virtio0', 138 'format': '$IMGFMT', 139 'target': '$TEST_IMG.3', 140 'sync': 'full', 141 'mode': 'existing' }}" \ 142 "BLOCK_JOB_READY.*virtio0" 143 144_send_qemu_cmd $h \ 145 "{ 'execute': 'block-job-complete', 146 'arguments': { 'device': 'virtio0' } }" \ 147 'BLOCK_JOB_COMPLETED' 148 149_send_qemu_cmd $h "{ 'execute': 'quit' }" '' 150 151echo 152echo '### Output of qemu-img map (destination image)' 153echo 154$QEMU_IMG map "$TEST_IMG.3" | _filter_qemu_img_map 155 156# success, all done 157echo "*** done" 158rm -f $seq.full 159status=0 160