|  | #!/usr/bin/env python3 | 
|  | # group: rw quick | 
|  | # | 
|  | # Test vmdk and file image creation | 
|  | # | 
|  | # Copyright (C) 2018 Red Hat, Inc. | 
|  | # | 
|  | # Creator/Owner: Kevin Wolf <kwolf@redhat.com> | 
|  | # | 
|  | # 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 <http://www.gnu.org/licenses/>. | 
|  | # | 
|  |  | 
|  | import math | 
|  | import iotests | 
|  | from iotests import imgfmt | 
|  |  | 
|  | iotests.script_initialize(supported_fmts=['vmdk']) | 
|  |  | 
|  | 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() | 
|  | vm.blockdev_create({ 'driver': 'file', | 
|  | 'filename': disk_path, | 
|  | 'size': 0 }) | 
|  |  | 
|  | vm.qmp_log('blockdev-add', driver='file', filename=disk_path, | 
|  | node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) | 
|  |  | 
|  | vm.blockdev_create({ '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() | 
|  | vm.blockdev_create({ 'driver': 'file', | 
|  | 'filename': disk_path, | 
|  | 'size': 0 }) | 
|  |  | 
|  | vm.blockdev_create({ '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() | 
|  | vm.blockdev_create({ 'driver': 'file', | 
|  | 'filename': disk_path, | 
|  | 'size': 0 }) | 
|  |  | 
|  | vm.blockdev_create({ '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() | 
|  | vm.blockdev_create({ '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' ]: | 
|  | vm.blockdev_create({ '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 ]: | 
|  | vm.blockdev_create({ '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 ]: | 
|  | iotests.qemu_img_create('-f', imgfmt, path, '0') | 
|  |  | 
|  | 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() | 
|  | vm.blockdev_create({ 'driver': imgfmt, | 
|  | 'file': 'node0', | 
|  | 'size': size, | 
|  | 'subformat': 'monolithicFlat' }) | 
|  | vm.shutdown() | 
|  |  | 
|  | # Correct extent | 
|  | iotests.log("== Correct extent ==") | 
|  | iotests.log("") | 
|  |  | 
|  | vm.launch() | 
|  | vm.blockdev_create({ 'driver': imgfmt, | 
|  | 'file': 'node0', | 
|  | 'size': size, | 
|  | 'subformat': 'monolithicFlat', | 
|  | 'extents': ['ext1'] }) | 
|  | vm.shutdown() | 
|  |  | 
|  | # Extra extent | 
|  | iotests.log("== Extra extent ==") | 
|  | iotests.log("") | 
|  |  | 
|  | vm.launch() | 
|  | vm.blockdev_create({ '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 = int(math.ceil(size / 2.0**31)) | 
|  | extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ] | 
|  |  | 
|  | vm.launch() | 
|  | vm.blockdev_create({ 'driver': imgfmt, | 
|  | 'file': 'node0', | 
|  | 'size': size, | 
|  | 'subformat': subfmt, | 
|  | 'extents': extents }) | 
|  | vm.shutdown() | 
|  |  | 
|  | iotests.img_info_log(disk_path) |