summaryrefslogtreecommitdiffstats
path: root/qemu/tests/qemu-iotests/112
blob: 3f054a3fcd09921cb9c5e667a77eda3112c3d5d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/bash
#
# Test cases for different refcount_bits values
#
# Copyright (C) 2015 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"

here="$PWD"
tmp=/tmp/$$
status=1	# failure is the default!

_cleanup()
{
	_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15

# get standard environment, filters and checks
. ./common.rc
. ./common.filter

# This tests qcow2-specific low-level functionality
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
# This test will set refcount_bits on its own which would conflict with the
# manual setting; compat will be overridden as well
_unsupported_imgopts refcount_bits 'compat=0.10'

function print_refcount_bits()
{
    $QEMU_IMG info "$TEST_IMG" | sed -n '/refcount bits:/ s/^ *//p'
}

echo
echo '=== refcount_bits limits ==='
echo

# Must be positive (non-zero)
IMGOPTS="$IMGOPTS,refcount_bits=0" _make_test_img 64M
# Must be positive (non-negative)
IMGOPTS="$IMGOPTS,refcount_bits=-1" _make_test_img 64M
# May not exceed 64
IMGOPTS="$IMGOPTS,refcount_bits=128" _make_test_img 64M
# Must be a power of two
IMGOPTS="$IMGOPTS,refcount_bits=42" _make_test_img 64M

# 1 is the minimum
IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
print_refcount_bits

# 64 is the maximum
IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
print_refcount_bits

# 16 is the default
_make_test_img 64M
print_refcount_bits

echo
echo '=== refcount_bits and compat=0.10 ==='
echo

# Should work
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=16" _make_test_img 64M
print_refcount_bits

# Should not work
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=1" _make_test_img 64M
IMGOPTS="$IMGOPTS,compat=0.10,refcount_bits=64" _make_test_img 64M


echo
echo '=== Snapshot limit on refcount_bits=1 ==='
echo

IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
print_refcount_bits

$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io

# Should fail for now; in the future, this might be supported by automatically
# copying all clusters with overflowing refcount
$QEMU_IMG snapshot -c foo "$TEST_IMG"

# The new L1 table could/should be leaked
_check_test_img

echo
echo '=== Snapshot limit on refcount_bits=2 ==='
echo

IMGOPTS="$IMGOPTS,refcount_bits=2" _make_test_img 64M
print_refcount_bits

$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io

# Should succeed
$QEMU_IMG snapshot -c foo "$TEST_IMG"
$QEMU_IMG snapshot -c bar "$TEST_IMG"
# Should fail (4th reference)
$QEMU_IMG snapshot -c baz "$TEST_IMG"

# The new L1 table could/should be leaked
_check_test_img

echo
echo '=== Compressed clusters with refcount_bits=1 ==='
echo

IMGOPTS="$IMGOPTS,refcount_bits=1" _make_test_img 64M
print_refcount_bits

# Both should fit into a single host cluster; instead of failing to increase the
# refcount of that cluster, qemu should just allocate a new cluster and make
# this operation succeed
$QEMU_IO -c 'write -P 0 -c  0  64k' \
         -c 'write -P 1 -c 64k 64k' \
         "$TEST_IMG" | _filter_qemu_io

_check_test_img

echo
echo '=== MSb set in 64 bit refcount ==='
echo

IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
print_refcount_bits

$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io

# Set the MSb in the refblock entry of the data cluster
poke_file "$TEST_IMG" $((0x20028)) "\x80\x00\x00\x00\x00\x00\x00\x00"

# Clear OFLAG_COPIED in the L2 entry of the data cluster
poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"

# Try to write to that cluster (should work, even though the MSb is set)
$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io

echo
echo '=== Snapshot on maximum 64 bit refcount value ==='
echo

IMGOPTS="$IMGOPTS,refcount_bits=64" _make_test_img 64M
print_refcount_bits

$QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io

# Set the refblock entry to the maximum value possible
poke_file "$TEST_IMG" $((0x20028)) "\xff\xff\xff\xff\xff\xff\xff\xff"

# Clear OFLAG_COPIED in the L2 entry of the data cluster
poke_file "$TEST_IMG" $((0x40000)) "\x00\x00\x00\x00\x00\x05\x00\x00"

# Try a snapshot (should correctly identify the overflow; may work in the future
# by falling back to COW)
$QEMU_IMG snapshot -c foo "$TEST_IMG"

# The new L1 table could/should be leaked; and obviously the data cluster is
# leaked (refcount=UINT64_MAX reference=1)
_check_test_img


# success, all done
echo '*** done'
rm -f $seq.full
status=0