| #!/usr/bin/env python3 | 
 | # group: rw quick | 
 | # | 
 | # Test persistent bitmap resizing. | 
 | # | 
 | # Copyright (c) 2019 John Snow for Red Hat, Inc. | 
 | # | 
 | # 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/>. | 
 | # | 
 | # owner=jsnow@redhat.com | 
 |  | 
 | import iotests | 
 | from iotests import log | 
 |  | 
 | iotests.script_initialize(supported_fmts=['qcow2'], | 
 |                           unsupported_imgopts=['compat']) | 
 | size = 64 * 1024 * 1024 * 1024 | 
 | gran_small = 32 * 1024 | 
 | gran_large = 128 * 1024 | 
 |  | 
 | def query_bitmaps(vm): | 
 |     res = vm.qmp("query-block") | 
 |     return { "bitmaps": { device['device']: device.get('inserted', {}) | 
 |                           .get('dirty-bitmaps', []) for | 
 |                           device in res['return'] } } | 
 |  | 
 | with iotests.FilePath('img') as img_path, \ | 
 |      iotests.VM() as vm: | 
 |  | 
 |     log('--- Preparing image & VM ---\n') | 
 |     iotests.qemu_img_create('-f', iotests.imgfmt, img_path, str(size)) | 
 |     vm.add_drive(img_path) | 
 |  | 
 |  | 
 |     log('--- 1st Boot (Establish Baseline Image) ---\n') | 
 |     vm.launch() | 
 |  | 
 |     log('\n--- Adding bitmaps Small, Medium, Large, and Transient ---\n') | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="Small", granularity=gran_small, persistent=True) | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="Medium", persistent=True) | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="Large", granularity=gran_large, persistent=True) | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="Transient", persistent=False) | 
 |  | 
 |     log('--- Forcing flush of bitmaps to disk ---\n') | 
 |     log(query_bitmaps(vm), indent=2) | 
 |     vm.shutdown() | 
 |  | 
 |  | 
 |     log('--- 2nd Boot (Grow Image) ---\n') | 
 |     vm.launch() | 
 |     log(query_bitmaps(vm), indent=2) | 
 |  | 
 |     log('--- Adding new bitmap, growing image, and adding 2nd new bitmap ---') | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="New", persistent=True) | 
 |     vm.qmp_log("human-monitor-command", | 
 |                command_line="block_resize drive0 70G") | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="Newtwo", persistent=True) | 
 |     log(query_bitmaps(vm), indent=2) | 
 |  | 
 |     log('--- Forcing flush of bitmaps to disk ---\n') | 
 |     vm.shutdown() | 
 |  | 
 |  | 
 |     log('--- 3rd Boot (Shrink Image) ---\n') | 
 |     vm.launch() | 
 |     log(query_bitmaps(vm), indent=2) | 
 |  | 
 |     log('--- Adding "NewB" bitmap, removing "New" bitmap ---') | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="NewB", persistent=True) | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", | 
 |                name="New") | 
 |  | 
 |     log('--- Truncating image ---\n') | 
 |     vm.qmp_log("human-monitor-command", | 
 |                command_line="block_resize drive0 50G") | 
 |  | 
 |     log('--- Adding "NewC" bitmap, removing "NewTwo" bitmap ---') | 
 |     vm.qmp_log("block-dirty-bitmap-add", node="drive0", | 
 |                name="NewC", persistent=True) | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Newtwo") | 
 |  | 
 |     log('--- Forcing flush of bitmaps to disk ---\n') | 
 |     vm.shutdown() | 
 |  | 
 |  | 
 |     log('--- 4th Boot (Verification and Cleanup) ---\n') | 
 |     vm.launch() | 
 |     log(query_bitmaps(vm), indent=2) | 
 |  | 
 |     log('--- Removing all Bitmaps ---\n') | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Small") | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Medium") | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="Large") | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="NewB") | 
 |     vm.qmp_log("block-dirty-bitmap-remove", node="drive0", name="NewC") | 
 |     log(query_bitmaps(vm), indent=2) | 
 |  | 
 |     log('\n--- Done ---') | 
 |     vm.shutdown() |