xref: /qemu/tests/qemu-iotests/206 (revision 770275ed)
1#!/usr/bin/env python3
2#
3# Test qcow2 and file image creation
4#
5# Copyright (C) 2018 Red Hat, Inc.
6#
7# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22
23import iotests
24from iotests import imgfmt
25
26iotests.verify_image_format(supported_fmts=['qcow2'])
27
28with iotests.FilePath('t.qcow2') as disk_path, \
29     iotests.FilePath('t.qcow2.base') as backing_path, \
30     iotests.VM() as vm:
31
32    vm.add_object('secret,id=keysec0,data=foo')
33
34    #
35    # Successful image creation (defaults)
36    #
37    iotests.log("=== Successful image creation (defaults) ===")
38    iotests.log("")
39
40    size = 128 * 1024 * 1024
41
42    vm.launch()
43    vm.blockdev_create({ 'driver': 'file',
44                         'filename': disk_path,
45                         'size': 0 })
46
47    vm.qmp_log('blockdev-add',
48               filters=[iotests.filter_qmp_testfiles],
49               driver='file', filename=disk_path,
50               node_name='imgfile')
51
52    vm.blockdev_create({ 'driver': imgfmt,
53                         'file': 'imgfile',
54                         'size': size })
55    vm.shutdown()
56
57    iotests.img_info_log(disk_path)
58
59    #
60    # Successful image creation (inline blockdev-add, explicit defaults)
61    #
62    iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
63    iotests.log("")
64
65    # Choose a different size to show that we got a new image
66    size = 64 * 1024 * 1024
67
68    vm.launch()
69    vm.blockdev_create({ 'driver': 'file',
70                         'filename': disk_path,
71                         'size': 0,
72                         'preallocation': 'off',
73                         'nocow': False })
74
75    vm.blockdev_create({ 'driver': imgfmt,
76                         'file': {
77                             'driver': 'file',
78                             'filename': disk_path,
79                         },
80                         'size': size,
81                         'version': 'v3',
82                         'cluster-size': 65536,
83                         'preallocation': 'off',
84                         'lazy-refcounts': False,
85                         'refcount-bits': 16 })
86    vm.shutdown()
87
88    iotests.img_info_log(disk_path)
89
90    #
91    # Successful image creation (v3 non-default options)
92    #
93    iotests.log("=== Successful image creation (v3 non-default options) ===")
94    iotests.log("")
95
96    # Choose a different size to show that we got a new image
97    size = 32 * 1024 * 1024
98
99    vm.launch()
100    vm.blockdev_create({ 'driver': 'file',
101                         'filename': disk_path,
102                         'size': 0,
103                         'preallocation': 'falloc',
104                         'nocow': True })
105
106    vm.blockdev_create({ 'driver': imgfmt,
107                         'file': {
108                             'driver': 'file',
109                             'filename': disk_path,
110                         },
111                         'size': size,
112                         'version': 'v3',
113                         'cluster-size': 2097152,
114                         'preallocation': 'metadata',
115                         'lazy-refcounts': True,
116                         'refcount-bits': 1 })
117    vm.shutdown()
118
119    iotests.img_info_log(disk_path)
120
121    #
122    # Successful image creation (v2 non-default options)
123    #
124    iotests.log("=== Successful image creation (v2 non-default options) ===")
125    iotests.log("")
126
127    vm.launch()
128    vm.blockdev_create({ 'driver': 'file',
129                         'filename': disk_path,
130                         'size': 0 })
131
132    vm.blockdev_create({ 'driver': imgfmt,
133                         'file': {
134                             'driver': 'file',
135                             'filename': disk_path,
136                         },
137                         'size': size,
138                         'backing-file': backing_path,
139                         'backing-fmt': 'qcow2',
140                         'version': 'v2',
141                         'cluster-size': 512 })
142    vm.shutdown()
143
144    iotests.img_info_log(disk_path)
145
146    #
147    # Successful image creation (encrypted)
148    #
149    iotests.log("=== Successful image creation (encrypted) ===")
150    iotests.log("")
151
152    vm.launch()
153    vm.blockdev_create({ 'driver': imgfmt,
154                         'file': {
155                             'driver': 'file',
156                             'filename': disk_path,
157                         },
158                         'size': size,
159                         'encrypt': {
160                             'format': 'luks',
161                             'key-secret': 'keysec0',
162                             'cipher-alg': 'twofish-128',
163                             'cipher-mode': 'ctr',
164                             'ivgen-alg': 'plain64',
165                             'ivgen-hash-alg': 'md5',
166                             'hash-alg': 'sha1',
167                             'iter-time': 10,
168                         }})
169    vm.shutdown()
170
171    iotests.img_info_log(disk_path)
172
173    #
174    # Invalid BlockdevRef
175    #
176    iotests.log("=== Invalid BlockdevRef ===")
177    iotests.log("")
178
179    vm.launch()
180    vm.blockdev_create({ 'driver': imgfmt,
181                         'file': "this doesn't exist",
182                         'size': size })
183    vm.shutdown()
184
185    #
186    # Invalid sizes
187    #
188    iotests.log("=== Invalid sizes ===")
189
190    # TODO Negative image sizes aren't handled correctly, but this is a problem
191    # with QAPI's implementation of the 'size' type and affects other commands
192    # as well. Once this is fixed, we may want to add a test case here.
193    #
194    # 1. Misaligned image size
195    # 2. 2^64 - 512
196    # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
197    # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size)
198
199    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
200
201    vm.launch()
202    for size in [ 1234, 18446744073709551104, 9223372036854775808,
203                  9223372036854775296 ]:
204        vm.blockdev_create({ 'driver': imgfmt,
205                             'file': 'node0',
206                             'size': size })
207    vm.shutdown()
208
209    #
210    # Invalid version
211    #
212    iotests.log("=== Invalid version ===")
213
214    vm.launch()
215    vm.blockdev_create({ 'driver': imgfmt,
216                         'file': 'node0',
217                         'size': 67108864,
218                         'version': 'v1' })
219    vm.blockdev_create({ 'driver': imgfmt,
220                         'file': 'node0',
221                         'size': 67108864,
222                         'version': 'v2',
223                         'lazy-refcounts': True })
224    vm.blockdev_create({ 'driver': imgfmt,
225                         'file': 'node0',
226                         'size': 67108864,
227                         'version': 'v2',
228                         'refcount-bits': 8 })
229    vm.shutdown()
230
231    #
232    # Invalid backing file options
233    #
234    iotests.log("=== Invalid backing file options ===")
235
236    vm.launch()
237    vm.blockdev_create({ 'driver': imgfmt,
238                         'file': 'node0',
239                         'size': 67108864,
240                         'backing-file': '/dev/null',
241                         'preallocation': 'full' })
242    vm.blockdev_create({ 'driver': imgfmt,
243                         'file': 'node0',
244                         'size': 67108864,
245                         'backing-fmt': imgfmt })
246    vm.shutdown()
247
248    #
249    # Invalid cluster size
250    #
251    iotests.log("=== Invalid cluster size ===")
252
253    vm.launch()
254    for csize in [ 1234, 128, 4194304, 0 ]:
255        vm.blockdev_create({ 'driver': imgfmt,
256                             'file': 'node0',
257                             'size': 67108864,
258                             'cluster-size': csize })
259    vm.blockdev_create({ 'driver': imgfmt,
260                         'file': 'node0',
261                         'size': 281474976710656,
262                         'cluster-size': 512 })
263    vm.shutdown()
264
265    #
266    # Invalid refcount width
267    #
268    iotests.log("=== Invalid refcount width ===")
269
270    vm.launch()
271    for refcount_bits in [ 128, 0, 7 ]:
272        vm.blockdev_create({ 'driver': imgfmt,
273                             'file': 'node0',
274                             'size': 67108864,
275                             'refcount-bits': refcount_bits })
276    vm.shutdown()
277