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 Wolfwith iotests.FilePath('t.qcow2') as disk_path, \ 294de110f8SKevin Wolf iotests.FilePath('t.qcow2.base') as backing_path, \ 304de110f8SKevin Wolf iotests.VM() as vm: 3139218a77SKevin Wolf 324de110f8SKevin Wolf vm.add_object('secret,id=keysec0,data=foo') 3339218a77SKevin Wolf 344de110f8SKevin Wolf # 354de110f8SKevin Wolf # Successful image creation (defaults) 364de110f8SKevin Wolf # 374de110f8SKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 384de110f8SKevin Wolf iotests.log("") 3939218a77SKevin Wolf 404de110f8SKevin Wolf size = 128 * 1024 * 1024 4139218a77SKevin Wolf 424de110f8SKevin Wolf vm.launch() 43*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': 'file', 444de110f8SKevin Wolf 'filename': disk_path, 454de110f8SKevin Wolf 'size': 0 }) 4639218a77SKevin Wolf 47f8ca8609SJohn Snow vm.qmp_log('blockdev-add', 4808fcd611SJohn Snow filters=[iotests.filter_qmp_testfiles], 49f8ca8609SJohn Snow driver='file', filename=disk_path, 504de110f8SKevin Wolf node_name='imgfile') 5139218a77SKevin Wolf 52*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 534de110f8SKevin Wolf 'file': 'imgfile', 544de110f8SKevin Wolf 'size': size }) 554de110f8SKevin Wolf vm.shutdown() 5639218a77SKevin Wolf 574de110f8SKevin Wolf iotests.img_info_log(disk_path) 584de110f8SKevin Wolf 594de110f8SKevin Wolf # 604de110f8SKevin Wolf # Successful image creation (inline blockdev-add, explicit defaults) 614de110f8SKevin Wolf # 624de110f8SKevin Wolf iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") 634de110f8SKevin Wolf iotests.log("") 6439218a77SKevin Wolf 6539218a77SKevin Wolf # Choose a different size to show that we got a new image 664de110f8SKevin Wolf size = 64 * 1024 * 1024 6739218a77SKevin Wolf 684de110f8SKevin Wolf vm.launch() 69*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': 'file', 704de110f8SKevin Wolf 'filename': disk_path, 714de110f8SKevin Wolf 'size': 0, 724de110f8SKevin Wolf 'preallocation': 'off', 734de110f8SKevin Wolf 'nocow': False }) 744de110f8SKevin Wolf 75*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 764de110f8SKevin Wolf 'file': { 774de110f8SKevin Wolf 'driver': 'file', 784de110f8SKevin Wolf 'filename': disk_path, 7939218a77SKevin Wolf }, 804de110f8SKevin Wolf 'size': size, 814de110f8SKevin Wolf 'version': 'v3', 824de110f8SKevin Wolf 'cluster-size': 65536, 834de110f8SKevin Wolf 'preallocation': 'off', 844de110f8SKevin Wolf 'lazy-refcounts': False, 854de110f8SKevin Wolf 'refcount-bits': 16 }) 864de110f8SKevin Wolf vm.shutdown() 8739218a77SKevin Wolf 884de110f8SKevin Wolf iotests.img_info_log(disk_path) 8939218a77SKevin Wolf 904de110f8SKevin Wolf # 914de110f8SKevin Wolf # Successful image creation (v3 non-default options) 924de110f8SKevin Wolf # 934de110f8SKevin Wolf iotests.log("=== Successful image creation (v3 non-default options) ===") 944de110f8SKevin Wolf iotests.log("") 9539218a77SKevin Wolf 9639218a77SKevin Wolf # Choose a different size to show that we got a new image 974de110f8SKevin Wolf size = 32 * 1024 * 1024 9839218a77SKevin Wolf 994de110f8SKevin Wolf vm.launch() 100*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': 'file', 1014de110f8SKevin Wolf 'filename': disk_path, 1024de110f8SKevin Wolf 'size': 0, 1034de110f8SKevin Wolf 'preallocation': 'falloc', 1044de110f8SKevin Wolf 'nocow': True }) 1054de110f8SKevin Wolf 106*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 1074de110f8SKevin Wolf 'file': { 1084de110f8SKevin Wolf 'driver': 'file', 1094de110f8SKevin Wolf 'filename': disk_path, 11039218a77SKevin Wolf }, 1114de110f8SKevin Wolf 'size': size, 1124de110f8SKevin Wolf 'version': 'v3', 1134de110f8SKevin Wolf 'cluster-size': 2097152, 1144de110f8SKevin Wolf 'preallocation': 'metadata', 1154de110f8SKevin Wolf 'lazy-refcounts': True, 1164de110f8SKevin Wolf 'refcount-bits': 1 }) 1174de110f8SKevin Wolf vm.shutdown() 11839218a77SKevin Wolf 1194de110f8SKevin Wolf iotests.img_info_log(disk_path) 12039218a77SKevin Wolf 1214de110f8SKevin Wolf # 1224de110f8SKevin Wolf # Successful image creation (v2 non-default options) 1234de110f8SKevin Wolf # 1244de110f8SKevin Wolf iotests.log("=== Successful image creation (v2 non-default options) ===") 1254de110f8SKevin Wolf iotests.log("") 12639218a77SKevin Wolf 1274de110f8SKevin Wolf vm.launch() 128*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': 'file', 1294de110f8SKevin Wolf 'filename': disk_path, 1304de110f8SKevin Wolf 'size': 0 }) 13139218a77SKevin Wolf 132*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 1334de110f8SKevin Wolf 'file': { 1344de110f8SKevin Wolf 'driver': 'file', 1354de110f8SKevin Wolf 'filename': disk_path, 13639218a77SKevin Wolf }, 1374de110f8SKevin Wolf 'size': size, 1384de110f8SKevin Wolf 'backing-file': backing_path, 1394de110f8SKevin Wolf 'backing-fmt': 'qcow2', 1404de110f8SKevin Wolf 'version': 'v2', 1414de110f8SKevin Wolf 'cluster-size': 512 }) 1424de110f8SKevin Wolf vm.shutdown() 14339218a77SKevin Wolf 1444de110f8SKevin Wolf iotests.img_info_log(disk_path) 14539218a77SKevin Wolf 1464de110f8SKevin Wolf # 1474de110f8SKevin Wolf # Successful image creation (encrypted) 1484de110f8SKevin Wolf # 1494de110f8SKevin Wolf iotests.log("=== Successful image creation (encrypted) ===") 1504de110f8SKevin Wolf iotests.log("") 15139218a77SKevin Wolf 1524de110f8SKevin Wolf vm.launch() 153*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 1544de110f8SKevin Wolf 'file': { 1554de110f8SKevin Wolf 'driver': 'file', 1564de110f8SKevin Wolf 'filename': disk_path, 15739218a77SKevin Wolf }, 1584de110f8SKevin Wolf 'size': size, 1594de110f8SKevin Wolf 'encrypt': { 1604de110f8SKevin Wolf 'format': 'luks', 1614de110f8SKevin Wolf 'key-secret': 'keysec0', 1624de110f8SKevin Wolf 'cipher-alg': 'twofish-128', 1634de110f8SKevin Wolf 'cipher-mode': 'ctr', 1644de110f8SKevin Wolf 'ivgen-alg': 'plain64', 1654de110f8SKevin Wolf 'ivgen-hash-alg': 'md5', 1664de110f8SKevin Wolf 'hash-alg': 'sha1', 1674de110f8SKevin Wolf 'iter-time': 10, 1684de110f8SKevin Wolf }}) 1694de110f8SKevin Wolf vm.shutdown() 17039218a77SKevin Wolf 1714de110f8SKevin Wolf iotests.img_info_log(disk_path) 17239218a77SKevin Wolf 1734de110f8SKevin Wolf # 1744de110f8SKevin Wolf # Invalid BlockdevRef 1754de110f8SKevin Wolf # 1764de110f8SKevin Wolf iotests.log("=== Invalid BlockdevRef ===") 1774de110f8SKevin Wolf iotests.log("") 17839218a77SKevin Wolf 1794de110f8SKevin Wolf vm.launch() 180*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 1814de110f8SKevin Wolf 'file': "this doesn't exist", 1824de110f8SKevin Wolf 'size': size }) 1834de110f8SKevin Wolf vm.shutdown() 18439218a77SKevin Wolf 1854de110f8SKevin Wolf # 1864de110f8SKevin Wolf # Invalid sizes 1874de110f8SKevin Wolf # 1884de110f8SKevin Wolf iotests.log("=== Invalid sizes ===") 18939218a77SKevin Wolf 19039218a77SKevin Wolf # TODO Negative image sizes aren't handled correctly, but this is a problem 1914de110f8SKevin Wolf # with QAPI's implementation of the 'size' type and affects other commands 1924de110f8SKevin Wolf # as well. Once this is fixed, we may want to add a test case here. 1934de110f8SKevin Wolf # 19439218a77SKevin Wolf # 1. Misaligned image size 19539218a77SKevin Wolf # 2. 2^64 - 512 19639218a77SKevin Wolf # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 19739218a77SKevin Wolf # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) 19839218a77SKevin Wolf 1994de110f8SKevin Wolf vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 20039218a77SKevin Wolf 2014de110f8SKevin Wolf vm.launch() 2024de110f8SKevin Wolf for size in [ 1234, 18446744073709551104, 9223372036854775808, 2034de110f8SKevin Wolf 9223372036854775296 ]: 204*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2054de110f8SKevin Wolf 'file': 'node0', 2064de110f8SKevin Wolf 'size': size }) 2074de110f8SKevin Wolf vm.shutdown() 20839218a77SKevin Wolf 2094de110f8SKevin Wolf # 2104de110f8SKevin Wolf # Invalid version 2114de110f8SKevin Wolf # 2124de110f8SKevin Wolf iotests.log("=== Invalid version ===") 21339218a77SKevin Wolf 2144de110f8SKevin Wolf vm.launch() 215*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2164de110f8SKevin Wolf 'file': 'node0', 2174de110f8SKevin Wolf 'size': 67108864, 2184de110f8SKevin Wolf 'version': 'v1' }) 219*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2204de110f8SKevin Wolf 'file': 'node0', 2214de110f8SKevin Wolf 'size': 67108864, 2224de110f8SKevin Wolf 'version': 'v2', 2234de110f8SKevin Wolf 'lazy-refcounts': True }) 224*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2254de110f8SKevin Wolf 'file': 'node0', 2264de110f8SKevin Wolf 'size': 67108864, 2274de110f8SKevin Wolf 'version': 'v2', 2284de110f8SKevin Wolf 'refcount-bits': 8 }) 2294de110f8SKevin Wolf vm.shutdown() 23039218a77SKevin Wolf 2314de110f8SKevin Wolf # 2324de110f8SKevin Wolf # Invalid backing file options 2334de110f8SKevin Wolf # 2344de110f8SKevin Wolf iotests.log("=== Invalid backing file options ===") 23539218a77SKevin Wolf 2364de110f8SKevin Wolf vm.launch() 237*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2384de110f8SKevin Wolf 'file': 'node0', 2394de110f8SKevin Wolf 'size': 67108864, 2404de110f8SKevin Wolf 'backing-file': '/dev/null', 2414de110f8SKevin Wolf 'preallocation': 'full' }) 242*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2434de110f8SKevin Wolf 'file': 'node0', 2444de110f8SKevin Wolf 'size': 67108864, 2454de110f8SKevin Wolf 'backing-fmt': imgfmt }) 2464de110f8SKevin Wolf vm.shutdown() 24739218a77SKevin Wolf 2484de110f8SKevin Wolf # 2494de110f8SKevin Wolf # Invalid cluster size 2504de110f8SKevin Wolf # 2514de110f8SKevin Wolf iotests.log("=== Invalid cluster size ===") 25239218a77SKevin Wolf 2534de110f8SKevin Wolf vm.launch() 2544de110f8SKevin Wolf for csize in [ 1234, 128, 4194304, 0 ]: 255*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2564de110f8SKevin Wolf 'file': 'node0', 2574de110f8SKevin Wolf 'size': 67108864, 2584de110f8SKevin Wolf 'cluster-size': csize }) 259*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2604de110f8SKevin Wolf 'file': 'node0', 2614de110f8SKevin Wolf 'size': 281474976710656, 2624de110f8SKevin Wolf 'cluster-size': 512 }) 2634de110f8SKevin Wolf vm.shutdown() 26439218a77SKevin Wolf 2654de110f8SKevin Wolf # 2664de110f8SKevin Wolf # Invalid refcount width 2674de110f8SKevin Wolf # 2684de110f8SKevin Wolf iotests.log("=== Invalid refcount width ===") 26939218a77SKevin Wolf 2704de110f8SKevin Wolf vm.launch() 2714de110f8SKevin Wolf for refcount_bits in [ 128, 0, 7 ]: 272*f6da1736SKevin Wolf vm.blockdev_create({ 'driver': imgfmt, 2734de110f8SKevin Wolf 'file': 'node0', 2744de110f8SKevin Wolf 'size': 67108864, 2754de110f8SKevin Wolf 'refcount-bits': refcount_bits }) 2764de110f8SKevin Wolf vm.shutdown() 277