165 (4640B)
1 #!/usr/bin/env python3 2 # group: rw quick 3 # 4 # Tests for persistent dirty bitmaps. 5 # 6 # Copyright: Vladimir Sementsov-Ogievskiy 2015-2017 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 22 import os 23 import re 24 import iotests 25 from iotests import qemu_img 26 27 disk = os.path.join(iotests.test_dir, 'disk') 28 disk_size = 0x40000000 # 1G 29 30 # regions for qemu_io: (start, count) in bytes 31 regions1 = ((0x0fff00, 0x10000), 32 (0x200000, 0x100000)) 33 34 regions2 = ((0x10000000, 0x20000), 35 (0x3fff0000, 0x10000)) 36 37 class TestPersistentDirtyBitmap(iotests.QMPTestCase): 38 39 def setUp(self): 40 qemu_img('create', '-f', iotests.imgfmt, disk, str(disk_size)) 41 42 def tearDown(self): 43 os.remove(disk) 44 45 def mkVm(self): 46 return iotests.VM().add_drive(disk, opts='node-name=node0') 47 48 def mkVmRo(self): 49 return iotests.VM().add_drive(disk, opts='readonly=on,node-name=node0') 50 51 def getSha256(self): 52 result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', 53 node='drive0', name='bitmap0') 54 return result['return']['sha256'] 55 56 def checkBitmap(self, sha256): 57 result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', 58 node='drive0', name='bitmap0') 59 self.assert_qmp(result, 'return/sha256', sha256); 60 61 def writeRegions(self, regions): 62 for r in regions: 63 self.vm.hmp_qemu_io('drive0', 64 'write %d %d' % r) 65 66 def qmpAddBitmap(self): 67 self.vm.qmp('block-dirty-bitmap-add', node='drive0', 68 name='bitmap0', persistent=True) 69 70 def test_persistent(self): 71 self.vm = self.mkVm() 72 self.vm.launch() 73 self.qmpAddBitmap() 74 75 self.writeRegions(regions1) 76 sha256 = self.getSha256() 77 78 self.vm.shutdown() 79 80 self.vm = self.mkVmRo() 81 self.vm.launch() 82 self.vm.shutdown() 83 84 #catch 'Persistent bitmaps are lost' possible error 85 log = self.vm.get_log() 86 log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) 87 log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) 88 if log: 89 print(log) 90 91 self.vm = self.mkVm() 92 self.vm.launch() 93 94 self.checkBitmap(sha256) 95 self.writeRegions(regions2) 96 sha256 = self.getSha256() 97 98 self.vm.shutdown() 99 self.vm.launch() 100 101 self.checkBitmap(sha256) 102 103 self.vm.shutdown() 104 105 def test_reopen_rw(self): 106 self.vm = self.mkVm() 107 self.vm.launch() 108 self.qmpAddBitmap() 109 110 # Calculate hashes 111 112 self.writeRegions(regions1) 113 sha256_1 = self.getSha256() 114 115 self.writeRegions(regions2) 116 sha256_2 = self.getSha256() 117 assert sha256_1 != sha256_2 # Otherwise, it's not very interesting. 118 119 result = self.vm.qmp('block-dirty-bitmap-clear', node='drive0', 120 name='bitmap0') 121 self.assert_qmp(result, 'return', {}) 122 123 # Start with regions1 124 125 self.writeRegions(regions1) 126 assert sha256_1 == self.getSha256() 127 128 self.vm.shutdown() 129 130 self.vm = self.mkVmRo() 131 self.vm.launch() 132 133 assert sha256_1 == self.getSha256() 134 135 # Check that we are in RO mode and can't modify bitmap. 136 self.writeRegions(regions2) 137 assert sha256_1 == self.getSha256() 138 139 # Reopen to RW 140 result = self.vm.qmp('blockdev-reopen', options=[{ 141 'node-name': 'node0', 142 'driver': iotests.imgfmt, 143 'file': { 144 'driver': 'file', 145 'filename': disk 146 }, 147 'read-only': False 148 }]) 149 self.assert_qmp(result, 'return', {}) 150 151 # Check that bitmap is reopened to RW and we can write to it. 152 self.writeRegions(regions2) 153 assert sha256_2 == self.getSha256() 154 155 self.vm.shutdown() 156 157 158 if __name__ == '__main__': 159 iotests.main(supported_fmts=['qcow2'], 160 supported_protocols=['file'], 161 unsupported_imgopts=['compat'])