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