1bf03dedeSKevin Wolf#!/usr/bin/env python3 2bf03dedeSKevin Wolf# 3bf03dedeSKevin Wolf# Copyright (C) 2019 Red Hat, Inc. 4bf03dedeSKevin Wolf# 5bf03dedeSKevin Wolf# This program is free software; you can redistribute it and/or modify 6bf03dedeSKevin Wolf# it under the terms of the GNU General Public License as published by 7bf03dedeSKevin Wolf# the Free Software Foundation; either version 2 of the License, or 8bf03dedeSKevin Wolf# (at your option) any later version. 9bf03dedeSKevin Wolf# 10bf03dedeSKevin Wolf# This program is distributed in the hope that it will be useful, 11bf03dedeSKevin Wolf# but WITHOUT ANY WARRANTY; without even the implied warranty of 12bf03dedeSKevin Wolf# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13bf03dedeSKevin Wolf# GNU General Public License for more details. 14bf03dedeSKevin Wolf# 15bf03dedeSKevin Wolf# You should have received a copy of the GNU General Public License 16bf03dedeSKevin Wolf# along with this program. If not, see <http://www.gnu.org/licenses/>. 17bf03dedeSKevin Wolf# 18bf03dedeSKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 19bf03dedeSKevin Wolf# 20bf03dedeSKevin Wolf# Some tests for short backing files and short overlays 21bf03dedeSKevin Wolf 22bf03dedeSKevin Wolfimport iotests 23bf03dedeSKevin Wolf 247d814059SJohn Snowiotests.script_initialize(supported_fmts=['qcow2'], 257d814059SJohn Snow supported_platforms=['linux']) 26bf03dedeSKevin Wolf 27bf03dedeSKevin Wolfsize_short = 1 * 1024 * 1024 28bf03dedeSKevin Wolfsize_long = 2 * 1024 * 1024 29bf03dedeSKevin Wolfsize_diff = size_long - size_short 30bf03dedeSKevin Wolf 31bf03dedeSKevin Wolfdef create_chain() -> None: 32bf03dedeSKevin Wolf iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, 33bf03dedeSKevin Wolf str(size_long)) 34*b66ff2c2SEric Blake iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, 35*b66ff2c2SEric Blake '-F', iotests.imgfmt, mid, str(size_short)) 36*b66ff2c2SEric Blake iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, 37*b66ff2c2SEric Blake '-F', iotests.imgfmt, top, str(size_long)) 38bf03dedeSKevin Wolf 39bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base) 40bf03dedeSKevin Wolf 41bf03dedeSKevin Wolfdef create_vm() -> iotests.VM: 42bf03dedeSKevin Wolf vm = iotests.VM() 43bf03dedeSKevin Wolf vm.add_blockdev('file,filename=%s,node-name=base-file' % base) 44bf03dedeSKevin Wolf vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt) 45bf03dedeSKevin Wolf vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid) 46bf03dedeSKevin Wolf vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base' 47bf03dedeSKevin Wolf % iotests.imgfmt) 48bf03dedeSKevin Wolf vm.add_drive(top, 'backing=mid,node-name=top') 49bf03dedeSKevin Wolf return vm 50bf03dedeSKevin Wolf 51bf03dedeSKevin Wolfwith iotests.FilePath('base') as base, \ 52bf03dedeSKevin Wolf iotests.FilePath('mid') as mid, \ 53bf03dedeSKevin Wolf iotests.FilePath('top') as top: 54bf03dedeSKevin Wolf 55bf03dedeSKevin Wolf iotests.log('== Commit tests ==') 56bf03dedeSKevin Wolf 57bf03dedeSKevin Wolf create_chain() 58bf03dedeSKevin Wolf 59bf03dedeSKevin Wolf iotests.log('=== Check visible data ===') 60bf03dedeSKevin Wolf 61bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top) 62bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top) 63bf03dedeSKevin Wolf 64bf03dedeSKevin Wolf iotests.log('=== Checking allocation status ===') 65bf03dedeSKevin Wolf 66bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, 67bf03dedeSKevin Wolf '-c', 'alloc %d %d' % (size_short, size_diff), 68bf03dedeSKevin Wolf base) 69bf03dedeSKevin Wolf 70bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, 71bf03dedeSKevin Wolf '-c', 'alloc %d %d' % (size_short, size_diff), 72bf03dedeSKevin Wolf mid) 73bf03dedeSKevin Wolf 74bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short, 75bf03dedeSKevin Wolf '-c', 'alloc %d %d' % (size_short, size_diff), 76bf03dedeSKevin Wolf top) 77bf03dedeSKevin Wolf 78bf03dedeSKevin Wolf iotests.log('=== Checking map ===') 79bf03dedeSKevin Wolf 80bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=json', base) 81bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=human', base) 82bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=json', mid) 83bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=human', mid) 84bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=json', top) 85bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=human', top) 86bf03dedeSKevin Wolf 87bf03dedeSKevin Wolf iotests.log('=== Testing qemu-img commit (top -> mid) ===') 88bf03dedeSKevin Wolf 89bf03dedeSKevin Wolf iotests.qemu_img_log('commit', top) 90bf03dedeSKevin Wolf iotests.img_info_log(mid) 91bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) 92bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) 93bf03dedeSKevin Wolf 94bf03dedeSKevin Wolf iotests.log('=== Testing HMP commit (top -> mid) ===') 95bf03dedeSKevin Wolf 96bf03dedeSKevin Wolf create_chain() 97bf03dedeSKevin Wolf with create_vm() as vm: 98bf03dedeSKevin Wolf vm.launch() 99bf03dedeSKevin Wolf vm.qmp_log('human-monitor-command', command_line='commit drive0') 100bf03dedeSKevin Wolf 101bf03dedeSKevin Wolf iotests.img_info_log(mid) 102bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) 103bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) 104bf03dedeSKevin Wolf 105bf03dedeSKevin Wolf iotests.log('=== Testing QMP active commit (top -> mid) ===') 106bf03dedeSKevin Wolf 107bf03dedeSKevin Wolf create_chain() 108bf03dedeSKevin Wolf with create_vm() as vm: 109bf03dedeSKevin Wolf vm.launch() 110bf03dedeSKevin Wolf vm.qmp_log('block-commit', device='top', base_node='mid', 111bf03dedeSKevin Wolf job_id='job0', auto_dismiss=False) 112bf03dedeSKevin Wolf vm.run_job('job0', wait=5) 113bf03dedeSKevin Wolf 114bf03dedeSKevin Wolf iotests.img_info_log(mid) 115bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid) 116bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid) 117bf03dedeSKevin Wolf 118bf03dedeSKevin Wolf 119bf03dedeSKevin Wolf iotests.log('== Resize tests ==') 120bf03dedeSKevin Wolf 121bf03dedeSKevin Wolf # Use different sizes for different allocation modes: 122bf03dedeSKevin Wolf # 123bf03dedeSKevin Wolf # We want to have at least one test where 32 bit truncation in the size of 124bf03dedeSKevin Wolf # the overlapping area becomes visible. This is covered by the 125bf03dedeSKevin Wolf # prealloc='off' case (1G to 6G is an overlap of 5G). 126bf03dedeSKevin Wolf # 127bf03dedeSKevin Wolf # However, we can only do this for modes that don't preallocate data 128bf03dedeSKevin Wolf # because otherwise we might run out of space on the test host. 129bf03dedeSKevin Wolf # 130bf03dedeSKevin Wolf # We also want to test some unaligned combinations. 131bf03dedeSKevin Wolf for (prealloc, base_size, top_size_old, top_size_new, off) in [ 132bf03dedeSKevin Wolf ('off', '6G', '1G', '8G', '5G'), 133bf03dedeSKevin Wolf ('metadata', '32G', '30G', '33G', '31G'), 134bf03dedeSKevin Wolf ('falloc', '10M', '5M', '15M', '9M'), 135bf03dedeSKevin Wolf ('full', '16M', '8M', '12M', '11M'), 136bf03dedeSKevin Wolf ('off', '384k', '253k', '512k', '253k'), 137bf03dedeSKevin Wolf ('off', '400k', '256k', '512k', '336k'), 138bf03dedeSKevin Wolf ('off', '512k', '256k', '500k', '436k')]: 139bf03dedeSKevin Wolf 140bf03dedeSKevin Wolf iotests.log('=== preallocation=%s ===' % prealloc) 141bf03dedeSKevin Wolf iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size) 142*b66ff2c2SEric Blake iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, 143*b66ff2c2SEric Blake '-F', iotests.imgfmt, top, top_size_old) 144bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base) 145bf03dedeSKevin Wolf 146bf03dedeSKevin Wolf # After this, top_size_old to base_size should be allocated/zeroed. 147bf03dedeSKevin Wolf # 148bf03dedeSKevin Wolf # In theory, leaving base_size to top_size_new unallocated would be 149bf03dedeSKevin Wolf # correct, but in practice, if we zero out anything, we zero out 150bf03dedeSKevin Wolf # everything up to top_size_new. 151bf03dedeSKevin Wolf iotests.qemu_img_log('resize', '-f', iotests.imgfmt, 152bf03dedeSKevin Wolf '--preallocation', prealloc, top, top_size_new) 153bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top) 154bf03dedeSKevin Wolf iotests.qemu_io_log('-c', 'map', top) 155bf03dedeSKevin Wolf iotests.qemu_img_log('map', '--output=json', top) 156