1#!/usr/bin/env python 2# 3# Test vmdk 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 math 24import iotests 25from iotests import imgfmt 26 27iotests.verify_image_format(supported_fmts=['vmdk']) 28 29def blockdev_create(vm, options): 30 result = vm.qmp_log('blockdev-create', job_id='job0', options=options) 31 32 if 'return' in result: 33 assert result['return'] == {} 34 vm.run_job('job0') 35 iotests.log("") 36 37with iotests.FilePath('t.vmdk') as disk_path, \ 38 iotests.FilePath('t.vmdk.1') as extent1_path, \ 39 iotests.FilePath('t.vmdk.2') as extent2_path, \ 40 iotests.FilePath('t.vmdk.3') as extent3_path, \ 41 iotests.VM() as vm: 42 43 # 44 # Successful image creation (defaults) 45 # 46 iotests.log("=== Successful image creation (defaults) ===") 47 iotests.log("") 48 49 size = 5 * 1024 * 1024 * 1024 50 51 vm.launch() 52 blockdev_create(vm, { 'driver': 'file', 53 'filename': disk_path, 54 'size': 0 }) 55 56 vm.qmp_log('blockdev-add', driver='file', filename=disk_path, 57 node_name='imgfile') 58 59 blockdev_create(vm, { 'driver': imgfmt, 60 'file': 'imgfile', 61 'size': size }) 62 vm.shutdown() 63 64 iotests.img_info_log(disk_path) 65 66 # 67 # Successful image creation (inline blockdev-add, explicit defaults) 68 # 69 iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") 70 iotests.log("") 71 72 # Choose a different size to show that we got a new image 73 size = 64 * 1024 * 1024 74 75 vm.launch() 76 blockdev_create(vm, { 'driver': 'file', 77 'filename': disk_path, 78 'size': 0 }) 79 80 blockdev_create(vm, { 'driver': imgfmt, 81 'file': { 82 'driver': 'file', 83 'filename': disk_path, 84 }, 85 'size': size, 86 'extents': [], 87 'subformat': 'monolithicSparse', 88 'adapter-type': 'ide', 89 'hwversion': '4', 90 'zeroed-grain': False }) 91 vm.shutdown() 92 93 iotests.img_info_log(disk_path) 94 95 # 96 # Successful image creation (non-default options) 97 # 98 iotests.log("=== Successful image creation (with non-default options) ===") 99 iotests.log("") 100 101 # Choose a different size to show that we got a new image 102 size = 32 * 1024 * 1024 103 104 vm.launch() 105 blockdev_create(vm, { 'driver': 'file', 106 'filename': disk_path, 107 'size': 0 }) 108 109 blockdev_create(vm, { 'driver': imgfmt, 110 'file': { 111 'driver': 'file', 112 'filename': disk_path, 113 }, 114 'size': size, 115 'extents': [], 116 'subformat': 'monolithicSparse', 117 'adapter-type': 'buslogic', 118 'zeroed-grain': True }) 119 vm.shutdown() 120 121 iotests.img_info_log(disk_path) 122 123 # 124 # Invalid BlockdevRef 125 # 126 iotests.log("=== Invalid BlockdevRef ===") 127 iotests.log("") 128 129 vm.launch() 130 blockdev_create(vm, { 'driver': imgfmt, 131 'file': "this doesn't exist", 132 'size': size }) 133 vm.shutdown() 134 135 # 136 # Adapter types 137 # 138 139 iotests.log("=== Adapter types ===") 140 iotests.log("") 141 142 vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 143 144 # Valid 145 iotests.log("== Valid adapter types ==") 146 iotests.log("") 147 148 vm.launch() 149 for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]: 150 blockdev_create(vm, { 'driver': imgfmt, 151 'file': 'node0', 152 'size': size, 153 'adapter-type': adapter_type }) 154 vm.shutdown() 155 156 # Invalid 157 iotests.log("== Invalid adapter types ==") 158 iotests.log("") 159 160 vm.launch() 161 for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]: 162 blockdev_create(vm, { 'driver': imgfmt, 163 'file': 'node0', 164 'size': size, 165 'adapter-type': adapter_type }) 166 vm.shutdown() 167 168 # 169 # Other subformats 170 # 171 iotests.log("=== Other subformats ===") 172 iotests.log("") 173 174 for path in [ extent1_path, extent2_path, extent3_path ]: 175 msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0') 176 iotests.log(msg, [iotests.filter_testfiles]) 177 178 vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path)) 179 vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path)) 180 vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path)) 181 182 # Missing extent 183 iotests.log("== Missing extent ==") 184 iotests.log("") 185 186 vm.launch() 187 blockdev_create(vm, { 'driver': imgfmt, 188 'file': 'node0', 189 'size': size, 190 'subformat': 'monolithicFlat' }) 191 vm.shutdown() 192 193 # Correct extent 194 iotests.log("== Correct extent ==") 195 iotests.log("") 196 197 vm.launch() 198 blockdev_create(vm, { 'driver': imgfmt, 199 'file': 'node0', 200 'size': size, 201 'subformat': 'monolithicFlat', 202 'extents': ['ext1'] }) 203 vm.shutdown() 204 205 # Extra extent 206 iotests.log("== Extra extent ==") 207 iotests.log("") 208 209 vm.launch() 210 blockdev_create(vm, { 'driver': imgfmt, 211 'file': 'node0', 212 'size': 512, 213 'subformat': 'monolithicFlat', 214 'extents': ['ext1', 'ext2', 'ext3'] }) 215 vm.shutdown() 216 217 # Split formats 218 iotests.log("== Split formats ==") 219 iotests.log("") 220 221 for size in [ 512, 1073741824, 2147483648, 5368709120 ]: 222 for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]: 223 iotests.log("= %s %d =" % (subfmt, size)) 224 iotests.log("") 225 226 num_extents = math.ceil(size / 2.0**31) 227 extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ] 228 229 vm.launch() 230 blockdev_create(vm, { 'driver': imgfmt, 231 'file': 'node0', 232 'size': size, 233 'subformat': subfmt, 234 'extents': extents }) 235 vm.shutdown() 236 237 iotests.img_info_log(disk_path) 238