1#!/usr/bin/env python3 2# group: rw quick 3# 4# Test persistent bitmap resizing. 5# 6# Copyright (c) 2019 John Snow for Red Hat, Inc. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program. If not, see <http://www.gnu.org/licenses/>. 20# 21# owner=jsnow@redhat.com 22 23import iotests 24from iotests import log 25 26iotests.script_initialize(supported_fmts=['qcow2']) 27size = 64 * 1024 * 1024 * 1024 28gran_small = 32 * 1024 29gran_large = 128 * 1024 30 31def query_bitmaps(vm): 32 res = vm.qmp("query-block") 33 return { "bitmaps": { device['device']: device.get('dirty-bitmaps', []) for 34 device in res['return'] } } 35 36with iotests.FilePath('img') as img_path, \ 37 iotests.VM() as vm: 38 39 log('--- Preparing image & VM ---\n') 40 iotests.qemu_img_create('-f', iotests.imgfmt, img_path, str(size)) 41 vm.add_drive(img_path) 42 43 44 log('--- 1st Boot (Establish Baseline Image) ---\n') 45 vm.launch() 46 47 log('\n--- Adding bitmaps Small, Medium, Large, and Transient ---\n') 48 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 49 name="Small", granularity=gran_small, persistent=True) 50 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 51 name="Medium", persistent=True) 52 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 53 name="Large", granularity=gran_large, persistent=True) 54 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 55 name="Transient", persistent=False) 56 57 log('--- Forcing flush of bitmaps to disk ---\n') 58 log(query_bitmaps(vm), indent=2) 59 vm.shutdown() 60 61 62 log('--- 2nd Boot (Grow Image) ---\n') 63 vm.launch() 64 log(query_bitmaps(vm), indent=2) 65 66 log('--- Adding new bitmap, growing image, and adding 2nd new bitmap ---') 67 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 68 name="New", persistent=True) 69 vm.qmp_log("human-monitor-command", 70 command_line="block_resize drive0 70G") 71 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 72 name="Newtwo", persistent=True) 73 log(query_bitmaps(vm), indent=2) 74 75 log('--- Forcing flush of bitmaps to disk ---\n') 76 vm.shutdown() 77 78 79 log('--- 3rd Boot (Shrink Image) ---\n') 80 vm.launch() 81 log(query_bitmaps(vm), indent=2) 82 83 log('--- Adding "NewB" bitmap, removing "New" bitmap ---') 84 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 85 name="NewB", persistent=True) 86 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", 87 name="New") 88 89 log('--- Truncating image ---\n') 90 vm.qmp_log("human-monitor-command", 91 command_line="block_resize drive0 50G") 92 93 log('--- Adding "NewC" bitmap, removing "NewTwo" bitmap ---') 94 vm.qmp_log("block-dirty-bitmap-add", node="drive0", 95 name="NewC", persistent=True) 96 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Newtwo") 97 98 log('--- Forcing flush of bitmaps to disk ---\n') 99 vm.shutdown() 100 101 102 log('--- 4th Boot (Verification and Cleanup) ---\n') 103 vm.launch() 104 log(query_bitmaps(vm), indent=2) 105 106 log('--- Removing all Bitmaps ---\n') 107 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Small") 108 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Medium") 109 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Large") 110 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="NewB") 111 vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="NewC") 112 log(query_bitmaps(vm), indent=2) 113 114 log('\n--- Done ---') 115 vm.shutdown() 116