1*4de110f8SKevin Wolf#!/usr/bin/env python 239218a77SKevin Wolf# 339218a77SKevin Wolf# Test qcow2 and file image creation 439218a77SKevin Wolf# 539218a77SKevin Wolf# Copyright (C) 2018 Red Hat, Inc. 639218a77SKevin Wolf# 7*4de110f8SKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 8*4de110f8SKevin Wolf# 939218a77SKevin Wolf# This program is free software; you can redistribute it and/or modify 1039218a77SKevin Wolf# it under the terms of the GNU General Public License as published by 1139218a77SKevin Wolf# the Free Software Foundation; either version 2 of the License, or 1239218a77SKevin Wolf# (at your option) any later version. 1339218a77SKevin Wolf# 1439218a77SKevin Wolf# This program is distributed in the hope that it will be useful, 1539218a77SKevin Wolf# but WITHOUT ANY WARRANTY; without even the implied warranty of 1639218a77SKevin Wolf# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1739218a77SKevin Wolf# GNU General Public License for more details. 1839218a77SKevin Wolf# 1939218a77SKevin Wolf# You should have received a copy of the GNU General Public License 2039218a77SKevin Wolf# along with this program. If not, see <http://www.gnu.org/licenses/>. 2139218a77SKevin Wolf# 2239218a77SKevin Wolf 23*4de110f8SKevin Wolfimport iotests 24*4de110f8SKevin Wolffrom iotests import imgfmt 2539218a77SKevin Wolf 26*4de110f8SKevin Wolfiotests.verify_image_format(supported_fmts=['qcow2']) 2739218a77SKevin Wolf 28*4de110f8SKevin Wolfdef blockdev_create(vm, options): 29*4de110f8SKevin Wolf result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) 3039218a77SKevin Wolf 31*4de110f8SKevin Wolf if 'return' in result: 32*4de110f8SKevin Wolf assert result['return'] == {} 33*4de110f8SKevin Wolf vm.run_job('job0') 34*4de110f8SKevin Wolf iotests.log("") 3539218a77SKevin Wolf 36*4de110f8SKevin Wolfwith iotests.FilePath('t.qcow2') as disk_path, \ 37*4de110f8SKevin Wolf iotests.FilePath('t.qcow2.base') as backing_path, \ 38*4de110f8SKevin Wolf iotests.VM() as vm: 3939218a77SKevin Wolf 40*4de110f8SKevin Wolf vm.add_object('secret,id=keysec0,data=foo') 4139218a77SKevin Wolf 42*4de110f8SKevin Wolf # 43*4de110f8SKevin Wolf # Successful image creation (defaults) 44*4de110f8SKevin Wolf # 45*4de110f8SKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 46*4de110f8SKevin Wolf iotests.log("") 4739218a77SKevin Wolf 48*4de110f8SKevin Wolf size = 128 * 1024 * 1024 4939218a77SKevin Wolf 50*4de110f8SKevin Wolf vm.launch() 51*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 52*4de110f8SKevin Wolf 'filename': disk_path, 53*4de110f8SKevin Wolf 'size': 0 }) 5439218a77SKevin Wolf 55*4de110f8SKevin Wolf vm.qmp_log('blockdev-add', driver='file', filename=disk_path, 56*4de110f8SKevin Wolf node_name='imgfile') 5739218a77SKevin Wolf 58*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 59*4de110f8SKevin Wolf 'file': 'imgfile', 60*4de110f8SKevin Wolf 'size': size }) 61*4de110f8SKevin Wolf vm.shutdown() 6239218a77SKevin Wolf 63*4de110f8SKevin Wolf iotests.img_info_log(disk_path) 64*4de110f8SKevin Wolf 65*4de110f8SKevin Wolf # 66*4de110f8SKevin Wolf # Successful image creation (inline blockdev-add, explicit defaults) 67*4de110f8SKevin Wolf # 68*4de110f8SKevin Wolf iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") 69*4de110f8SKevin Wolf iotests.log("") 7039218a77SKevin Wolf 7139218a77SKevin Wolf # Choose a different size to show that we got a new image 72*4de110f8SKevin Wolf size = 64 * 1024 * 1024 7339218a77SKevin Wolf 74*4de110f8SKevin Wolf vm.launch() 75*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 76*4de110f8SKevin Wolf 'filename': disk_path, 77*4de110f8SKevin Wolf 'size': 0, 78*4de110f8SKevin Wolf 'preallocation': 'off', 79*4de110f8SKevin Wolf 'nocow': False }) 80*4de110f8SKevin Wolf 81*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 82*4de110f8SKevin Wolf 'file': { 83*4de110f8SKevin Wolf 'driver': 'file', 84*4de110f8SKevin Wolf 'filename': disk_path, 8539218a77SKevin Wolf }, 86*4de110f8SKevin Wolf 'size': size, 87*4de110f8SKevin Wolf 'version': 'v3', 88*4de110f8SKevin Wolf 'cluster-size': 65536, 89*4de110f8SKevin Wolf 'preallocation': 'off', 90*4de110f8SKevin Wolf 'lazy-refcounts': False, 91*4de110f8SKevin Wolf 'refcount-bits': 16 }) 92*4de110f8SKevin Wolf vm.shutdown() 9339218a77SKevin Wolf 94*4de110f8SKevin Wolf iotests.img_info_log(disk_path) 9539218a77SKevin Wolf 96*4de110f8SKevin Wolf # 97*4de110f8SKevin Wolf # Successful image creation (v3 non-default options) 98*4de110f8SKevin Wolf # 99*4de110f8SKevin Wolf iotests.log("=== Successful image creation (v3 non-default options) ===") 100*4de110f8SKevin Wolf iotests.log("") 10139218a77SKevin Wolf 10239218a77SKevin Wolf # Choose a different size to show that we got a new image 103*4de110f8SKevin Wolf size = 32 * 1024 * 1024 10439218a77SKevin Wolf 105*4de110f8SKevin Wolf vm.launch() 106*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 107*4de110f8SKevin Wolf 'filename': disk_path, 108*4de110f8SKevin Wolf 'size': 0, 109*4de110f8SKevin Wolf 'preallocation': 'falloc', 110*4de110f8SKevin Wolf 'nocow': True }) 111*4de110f8SKevin Wolf 112*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 113*4de110f8SKevin Wolf 'file': { 114*4de110f8SKevin Wolf 'driver': 'file', 115*4de110f8SKevin Wolf 'filename': disk_path, 11639218a77SKevin Wolf }, 117*4de110f8SKevin Wolf 'size': size, 118*4de110f8SKevin Wolf 'version': 'v3', 119*4de110f8SKevin Wolf 'cluster-size': 2097152, 120*4de110f8SKevin Wolf 'preallocation': 'metadata', 121*4de110f8SKevin Wolf 'lazy-refcounts': True, 122*4de110f8SKevin Wolf 'refcount-bits': 1 }) 123*4de110f8SKevin Wolf vm.shutdown() 12439218a77SKevin Wolf 125*4de110f8SKevin Wolf iotests.img_info_log(disk_path) 12639218a77SKevin Wolf 127*4de110f8SKevin Wolf # 128*4de110f8SKevin Wolf # Successful image creation (v2 non-default options) 129*4de110f8SKevin Wolf # 130*4de110f8SKevin Wolf iotests.log("=== Successful image creation (v2 non-default options) ===") 131*4de110f8SKevin Wolf iotests.log("") 13239218a77SKevin Wolf 133*4de110f8SKevin Wolf vm.launch() 134*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 135*4de110f8SKevin Wolf 'filename': disk_path, 136*4de110f8SKevin Wolf 'size': 0 }) 13739218a77SKevin Wolf 138*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 139*4de110f8SKevin Wolf 'file': { 140*4de110f8SKevin Wolf 'driver': 'file', 141*4de110f8SKevin Wolf 'filename': disk_path, 14239218a77SKevin Wolf }, 143*4de110f8SKevin Wolf 'size': size, 144*4de110f8SKevin Wolf 'backing-file': backing_path, 145*4de110f8SKevin Wolf 'backing-fmt': 'qcow2', 146*4de110f8SKevin Wolf 'version': 'v2', 147*4de110f8SKevin Wolf 'cluster-size': 512 }) 148*4de110f8SKevin Wolf vm.shutdown() 14939218a77SKevin Wolf 150*4de110f8SKevin Wolf iotests.img_info_log(disk_path) 15139218a77SKevin Wolf 152*4de110f8SKevin Wolf # 153*4de110f8SKevin Wolf # Successful image creation (encrypted) 154*4de110f8SKevin Wolf # 155*4de110f8SKevin Wolf iotests.log("=== Successful image creation (encrypted) ===") 156*4de110f8SKevin Wolf iotests.log("") 15739218a77SKevin Wolf 158*4de110f8SKevin Wolf vm.launch() 159*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 160*4de110f8SKevin Wolf 'file': { 161*4de110f8SKevin Wolf 'driver': 'file', 162*4de110f8SKevin Wolf 'filename': disk_path, 16339218a77SKevin Wolf }, 164*4de110f8SKevin Wolf 'size': size, 165*4de110f8SKevin Wolf 'encrypt': { 166*4de110f8SKevin Wolf 'format': 'luks', 167*4de110f8SKevin Wolf 'key-secret': 'keysec0', 168*4de110f8SKevin Wolf 'cipher-alg': 'twofish-128', 169*4de110f8SKevin Wolf 'cipher-mode': 'ctr', 170*4de110f8SKevin Wolf 'ivgen-alg': 'plain64', 171*4de110f8SKevin Wolf 'ivgen-hash-alg': 'md5', 172*4de110f8SKevin Wolf 'hash-alg': 'sha1', 173*4de110f8SKevin Wolf 'iter-time': 10, 174*4de110f8SKevin Wolf }}) 175*4de110f8SKevin Wolf vm.shutdown() 17639218a77SKevin Wolf 177*4de110f8SKevin Wolf iotests.img_info_log(disk_path) 17839218a77SKevin Wolf 179*4de110f8SKevin Wolf # 180*4de110f8SKevin Wolf # Invalid BlockdevRef 181*4de110f8SKevin Wolf # 182*4de110f8SKevin Wolf iotests.log("=== Invalid BlockdevRef ===") 183*4de110f8SKevin Wolf iotests.log("") 18439218a77SKevin Wolf 185*4de110f8SKevin Wolf vm.launch() 186*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 187*4de110f8SKevin Wolf 'file': "this doesn't exist", 188*4de110f8SKevin Wolf 'size': size }) 189*4de110f8SKevin Wolf vm.shutdown() 19039218a77SKevin Wolf 191*4de110f8SKevin Wolf # 192*4de110f8SKevin Wolf # Invalid sizes 193*4de110f8SKevin Wolf # 194*4de110f8SKevin Wolf iotests.log("=== Invalid sizes ===") 19539218a77SKevin Wolf 19639218a77SKevin Wolf # TODO Negative image sizes aren't handled correctly, but this is a problem 197*4de110f8SKevin Wolf # with QAPI's implementation of the 'size' type and affects other commands 198*4de110f8SKevin Wolf # as well. Once this is fixed, we may want to add a test case here. 199*4de110f8SKevin Wolf # 20039218a77SKevin Wolf # 1. Misaligned image size 20139218a77SKevin Wolf # 2. 2^64 - 512 20239218a77SKevin Wolf # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 20339218a77SKevin Wolf # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) 20439218a77SKevin Wolf 205*4de110f8SKevin Wolf vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 20639218a77SKevin Wolf 207*4de110f8SKevin Wolf vm.launch() 208*4de110f8SKevin Wolf for size in [ 1234, 18446744073709551104, 9223372036854775808, 209*4de110f8SKevin Wolf 9223372036854775296 ]: 210*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 211*4de110f8SKevin Wolf 'file': 'node0', 212*4de110f8SKevin Wolf 'size': size }) 213*4de110f8SKevin Wolf vm.shutdown() 21439218a77SKevin Wolf 215*4de110f8SKevin Wolf # 216*4de110f8SKevin Wolf # Invalid version 217*4de110f8SKevin Wolf # 218*4de110f8SKevin Wolf iotests.log("=== Invalid version ===") 21939218a77SKevin Wolf 220*4de110f8SKevin Wolf vm.launch() 221*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 222*4de110f8SKevin Wolf 'file': 'node0', 223*4de110f8SKevin Wolf 'size': 67108864, 224*4de110f8SKevin Wolf 'version': 'v1' }) 225*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 226*4de110f8SKevin Wolf 'file': 'node0', 227*4de110f8SKevin Wolf 'size': 67108864, 228*4de110f8SKevin Wolf 'version': 'v2', 229*4de110f8SKevin Wolf 'lazy-refcounts': True }) 230*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 231*4de110f8SKevin Wolf 'file': 'node0', 232*4de110f8SKevin Wolf 'size': 67108864, 233*4de110f8SKevin Wolf 'version': 'v2', 234*4de110f8SKevin Wolf 'refcount-bits': 8 }) 235*4de110f8SKevin Wolf vm.shutdown() 23639218a77SKevin Wolf 237*4de110f8SKevin Wolf # 238*4de110f8SKevin Wolf # Invalid backing file options 239*4de110f8SKevin Wolf # 240*4de110f8SKevin Wolf iotests.log("=== Invalid backing file options ===") 24139218a77SKevin Wolf 242*4de110f8SKevin Wolf vm.launch() 243*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 244*4de110f8SKevin Wolf 'file': 'node0', 245*4de110f8SKevin Wolf 'size': 67108864, 246*4de110f8SKevin Wolf 'backing-file': '/dev/null', 247*4de110f8SKevin Wolf 'preallocation': 'full' }) 248*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 249*4de110f8SKevin Wolf 'file': 'node0', 250*4de110f8SKevin Wolf 'size': 67108864, 251*4de110f8SKevin Wolf 'backing-fmt': imgfmt }) 252*4de110f8SKevin Wolf vm.shutdown() 25339218a77SKevin Wolf 254*4de110f8SKevin Wolf # 255*4de110f8SKevin Wolf # Invalid cluster size 256*4de110f8SKevin Wolf # 257*4de110f8SKevin Wolf iotests.log("=== Invalid cluster size ===") 25839218a77SKevin Wolf 259*4de110f8SKevin Wolf vm.launch() 260*4de110f8SKevin Wolf for csize in [ 1234, 128, 4194304, 0 ]: 261*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 262*4de110f8SKevin Wolf 'file': 'node0', 263*4de110f8SKevin Wolf 'size': 67108864, 264*4de110f8SKevin Wolf 'cluster-size': csize }) 265*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 266*4de110f8SKevin Wolf 'file': 'node0', 267*4de110f8SKevin Wolf 'size': 281474976710656, 268*4de110f8SKevin Wolf 'cluster-size': 512 }) 269*4de110f8SKevin Wolf vm.shutdown() 27039218a77SKevin Wolf 271*4de110f8SKevin Wolf # 272*4de110f8SKevin Wolf # Invalid refcount width 273*4de110f8SKevin Wolf # 274*4de110f8SKevin Wolf iotests.log("=== Invalid refcount width ===") 27539218a77SKevin Wolf 276*4de110f8SKevin Wolf vm.launch() 277*4de110f8SKevin Wolf for refcount_bits in [ 128, 0, 7 ]: 278*4de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 279*4de110f8SKevin Wolf 'file': 'node0', 280*4de110f8SKevin Wolf 'size': 67108864, 281*4de110f8SKevin Wolf 'refcount-bits': refcount_bits }) 282*4de110f8SKevin Wolf vm.shutdown() 283