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.script_initialize(supported_fmts=['qcow2'], 27 supported_protocols=['file']) 28iotests.verify_working_luks() 29 30with iotests.FilePath('t.qcow2') as disk_path, \ 31 iotests.FilePath('t.qcow2.base') as backing_path, \ 32 iotests.VM() as vm: 33 34 vm.add_object('secret,id=keysec0,data=foo') 35 36 # 37 # Successful image creation (defaults) 38 # 39 iotests.log("=== Successful image creation (defaults) ===") 40 iotests.log("") 41 42 size = 128 * 1024 * 1024 43 44 vm.launch() 45 vm.blockdev_create({ 'driver': 'file', 46 'filename': disk_path, 47 'size': 0 }) 48 49 vm.qmp_log('blockdev-add', 50 filters=[iotests.filter_qmp_testfiles], 51 driver='file', filename=disk_path, 52 node_name='imgfile') 53 54 vm.blockdev_create({ 'driver': imgfmt, 55 'file': 'imgfile', 56 'size': size }) 57 vm.shutdown() 58 59 iotests.img_info_log(disk_path) 60 61 # 62 # Successful image creation (inline blockdev-add, explicit defaults) 63 # 64 iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") 65 iotests.log("") 66 67 # Choose a different size to show that we got a new image 68 size = 64 * 1024 * 1024 69 70 vm.launch() 71 vm.blockdev_create({ 'driver': 'file', 72 'filename': disk_path, 73 'size': 0, 74 'preallocation': 'off', 75 'nocow': False }) 76 77 vm.blockdev_create({ 'driver': imgfmt, 78 'file': { 79 'driver': 'file', 80 'filename': disk_path, 81 }, 82 'size': size, 83 'version': 'v3', 84 'cluster-size': 65536, 85 'preallocation': 'off', 86 'lazy-refcounts': False, 87 'refcount-bits': 16 }) 88 vm.shutdown() 89 90 iotests.img_info_log(disk_path) 91 92 # 93 # Successful image creation (v3 non-default options) 94 # 95 iotests.log("=== Successful image creation (v3 non-default options) ===") 96 iotests.log("") 97 98 # Choose a different size to show that we got a new image 99 size = 32 * 1024 * 1024 100 101 vm.launch() 102 vm.blockdev_create({ 'driver': 'file', 103 'filename': disk_path, 104 'size': 0, 105 'preallocation': 'falloc', 106 'nocow': True }) 107 108 vm.blockdev_create({ 'driver': imgfmt, 109 'file': { 110 'driver': 'file', 111 'filename': disk_path, 112 }, 113 'size': size, 114 'version': 'v3', 115 'cluster-size': 2097152, 116 'preallocation': 'metadata', 117 'lazy-refcounts': True, 118 'refcount-bits': 1 }) 119 vm.shutdown() 120 121 iotests.img_info_log(disk_path) 122 123 # 124 # Successful image creation (v2 non-default options) 125 # 126 iotests.log("=== Successful image creation (v2 non-default options) ===") 127 iotests.log("") 128 129 vm.launch() 130 vm.blockdev_create({ 'driver': 'file', 131 'filename': disk_path, 132 'size': 0 }) 133 134 vm.blockdev_create({ 'driver': imgfmt, 135 'file': { 136 'driver': 'file', 137 'filename': disk_path, 138 }, 139 'size': size, 140 'backing-file': backing_path, 141 'backing-fmt': 'qcow2', 142 'version': 'v2', 143 'cluster-size': 512 }) 144 vm.shutdown() 145 146 iotests.img_info_log(disk_path) 147 148 # 149 # Successful image creation (encrypted) 150 # 151 iotests.log("=== Successful image creation (encrypted) ===") 152 iotests.log("") 153 154 vm.launch() 155 vm.blockdev_create({ 'driver': imgfmt, 156 'file': { 157 'driver': 'file', 158 'filename': disk_path, 159 }, 160 'size': size, 161 'encrypt': { 162 'format': 'luks', 163 'key-secret': 'keysec0', 164 'cipher-alg': 'twofish-128', 165 'cipher-mode': 'ctr', 166 'ivgen-alg': 'plain64', 167 'ivgen-hash-alg': 'md5', 168 'hash-alg': 'sha1', 169 'iter-time': 10, 170 }}) 171 vm.shutdown() 172 173 iotests.img_info_log(disk_path) 174 175 # 176 # Invalid BlockdevRef 177 # 178 iotests.log("=== Invalid BlockdevRef ===") 179 iotests.log("") 180 181 vm.launch() 182 vm.blockdev_create({ 'driver': imgfmt, 183 'file': "this doesn't exist", 184 'size': size }) 185 vm.shutdown() 186 187 # 188 # Invalid sizes 189 # 190 iotests.log("=== Invalid sizes ===") 191 192 # TODO Negative image sizes aren't handled correctly, but this is a problem 193 # with QAPI's implementation of the 'size' type and affects other commands 194 # as well. Once this is fixed, we may want to add a test case here. 195 # 196 # 1. Misaligned image size 197 # 2. 2^64 - 512 198 # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 199 # 4. 2^63 - 512 (generally valid, but qcow2 can't handle images this size) 200 201 vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 202 203 vm.launch() 204 for size in [ 1234, 18446744073709551104, 9223372036854775808, 205 9223372036854775296, 9223372035781033984 ]: 206 vm.blockdev_create({ 'driver': imgfmt, 207 'file': 'node0', 208 'size': size }) 209 vm.shutdown() 210 211 # 212 # Invalid version 213 # 214 iotests.log("=== Invalid version ===") 215 216 vm.launch() 217 vm.blockdev_create({ 'driver': imgfmt, 218 'file': 'node0', 219 'size': 67108864, 220 'version': 'v1' }) 221 vm.blockdev_create({ 'driver': imgfmt, 222 'file': 'node0', 223 'size': 67108864, 224 'version': 'v2', 225 'lazy-refcounts': True }) 226 vm.blockdev_create({ 'driver': imgfmt, 227 'file': 'node0', 228 'size': 67108864, 229 'version': 'v2', 230 'refcount-bits': 8 }) 231 vm.shutdown() 232 233 # 234 # Invalid backing file options 235 # 236 iotests.log("=== Invalid backing file options ===") 237 238 vm.launch() 239 vm.blockdev_create({ 'driver': imgfmt, 240 'file': 'node0', 241 'size': 67108864, 242 'backing-file': '/dev/null', 243 'preallocation': 'full' }) 244 vm.blockdev_create({ 'driver': imgfmt, 245 'file': 'node0', 246 'size': 67108864, 247 'backing-fmt': imgfmt }) 248 vm.shutdown() 249 250 # 251 # Invalid cluster size 252 # 253 iotests.log("=== Invalid cluster size ===") 254 255 vm.launch() 256 for csize in [ 1234, 128, 4194304, 0 ]: 257 vm.blockdev_create({ 'driver': imgfmt, 258 'file': 'node0', 259 'size': 67108864, 260 'cluster-size': csize }) 261 vm.blockdev_create({ 'driver': imgfmt, 262 'file': 'node0', 263 'size': 281474976710656, 264 'cluster-size': 512 }) 265 vm.shutdown() 266 267 # 268 # Invalid refcount width 269 # 270 iotests.log("=== Invalid refcount width ===") 271 272 vm.launch() 273 for refcount_bits in [ 128, 0, 7 ]: 274 vm.blockdev_create({ 'driver': imgfmt, 275 'file': 'node0', 276 'size': 67108864, 277 'refcount-bits': refcount_bits }) 278 vm.shutdown() 279