14de110f8SKevin 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# 74de110f8SKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 84de110f8SKevin 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 234de110f8SKevin Wolfimport iotests 244de110f8SKevin Wolffrom iotests import imgfmt 2539218a77SKevin Wolf 264de110f8SKevin Wolfiotests.verify_image_format(supported_fmts=['qcow2']) 2739218a77SKevin Wolf 284de110f8SKevin Wolfdef blockdev_create(vm, options): 29*f8ca8609SJohn Snow result = vm.qmp_log('blockdev-create', 30*f8ca8609SJohn Snow filters=[iotests.filter_testfiles], 31*f8ca8609SJohn Snow job_id='job0', options=options) 3239218a77SKevin Wolf 334de110f8SKevin Wolf if 'return' in result: 344de110f8SKevin Wolf assert result['return'] == {} 354de110f8SKevin Wolf vm.run_job('job0') 364de110f8SKevin Wolf iotests.log("") 3739218a77SKevin Wolf 384de110f8SKevin Wolfwith iotests.FilePath('t.qcow2') as disk_path, \ 394de110f8SKevin Wolf iotests.FilePath('t.qcow2.base') as backing_path, \ 404de110f8SKevin Wolf iotests.VM() as vm: 4139218a77SKevin Wolf 424de110f8SKevin Wolf vm.add_object('secret,id=keysec0,data=foo') 4339218a77SKevin Wolf 444de110f8SKevin Wolf # 454de110f8SKevin Wolf # Successful image creation (defaults) 464de110f8SKevin Wolf # 474de110f8SKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 484de110f8SKevin Wolf iotests.log("") 4939218a77SKevin Wolf 504de110f8SKevin Wolf size = 128 * 1024 * 1024 5139218a77SKevin Wolf 524de110f8SKevin Wolf vm.launch() 534de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 544de110f8SKevin Wolf 'filename': disk_path, 554de110f8SKevin Wolf 'size': 0 }) 5639218a77SKevin Wolf 57*f8ca8609SJohn Snow vm.qmp_log('blockdev-add', 58*f8ca8609SJohn Snow filters=[iotests.filter_testfiles], 59*f8ca8609SJohn Snow driver='file', filename=disk_path, 604de110f8SKevin Wolf node_name='imgfile') 6139218a77SKevin Wolf 624de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 634de110f8SKevin Wolf 'file': 'imgfile', 644de110f8SKevin Wolf 'size': size }) 654de110f8SKevin Wolf vm.shutdown() 6639218a77SKevin Wolf 674de110f8SKevin Wolf iotests.img_info_log(disk_path) 684de110f8SKevin Wolf 694de110f8SKevin Wolf # 704de110f8SKevin Wolf # Successful image creation (inline blockdev-add, explicit defaults) 714de110f8SKevin Wolf # 724de110f8SKevin Wolf iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") 734de110f8SKevin Wolf iotests.log("") 7439218a77SKevin Wolf 7539218a77SKevin Wolf # Choose a different size to show that we got a new image 764de110f8SKevin Wolf size = 64 * 1024 * 1024 7739218a77SKevin Wolf 784de110f8SKevin Wolf vm.launch() 794de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 804de110f8SKevin Wolf 'filename': disk_path, 814de110f8SKevin Wolf 'size': 0, 824de110f8SKevin Wolf 'preallocation': 'off', 834de110f8SKevin Wolf 'nocow': False }) 844de110f8SKevin Wolf 854de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 864de110f8SKevin Wolf 'file': { 874de110f8SKevin Wolf 'driver': 'file', 884de110f8SKevin Wolf 'filename': disk_path, 8939218a77SKevin Wolf }, 904de110f8SKevin Wolf 'size': size, 914de110f8SKevin Wolf 'version': 'v3', 924de110f8SKevin Wolf 'cluster-size': 65536, 934de110f8SKevin Wolf 'preallocation': 'off', 944de110f8SKevin Wolf 'lazy-refcounts': False, 954de110f8SKevin Wolf 'refcount-bits': 16 }) 964de110f8SKevin Wolf vm.shutdown() 9739218a77SKevin Wolf 984de110f8SKevin Wolf iotests.img_info_log(disk_path) 9939218a77SKevin Wolf 1004de110f8SKevin Wolf # 1014de110f8SKevin Wolf # Successful image creation (v3 non-default options) 1024de110f8SKevin Wolf # 1034de110f8SKevin Wolf iotests.log("=== Successful image creation (v3 non-default options) ===") 1044de110f8SKevin Wolf iotests.log("") 10539218a77SKevin Wolf 10639218a77SKevin Wolf # Choose a different size to show that we got a new image 1074de110f8SKevin Wolf size = 32 * 1024 * 1024 10839218a77SKevin Wolf 1094de110f8SKevin Wolf vm.launch() 1104de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 1114de110f8SKevin Wolf 'filename': disk_path, 1124de110f8SKevin Wolf 'size': 0, 1134de110f8SKevin Wolf 'preallocation': 'falloc', 1144de110f8SKevin Wolf 'nocow': True }) 1154de110f8SKevin Wolf 1164de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1174de110f8SKevin Wolf 'file': { 1184de110f8SKevin Wolf 'driver': 'file', 1194de110f8SKevin Wolf 'filename': disk_path, 12039218a77SKevin Wolf }, 1214de110f8SKevin Wolf 'size': size, 1224de110f8SKevin Wolf 'version': 'v3', 1234de110f8SKevin Wolf 'cluster-size': 2097152, 1244de110f8SKevin Wolf 'preallocation': 'metadata', 1254de110f8SKevin Wolf 'lazy-refcounts': True, 1264de110f8SKevin Wolf 'refcount-bits': 1 }) 1274de110f8SKevin Wolf vm.shutdown() 12839218a77SKevin Wolf 1294de110f8SKevin Wolf iotests.img_info_log(disk_path) 13039218a77SKevin Wolf 1314de110f8SKevin Wolf # 1324de110f8SKevin Wolf # Successful image creation (v2 non-default options) 1334de110f8SKevin Wolf # 1344de110f8SKevin Wolf iotests.log("=== Successful image creation (v2 non-default options) ===") 1354de110f8SKevin Wolf iotests.log("") 13639218a77SKevin Wolf 1374de110f8SKevin Wolf vm.launch() 1384de110f8SKevin Wolf blockdev_create(vm, { 'driver': 'file', 1394de110f8SKevin Wolf 'filename': disk_path, 1404de110f8SKevin Wolf 'size': 0 }) 14139218a77SKevin Wolf 1424de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1434de110f8SKevin Wolf 'file': { 1444de110f8SKevin Wolf 'driver': 'file', 1454de110f8SKevin Wolf 'filename': disk_path, 14639218a77SKevin Wolf }, 1474de110f8SKevin Wolf 'size': size, 1484de110f8SKevin Wolf 'backing-file': backing_path, 1494de110f8SKevin Wolf 'backing-fmt': 'qcow2', 1504de110f8SKevin Wolf 'version': 'v2', 1514de110f8SKevin Wolf 'cluster-size': 512 }) 1524de110f8SKevin Wolf vm.shutdown() 15339218a77SKevin Wolf 1544de110f8SKevin Wolf iotests.img_info_log(disk_path) 15539218a77SKevin Wolf 1564de110f8SKevin Wolf # 1574de110f8SKevin Wolf # Successful image creation (encrypted) 1584de110f8SKevin Wolf # 1594de110f8SKevin Wolf iotests.log("=== Successful image creation (encrypted) ===") 1604de110f8SKevin Wolf iotests.log("") 16139218a77SKevin Wolf 1624de110f8SKevin Wolf vm.launch() 1634de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1644de110f8SKevin Wolf 'file': { 1654de110f8SKevin Wolf 'driver': 'file', 1664de110f8SKevin Wolf 'filename': disk_path, 16739218a77SKevin Wolf }, 1684de110f8SKevin Wolf 'size': size, 1694de110f8SKevin Wolf 'encrypt': { 1704de110f8SKevin Wolf 'format': 'luks', 1714de110f8SKevin Wolf 'key-secret': 'keysec0', 1724de110f8SKevin Wolf 'cipher-alg': 'twofish-128', 1734de110f8SKevin Wolf 'cipher-mode': 'ctr', 1744de110f8SKevin Wolf 'ivgen-alg': 'plain64', 1754de110f8SKevin Wolf 'ivgen-hash-alg': 'md5', 1764de110f8SKevin Wolf 'hash-alg': 'sha1', 1774de110f8SKevin Wolf 'iter-time': 10, 1784de110f8SKevin Wolf }}) 1794de110f8SKevin Wolf vm.shutdown() 18039218a77SKevin Wolf 1814de110f8SKevin Wolf iotests.img_info_log(disk_path) 18239218a77SKevin Wolf 1834de110f8SKevin Wolf # 1844de110f8SKevin Wolf # Invalid BlockdevRef 1854de110f8SKevin Wolf # 1864de110f8SKevin Wolf iotests.log("=== Invalid BlockdevRef ===") 1874de110f8SKevin Wolf iotests.log("") 18839218a77SKevin Wolf 1894de110f8SKevin Wolf vm.launch() 1904de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1914de110f8SKevin Wolf 'file': "this doesn't exist", 1924de110f8SKevin Wolf 'size': size }) 1934de110f8SKevin Wolf vm.shutdown() 19439218a77SKevin Wolf 1954de110f8SKevin Wolf # 1964de110f8SKevin Wolf # Invalid sizes 1974de110f8SKevin Wolf # 1984de110f8SKevin Wolf iotests.log("=== Invalid sizes ===") 19939218a77SKevin Wolf 20039218a77SKevin Wolf # TODO Negative image sizes aren't handled correctly, but this is a problem 2014de110f8SKevin Wolf # with QAPI's implementation of the 'size' type and affects other commands 2024de110f8SKevin Wolf # as well. Once this is fixed, we may want to add a test case here. 2034de110f8SKevin Wolf # 20439218a77SKevin Wolf # 1. Misaligned image size 20539218a77SKevin Wolf # 2. 2^64 - 512 20639218a77SKevin Wolf # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 20739218a77SKevin Wolf # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) 20839218a77SKevin Wolf 2094de110f8SKevin Wolf vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 21039218a77SKevin Wolf 2114de110f8SKevin Wolf vm.launch() 2124de110f8SKevin Wolf for size in [ 1234, 18446744073709551104, 9223372036854775808, 2134de110f8SKevin Wolf 9223372036854775296 ]: 2144de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2154de110f8SKevin Wolf 'file': 'node0', 2164de110f8SKevin Wolf 'size': size }) 2174de110f8SKevin Wolf vm.shutdown() 21839218a77SKevin Wolf 2194de110f8SKevin Wolf # 2204de110f8SKevin Wolf # Invalid version 2214de110f8SKevin Wolf # 2224de110f8SKevin Wolf iotests.log("=== Invalid version ===") 22339218a77SKevin Wolf 2244de110f8SKevin Wolf vm.launch() 2254de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2264de110f8SKevin Wolf 'file': 'node0', 2274de110f8SKevin Wolf 'size': 67108864, 2284de110f8SKevin Wolf 'version': 'v1' }) 2294de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2304de110f8SKevin Wolf 'file': 'node0', 2314de110f8SKevin Wolf 'size': 67108864, 2324de110f8SKevin Wolf 'version': 'v2', 2334de110f8SKevin Wolf 'lazy-refcounts': True }) 2344de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2354de110f8SKevin Wolf 'file': 'node0', 2364de110f8SKevin Wolf 'size': 67108864, 2374de110f8SKevin Wolf 'version': 'v2', 2384de110f8SKevin Wolf 'refcount-bits': 8 }) 2394de110f8SKevin Wolf vm.shutdown() 24039218a77SKevin Wolf 2414de110f8SKevin Wolf # 2424de110f8SKevin Wolf # Invalid backing file options 2434de110f8SKevin Wolf # 2444de110f8SKevin Wolf iotests.log("=== Invalid backing file options ===") 24539218a77SKevin Wolf 2464de110f8SKevin Wolf vm.launch() 2474de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2484de110f8SKevin Wolf 'file': 'node0', 2494de110f8SKevin Wolf 'size': 67108864, 2504de110f8SKevin Wolf 'backing-file': '/dev/null', 2514de110f8SKevin Wolf 'preallocation': 'full' }) 2524de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2534de110f8SKevin Wolf 'file': 'node0', 2544de110f8SKevin Wolf 'size': 67108864, 2554de110f8SKevin Wolf 'backing-fmt': imgfmt }) 2564de110f8SKevin Wolf vm.shutdown() 25739218a77SKevin Wolf 2584de110f8SKevin Wolf # 2594de110f8SKevin Wolf # Invalid cluster size 2604de110f8SKevin Wolf # 2614de110f8SKevin Wolf iotests.log("=== Invalid cluster size ===") 26239218a77SKevin Wolf 2634de110f8SKevin Wolf vm.launch() 2644de110f8SKevin Wolf for csize in [ 1234, 128, 4194304, 0 ]: 2654de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2664de110f8SKevin Wolf 'file': 'node0', 2674de110f8SKevin Wolf 'size': 67108864, 2684de110f8SKevin Wolf 'cluster-size': csize }) 2694de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2704de110f8SKevin Wolf 'file': 'node0', 2714de110f8SKevin Wolf 'size': 281474976710656, 2724de110f8SKevin Wolf 'cluster-size': 512 }) 2734de110f8SKevin Wolf vm.shutdown() 27439218a77SKevin Wolf 2754de110f8SKevin Wolf # 2764de110f8SKevin Wolf # Invalid refcount width 2774de110f8SKevin Wolf # 2784de110f8SKevin Wolf iotests.log("=== Invalid refcount width ===") 27939218a77SKevin Wolf 2804de110f8SKevin Wolf vm.launch() 2814de110f8SKevin Wolf for refcount_bits in [ 128, 0, 7 ]: 2824de110f8SKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 2834de110f8SKevin Wolf 'file': 'node0', 2844de110f8SKevin Wolf 'size': 67108864, 2854de110f8SKevin Wolf 'refcount-bits': refcount_bits }) 2864de110f8SKevin Wolf vm.shutdown() 287