1*d2eed8c6SMax Reitz#!/bin/bash 2*d2eed8c6SMax Reitz# 3*d2eed8c6SMax Reitz# Test cases for different refcount_bits values 4*d2eed8c6SMax Reitz# 5*d2eed8c6SMax Reitz# Copyright (C) 2015 Red Hat, Inc. 6*d2eed8c6SMax Reitz# 7*d2eed8c6SMax Reitz# This program is free software; you can redistribute it and/or modify 8*d2eed8c6SMax Reitz# it under the terms of the GNU General Public License as published by 9*d2eed8c6SMax Reitz# the Free Software Foundation; either version 2 of the License, or 10*d2eed8c6SMax Reitz# (at your option) any later version. 11*d2eed8c6SMax Reitz# 12*d2eed8c6SMax Reitz# This program is distributed in the hope that it will be useful, 13*d2eed8c6SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*d2eed8c6SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*d2eed8c6SMax Reitz# GNU General Public License for more details. 16*d2eed8c6SMax Reitz# 17*d2eed8c6SMax Reitz# You should have received a copy of the GNU General Public License 18*d2eed8c6SMax Reitz# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*d2eed8c6SMax Reitz# 20*d2eed8c6SMax Reitz 21*d2eed8c6SMax Reitz# creator 22*d2eed8c6SMax Reitzowner=mreitz@redhat.com 23*d2eed8c6SMax Reitz 24*d2eed8c6SMax Reitzseq="$(basename $0)" 25*d2eed8c6SMax Reitzecho "QA output created by $seq" 26*d2eed8c6SMax Reitz 27*d2eed8c6SMax Reitzhere="$PWD" 28*d2eed8c6SMax Reitztmp=/tmp/$$ 29*d2eed8c6SMax Reitzstatus=1 # failure is the default! 30*d2eed8c6SMax Reitz 31*d2eed8c6SMax Reitz_cleanup() 32*d2eed8c6SMax Reitz{ 33*d2eed8c6SMax Reitz _cleanup_test_img 34*d2eed8c6SMax Reitz} 35*d2eed8c6SMax Reitztrap "_cleanup; exit \$status" 0 1 2 3 15 36*d2eed8c6SMax Reitz 37*d2eed8c6SMax Reitz# get standard environment, filters and checks 38*d2eed8c6SMax Reitz. ./common.rc 39*d2eed8c6SMax Reitz. ./common.filter 40*d2eed8c6SMax Reitz 41*d2eed8c6SMax Reitz# This tests qcow2-specific low-level functionality 42*d2eed8c6SMax Reitz_supported_fmt qcow2 43*d2eed8c6SMax Reitz_supported_proto file 44*d2eed8c6SMax Reitz_supported_os Linux 45*d2eed8c6SMax Reitz# This test will set refcount_bits on its own which would conflict with the 46*d2eed8c6SMax Reitz# manual setting; compat will be overridden as well 47*d2eed8c6SMax Reitz_unsupported_imgopts refcount_bits 'compat=0.10' 48*d2eed8c6SMax Reitz 49*d2eed8c6SMax Reitzfunction print_refcount_bits() 50*d2eed8c6SMax Reitz{ 51*d2eed8c6SMax Reitz $QEMU_IMG info "$TEST_IMG" | sed -n '/refcount bits:/ s/^ *//p' 52*d2eed8c6SMax Reitz} 53*d2eed8c6SMax Reitz 54*d2eed8c6SMax Reitzecho 55*d2eed8c6SMax Reitzecho '=== refcount_bits limits ===' 56*d2eed8c6SMax Reitzecho 57*d2eed8c6SMax Reitz 58*d2eed8c6SMax Reitz# Must be positive (non-zero) 59*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=0" _make_test_img 64M 60*d2eed8c6SMax Reitz# Must be positive (non-negative) 61*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=-1" _make_test_img 64M 62*d2eed8c6SMax Reitz# May not exceed 64 63*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=128" _make_test_img 64M 64*d2eed8c6SMax Reitz# Must be a power of two 65*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=42" _make_test_img 64M 66*d2eed8c6SMax Reitz 67*d2eed8c6SMax Reitz# 1 is the minimum 68*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M 69*d2eed8c6SMax Reitzprint_refcount_bits 70*d2eed8c6SMax Reitz 71*d2eed8c6SMax Reitz# 64 is the maximum 72*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M 73*d2eed8c6SMax Reitzprint_refcount_bits 74*d2eed8c6SMax Reitz 75*d2eed8c6SMax Reitz# 16 is the default 76*d2eed8c6SMax Reitz_make_test_img 64M 77*d2eed8c6SMax Reitzprint_refcount_bits 78*d2eed8c6SMax Reitz 79*d2eed8c6SMax Reitzecho 80*d2eed8c6SMax Reitzecho '=== refcount_bits and compat=0.10 ===' 81*d2eed8c6SMax Reitzecho 82*d2eed8c6SMax Reitz 83*d2eed8c6SMax Reitz# Should work 84*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=16" _make_test_img 64M 85*d2eed8c6SMax Reitzprint_refcount_bits 86*d2eed8c6SMax Reitz 87*d2eed8c6SMax Reitz# Should not work 88*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=1" _make_test_img 64M 89*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=64" _make_test_img 64M 90*d2eed8c6SMax Reitz 91*d2eed8c6SMax Reitz 92*d2eed8c6SMax Reitzecho 93*d2eed8c6SMax Reitzecho '=== Snapshot limit on refcount_bits=1 ===' 94*d2eed8c6SMax Reitzecho 95*d2eed8c6SMax Reitz 96*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M 97*d2eed8c6SMax Reitzprint_refcount_bits 98*d2eed8c6SMax Reitz 99*d2eed8c6SMax Reitz$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 100*d2eed8c6SMax Reitz 101*d2eed8c6SMax Reitz# Should fail for now; in the future, this might be supported by automatically 102*d2eed8c6SMax Reitz# copying all clusters with overflowing refcount 103*d2eed8c6SMax Reitz$QEMU_IMG snapshot -c foo "$TEST_IMG" 104*d2eed8c6SMax Reitz 105*d2eed8c6SMax Reitz# The new L1 table could/should be leaked 106*d2eed8c6SMax Reitz_check_test_img 107*d2eed8c6SMax Reitz 108*d2eed8c6SMax Reitzecho 109*d2eed8c6SMax Reitzecho '=== Snapshot limit on refcount_bits=2 ===' 110*d2eed8c6SMax Reitzecho 111*d2eed8c6SMax Reitz 112*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=2" _make_test_img 64M 113*d2eed8c6SMax Reitzprint_refcount_bits 114*d2eed8c6SMax Reitz 115*d2eed8c6SMax Reitz$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 116*d2eed8c6SMax Reitz 117*d2eed8c6SMax Reitz# Should succeed 118*d2eed8c6SMax Reitz$QEMU_IMG snapshot -c foo "$TEST_IMG" 119*d2eed8c6SMax Reitz$QEMU_IMG snapshot -c bar "$TEST_IMG" 120*d2eed8c6SMax Reitz# Should fail (4th reference) 121*d2eed8c6SMax Reitz$QEMU_IMG snapshot -c baz "$TEST_IMG" 122*d2eed8c6SMax Reitz 123*d2eed8c6SMax Reitz# The new L1 table could/should be leaked 124*d2eed8c6SMax Reitz_check_test_img 125*d2eed8c6SMax Reitz 126*d2eed8c6SMax Reitzecho 127*d2eed8c6SMax Reitzecho '=== Compressed clusters with refcount_bits=1 ===' 128*d2eed8c6SMax Reitzecho 129*d2eed8c6SMax Reitz 130*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M 131*d2eed8c6SMax Reitzprint_refcount_bits 132*d2eed8c6SMax Reitz 133*d2eed8c6SMax Reitz# Both should fit into a single host cluster; instead of failing to increase the 134*d2eed8c6SMax Reitz# refcount of that cluster, qemu should just allocate a new cluster and make 135*d2eed8c6SMax Reitz# this operation succeed 136*d2eed8c6SMax Reitz$QEMU_IO -c 'write -P 0 -c 0 64k' \ 137*d2eed8c6SMax Reitz -c 'write -P 1 -c 64k 64k' \ 138*d2eed8c6SMax Reitz "$TEST_IMG" | _filter_qemu_io 139*d2eed8c6SMax Reitz 140*d2eed8c6SMax Reitz_check_test_img 141*d2eed8c6SMax Reitz 142*d2eed8c6SMax Reitzecho 143*d2eed8c6SMax Reitzecho '=== MSb set in 64 bit refcount ===' 144*d2eed8c6SMax Reitzecho 145*d2eed8c6SMax Reitz 146*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M 147*d2eed8c6SMax Reitzprint_refcount_bits 148*d2eed8c6SMax Reitz 149*d2eed8c6SMax Reitz$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 150*d2eed8c6SMax Reitz 151*d2eed8c6SMax Reitz# Set the MSb in the refblock entry of the data cluster 152*d2eed8c6SMax Reitzpoke_file "$TEST_IMG" $((0x20028)) "\x80\x00\x00\x00\x00\x00\x00\x00" 153*d2eed8c6SMax Reitz 154*d2eed8c6SMax Reitz# Clear OFLAG_COPIED in the L2 entry of the data cluster 155*d2eed8c6SMax Reitzpoke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00" 156*d2eed8c6SMax Reitz 157*d2eed8c6SMax Reitz# Try to write to that cluster (should work, even though the MSb is set) 158*d2eed8c6SMax Reitz$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 159*d2eed8c6SMax Reitz 160*d2eed8c6SMax Reitzecho 161*d2eed8c6SMax Reitzecho '=== Snapshot on maximum 64 bit refcount value ===' 162*d2eed8c6SMax Reitzecho 163*d2eed8c6SMax Reitz 164*d2eed8c6SMax ReitzIMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M 165*d2eed8c6SMax Reitzprint_refcount_bits 166*d2eed8c6SMax Reitz 167*d2eed8c6SMax Reitz$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io 168*d2eed8c6SMax Reitz 169*d2eed8c6SMax Reitz# Set the refblock entry to the maximum value possible 170*d2eed8c6SMax Reitzpoke_file "$TEST_IMG" $((0x20028)) "\xff\xff\xff\xff\xff\xff\xff\xff" 171*d2eed8c6SMax Reitz 172*d2eed8c6SMax Reitz# Clear OFLAG_COPIED in the L2 entry of the data cluster 173*d2eed8c6SMax Reitzpoke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00" 174*d2eed8c6SMax Reitz 175*d2eed8c6SMax Reitz# Try a snapshot (should correctly identify the overflow; may work in the future 176*d2eed8c6SMax Reitz# by falling back to COW) 177*d2eed8c6SMax Reitz$QEMU_IMG snapshot -c foo "$TEST_IMG" 178*d2eed8c6SMax Reitz 179*d2eed8c6SMax Reitz# The new L1 table could/should be leaked; and obviously the data cluster is 180*d2eed8c6SMax Reitz# leaked (refcount=UINT64_MAX reference=1) 181*d2eed8c6SMax Reitz_check_test_img 182*d2eed8c6SMax Reitz 183*d2eed8c6SMax Reitz 184*d2eed8c6SMax Reitz# success, all done 185*d2eed8c6SMax Reitzecho '*** done' 186*d2eed8c6SMax Reitzrm -f $seq.full 187*d2eed8c6SMax Reitzstatus=0 188