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