17c477526SPhilippe Mathieu-Daudé#!/usr/bin/env python3 29dd003a9SVladimir Sementsov-Ogievskiy# group: quick 314da540fSJohn Snow# 414da540fSJohn Snow# Test bitmap merges. 514da540fSJohn Snow# 614da540fSJohn Snow# Copyright (c) 2018 John Snow for Red Hat, Inc. 714da540fSJohn Snow# 814da540fSJohn Snow# This program is free software; you can redistribute it and/or modify 914da540fSJohn Snow# it under the terms of the GNU General Public License as published by 1014da540fSJohn Snow# the Free Software Foundation; either version 2 of the License, or 1114da540fSJohn Snow# (at your option) any later version. 1214da540fSJohn Snow# 1314da540fSJohn Snow# This program is distributed in the hope that it will be useful, 1414da540fSJohn Snow# but WITHOUT ANY WARRANTY; without even the implied warranty of 1514da540fSJohn Snow# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1614da540fSJohn Snow# GNU General Public License for more details. 1714da540fSJohn Snow# 1814da540fSJohn Snow# You should have received a copy of the GNU General Public License 1914da540fSJohn Snow# along with this program. If not, see <http://www.gnu.org/licenses/>. 2014da540fSJohn Snow# 2114da540fSJohn Snow# owner=jsnow@redhat.com 2214da540fSJohn Snow 2314da540fSJohn Snowimport iotests 2414da540fSJohn Snowfrom iotests import log 2514da540fSJohn Snow 267d814059SJohn Snowiotests.script_initialize(supported_fmts=['generic']) 2714da540fSJohn Snowsize = 64 * 1024 * 1024 2814da540fSJohn Snowgranularity = 64 * 1024 2914da540fSJohn Snow 3014da540fSJohn Snowpatterns = [("0x5d", "0", "64k"), 3114da540fSJohn Snow ("0xd5", "1M", "64k"), 3214da540fSJohn Snow ("0xdc", "32M", "64k"), 3314da540fSJohn Snow ("0xcd", "0x3ff0000", "64k")] # 64M - 64K 3414da540fSJohn Snow 3514da540fSJohn Snowoverwrite = [("0xab", "0", "64k"), # Full overwrite 3614da540fSJohn Snow ("0xad", "0x00f8000", "64k"), # Partial-left (1M-32K) 3714da540fSJohn Snow ("0x1d", "0x2008000", "64k"), # Partial-right (32M+32K) 3814da540fSJohn Snow ("0xea", "0x3fe0000", "64k")] # Adjacent-left (64M - 128K) 3914da540fSJohn Snow 4014da540fSJohn Snowdef query_bitmaps(vm): 4114da540fSJohn Snow res = vm.qmp("query-block") 42*e67d8e29SDaniel P. Berrangé return { "bitmaps": { device['device']: device.get('inserted', {}).get('dirty-bitmaps', []) for 4314da540fSJohn Snow device in res['return'] } } 4414da540fSJohn Snow 4514da540fSJohn Snowwith iotests.FilePath('img') as img_path, \ 4614da540fSJohn Snow iotests.VM() as vm: 4714da540fSJohn Snow 4814da540fSJohn Snow log('--- Preparing image & VM ---\n') 4914da540fSJohn Snow iotests.qemu_img_create('-f', iotests.imgfmt, img_path, str(size)) 5014da540fSJohn Snow vm.add_drive(img_path) 5114da540fSJohn Snow vm.launch() 5214da540fSJohn Snow 5314da540fSJohn Snow log('\n--- Adding preliminary bitmaps A & B ---\n') 5414da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-add", node="drive0", 5514da540fSJohn Snow name="bitmapA", granularity=granularity) 5614da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-add", node="drive0", 5714da540fSJohn Snow name="bitmapB", granularity=granularity) 5814da540fSJohn Snow 5914da540fSJohn Snow # Dirties 4 clusters. count=262144 6014da540fSJohn Snow log('\n--- Emulating writes ---\n') 6114da540fSJohn Snow for p in patterns: 6214da540fSJohn Snow cmd = "write -P%s %s %s" % p 6314da540fSJohn Snow log(cmd) 6414da540fSJohn Snow log(vm.hmp_qemu_io("drive0", cmd)) 6514da540fSJohn Snow 6614da540fSJohn Snow log(query_bitmaps(vm), indent=2) 6714da540fSJohn Snow 6814da540fSJohn Snow log('\n--- Submitting & Aborting Transaction ---\n') 6914da540fSJohn Snow vm.qmp_log("transaction", indent=2, actions=[ 7014da540fSJohn Snow { "type": "block-dirty-bitmap-disable", 7114da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapB" }}, 7214da540fSJohn Snow { "type": "block-dirty-bitmap-add", 7314da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapC", 7414da540fSJohn Snow "granularity": granularity }}, 7514da540fSJohn Snow { "type": "block-dirty-bitmap-clear", 7614da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapA" }}, 7714da540fSJohn Snow { "type": "abort", "data": {}} 7814da540fSJohn Snow ]) 7914da540fSJohn Snow log(query_bitmaps(vm), indent=2) 8014da540fSJohn Snow 8114da540fSJohn Snow log('\n--- Disabling B & Adding C ---\n') 8214da540fSJohn Snow vm.qmp_log("transaction", indent=2, actions=[ 8314da540fSJohn Snow { "type": "block-dirty-bitmap-disable", 8414da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapB" }}, 8514da540fSJohn Snow { "type": "block-dirty-bitmap-add", 8614da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapC", 8714da540fSJohn Snow "granularity": granularity }}, 8814da540fSJohn Snow # Purely extraneous, but test that it works: 8914da540fSJohn Snow { "type": "block-dirty-bitmap-disable", 9014da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapC" }}, 9114da540fSJohn Snow { "type": "block-dirty-bitmap-enable", 9214da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapC" }}, 9314da540fSJohn Snow ]) 9414da540fSJohn Snow 9514da540fSJohn Snow log('\n--- Emulating further writes ---\n') 9614da540fSJohn Snow # Dirties 6 clusters, 3 of which are new in contrast to "A". 9714da540fSJohn Snow # A = 64 * 1024 * (4 + 3) = 458752 9814da540fSJohn Snow # C = 64 * 1024 * 6 = 393216 9914da540fSJohn Snow for p in overwrite: 10014da540fSJohn Snow cmd = "write -P%s %s %s" % p 10114da540fSJohn Snow log(cmd) 10214da540fSJohn Snow log(vm.hmp_qemu_io("drive0", cmd)) 10314da540fSJohn Snow 10414da540fSJohn Snow log('\n--- Disabling A & C ---\n') 10514da540fSJohn Snow vm.qmp_log("transaction", indent=2, actions=[ 10614da540fSJohn Snow { "type": "block-dirty-bitmap-disable", 10714da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapA" }}, 10814da540fSJohn Snow { "type": "block-dirty-bitmap-disable", 10914da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapC" }} 11014da540fSJohn Snow ]) 11114da540fSJohn Snow 11214da540fSJohn Snow # A: 7 clusters 11314da540fSJohn Snow # B: 4 clusters 11414da540fSJohn Snow # C: 6 clusters 11514da540fSJohn Snow log(query_bitmaps(vm), indent=2) 11614da540fSJohn Snow 11714da540fSJohn Snow log('\n--- Submitting & Aborting Merge Transaction ---\n') 11814da540fSJohn Snow vm.qmp_log("transaction", indent=2, actions=[ 11914da540fSJohn Snow { "type": "block-dirty-bitmap-add", 12014da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapD", 12114da540fSJohn Snow "disabled": True, "granularity": granularity }}, 12214da540fSJohn Snow { "type": "block-dirty-bitmap-merge", 12314da540fSJohn Snow "data": { "node": "drive0", "target": "bitmapD", 12414da540fSJohn Snow "bitmaps": ["bitmapB", "bitmapC"] }}, 12514da540fSJohn Snow { "type": "abort", "data": {}} 12614da540fSJohn Snow ]) 12714da540fSJohn Snow log(query_bitmaps(vm), indent=2) 12814da540fSJohn Snow 12914da540fSJohn Snow log('\n--- Creating D as a merge of B & C ---\n') 13014da540fSJohn Snow # Good hygiene: create a disabled bitmap as a merge target. 13114da540fSJohn Snow vm.qmp_log("transaction", indent=2, actions=[ 13214da540fSJohn Snow { "type": "block-dirty-bitmap-add", 13314da540fSJohn Snow "data": { "node": "drive0", "name": "bitmapD", 13414da540fSJohn Snow "disabled": True, "granularity": granularity }}, 13514da540fSJohn Snow { "type": "block-dirty-bitmap-merge", 13614da540fSJohn Snow "data": { "node": "drive0", "target": "bitmapD", 13714da540fSJohn Snow "bitmaps": ["bitmapB", "bitmapC"] }} 13814da540fSJohn Snow ]) 13914da540fSJohn Snow 14014da540fSJohn Snow # A and D should now both have 7 clusters apiece. 14114da540fSJohn Snow # B and C remain unchanged with 4 and 6 respectively. 14214da540fSJohn Snow log(query_bitmaps(vm), indent=2) 14314da540fSJohn Snow 14414da540fSJohn Snow # A and D should be equivalent. 14514da540fSJohn Snow # Some formats round the size of the disk, so don't print the checksums. 14614da540fSJohn Snow check_a = vm.qmp('x-debug-block-dirty-bitmap-sha256', 14714da540fSJohn Snow node="drive0", name="bitmapA")['return']['sha256'] 14814da540fSJohn Snow check_d = vm.qmp('x-debug-block-dirty-bitmap-sha256', 14914da540fSJohn Snow node="drive0", name="bitmapD")['return']['sha256'] 15014da540fSJohn Snow assert(check_a == check_d) 15114da540fSJohn Snow 15214da540fSJohn Snow log('\n--- Removing bitmaps A, B, C, and D ---\n') 15314da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapA") 15414da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapB") 15514da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapC") 15614da540fSJohn Snow vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="bitmapD") 15714da540fSJohn Snow 15814da540fSJohn Snow log('\n--- Final Query ---\n') 15914da540fSJohn Snow log(query_bitmaps(vm), indent=2) 16014da540fSJohn Snow 16114da540fSJohn Snow log('\n--- Done ---\n') 16214da540fSJohn Snow vm.shutdown() 163