#!/usr/bin/env python # # Test vmdk and file image creation # # Copyright (C) 2018 Red Hat, Inc. # # Creator/Owner: Kevin Wolf # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import math import iotests from iotests import imgfmt iotests.verify_image_format(supported_fmts=['vmdk']) def blockdev_create(vm, options): result = vm.qmp_log('blockdev-create', job_id='job0', options=options) if 'return' in result: assert result['return'] == {} vm.run_job('job0') iotests.log("") with iotests.FilePath('t.vmdk') as disk_path, \ iotests.FilePath('t.vmdk.1') as extent1_path, \ iotests.FilePath('t.vmdk.2') as extent2_path, \ iotests.FilePath('t.vmdk.3') as extent3_path, \ iotests.VM() as vm: # # Successful image creation (defaults) # iotests.log("=== Successful image creation (defaults) ===") iotests.log("") size = 5 * 1024 * 1024 * 1024 vm.launch() blockdev_create(vm, { 'driver': 'file', 'filename': disk_path, 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, node_name='imgfile') blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', 'size': size }) vm.shutdown() iotests.img_info_log(disk_path) # # Successful image creation (inline blockdev-add, explicit defaults) # iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===") iotests.log("") # Choose a different size to show that we got a new image size = 64 * 1024 * 1024 vm.launch() blockdev_create(vm, { 'driver': 'file', 'filename': disk_path, 'size': 0 }) blockdev_create(vm, { 'driver': imgfmt, 'file': { 'driver': 'file', 'filename': disk_path, }, 'size': size, 'extents': [], 'subformat': 'monolithicSparse', 'adapter-type': 'ide', 'hwversion': '4', 'zeroed-grain': False }) vm.shutdown() iotests.img_info_log(disk_path) # # Successful image creation (non-default options) # iotests.log("=== Successful image creation (with non-default options) ===") iotests.log("") # Choose a different size to show that we got a new image size = 32 * 1024 * 1024 vm.launch() blockdev_create(vm, { 'driver': 'file', 'filename': disk_path, 'size': 0 }) blockdev_create(vm, { 'driver': imgfmt, 'file': { 'driver': 'file', 'filename': disk_path, }, 'size': size, 'extents': [], 'subformat': 'monolithicSparse', 'adapter-type': 'buslogic', 'zeroed-grain': True }) vm.shutdown() iotests.img_info_log(disk_path) # # Invalid BlockdevRef # iotests.log("=== Invalid BlockdevRef ===") iotests.log("") vm.launch() blockdev_create(vm, { 'driver': imgfmt, 'file': "this doesn't exist", 'size': size }) vm.shutdown() # # Adapter types # iotests.log("=== Adapter types ===") iotests.log("") vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) # Valid iotests.log("== Valid adapter types ==") iotests.log("") vm.launch() for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]: blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': size, 'adapter-type': adapter_type }) vm.shutdown() # Invalid iotests.log("== Invalid adapter types ==") iotests.log("") vm.launch() for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]: blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': size, 'adapter-type': adapter_type }) vm.shutdown() # # Other subformats # iotests.log("=== Other subformats ===") iotests.log("") for path in [ extent1_path, extent2_path, extent3_path ]: msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0') iotests.log(msg, [iotests.filter_testfiles]) vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path)) vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path)) vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path)) # Missing extent iotests.log("== Missing extent ==") iotests.log("") vm.launch() blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': size, 'subformat': 'monolithicFlat' }) vm.shutdown() # Correct extent iotests.log("== Correct extent ==") iotests.log("") vm.launch() blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': size, 'subformat': 'monolithicFlat', 'extents': ['ext1'] }) vm.shutdown() # Extra extent iotests.log("== Extra extent ==") iotests.log("") vm.launch() blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': 512, 'subformat': 'monolithicFlat', 'extents': ['ext1', 'ext2', 'ext3'] }) vm.shutdown() # Split formats iotests.log("== Split formats ==") iotests.log("") for size in [ 512, 1073741824, 2147483648, 5368709120 ]: for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]: iotests.log("= %s %d =" % (subfmt, size)) iotests.log("") num_extents = math.ceil(size / 2.0**31) extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ] vm.launch() blockdev_create(vm, { 'driver': imgfmt, 'file': 'node0', 'size': size, 'subformat': subfmt, 'extents': extents }) vm.shutdown() iotests.img_info_log(disk_path)