1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3 29dd003a9SVladimir Sementsov-Ogievskiy# group: rw quick 3fc905d3aSVladimir Sementsov-Ogievskiy# 4fc905d3aSVladimir Sementsov-Ogievskiy# Tests for persistent dirty bitmaps. 5fc905d3aSVladimir Sementsov-Ogievskiy# 6fc905d3aSVladimir Sementsov-Ogievskiy# Copyright: Vladimir Sementsov-Ogievskiy 2015-2017 7fc905d3aSVladimir Sementsov-Ogievskiy# 8fc905d3aSVladimir Sementsov-Ogievskiy# This program is free software; you can redistribute it and/or modify 9fc905d3aSVladimir Sementsov-Ogievskiy# it under the terms of the GNU General Public License as published by 10fc905d3aSVladimir Sementsov-Ogievskiy# the Free Software Foundation; either version 2 of the License, or 11fc905d3aSVladimir Sementsov-Ogievskiy# (at your option) any later version. 12fc905d3aSVladimir Sementsov-Ogievskiy# 13fc905d3aSVladimir Sementsov-Ogievskiy# This program is distributed in the hope that it will be useful, 14fc905d3aSVladimir Sementsov-Ogievskiy# but WITHOUT ANY WARRANTY; without even the implied warranty of 15fc905d3aSVladimir Sementsov-Ogievskiy# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16fc905d3aSVladimir Sementsov-Ogievskiy# GNU General Public License for more details. 17fc905d3aSVladimir Sementsov-Ogievskiy# 18fc905d3aSVladimir Sementsov-Ogievskiy# You should have received a copy of the GNU General Public License 19fc905d3aSVladimir Sementsov-Ogievskiy# along with this program. If not, see <http://www.gnu.org/licenses/>. 20fc905d3aSVladimir Sementsov-Ogievskiy# 21fc905d3aSVladimir Sementsov-Ogievskiy 22fc905d3aSVladimir Sementsov-Ogievskiyimport os 23fc905d3aSVladimir Sementsov-Ogievskiyimport re 24fc905d3aSVladimir Sementsov-Ogievskiyimport iotests 25fc905d3aSVladimir Sementsov-Ogievskiyfrom iotests import qemu_img 26fc905d3aSVladimir Sementsov-Ogievskiy 27fc905d3aSVladimir Sementsov-Ogievskiydisk = os.path.join(iotests.test_dir, 'disk') 28fc905d3aSVladimir Sementsov-Ogievskiydisk_size = 0x40000000 # 1G 29fc905d3aSVladimir Sementsov-Ogievskiy 30fc905d3aSVladimir Sementsov-Ogievskiy# regions for qemu_io: (start, count) in bytes 3149d741b5SEric Blakeregions1 = ((0x0fff00, 0x10000), 32fc905d3aSVladimir Sementsov-Ogievskiy (0x200000, 0x100000)) 33fc905d3aSVladimir Sementsov-Ogievskiy 34fc905d3aSVladimir Sementsov-Ogievskiyregions2 = ((0x10000000, 0x20000), 35fc905d3aSVladimir Sementsov-Ogievskiy (0x3fff0000, 0x10000)) 36fc905d3aSVladimir Sementsov-Ogievskiy 37fc905d3aSVladimir Sementsov-Ogievskiyclass TestPersistentDirtyBitmap(iotests.QMPTestCase): 38fc905d3aSVladimir Sementsov-Ogievskiy 39fc905d3aSVladimir Sementsov-Ogievskiy def setUp(self): 40fc905d3aSVladimir Sementsov-Ogievskiy qemu_img('create', '-f', iotests.imgfmt, disk, str(disk_size)) 41fc905d3aSVladimir Sementsov-Ogievskiy 42fc905d3aSVladimir Sementsov-Ogievskiy def tearDown(self): 43fc905d3aSVladimir Sementsov-Ogievskiy os.remove(disk) 44fc905d3aSVladimir Sementsov-Ogievskiy 45fc905d3aSVladimir Sementsov-Ogievskiy def mkVm(self): 465752f89aSVladimir Sementsov-Ogievskiy return iotests.VM().add_drive(disk, opts='node-name=node0') 47fc905d3aSVladimir Sementsov-Ogievskiy 48fc905d3aSVladimir Sementsov-Ogievskiy def mkVmRo(self): 495752f89aSVladimir Sementsov-Ogievskiy return iotests.VM().add_drive(disk, opts='readonly=on,node-name=node0') 50fc905d3aSVladimir Sementsov-Ogievskiy 51fc905d3aSVladimir Sementsov-Ogievskiy def getSha256(self): 52fc905d3aSVladimir Sementsov-Ogievskiy result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', 53fc905d3aSVladimir Sementsov-Ogievskiy node='drive0', name='bitmap0') 54fc905d3aSVladimir Sementsov-Ogievskiy return result['return']['sha256'] 55fc905d3aSVladimir Sementsov-Ogievskiy 56fc905d3aSVladimir Sementsov-Ogievskiy def checkBitmap(self, sha256): 57fc905d3aSVladimir Sementsov-Ogievskiy result = self.vm.qmp('x-debug-block-dirty-bitmap-sha256', 58fc905d3aSVladimir Sementsov-Ogievskiy node='drive0', name='bitmap0') 59fc905d3aSVladimir Sementsov-Ogievskiy self.assert_qmp(result, 'return/sha256', sha256); 60fc905d3aSVladimir Sementsov-Ogievskiy 61fc905d3aSVladimir Sementsov-Ogievskiy def writeRegions(self, regions): 62fc905d3aSVladimir Sementsov-Ogievskiy for r in regions: 63fc905d3aSVladimir Sementsov-Ogievskiy self.vm.hmp_qemu_io('drive0', 64fc905d3aSVladimir Sementsov-Ogievskiy 'write %d %d' % r) 65fc905d3aSVladimir Sementsov-Ogievskiy 66fc905d3aSVladimir Sementsov-Ogievskiy def qmpAddBitmap(self): 67fc905d3aSVladimir Sementsov-Ogievskiy self.vm.qmp('block-dirty-bitmap-add', node='drive0', 683e99da5eSVladimir Sementsov-Ogievskiy name='bitmap0', persistent=True) 69fc905d3aSVladimir Sementsov-Ogievskiy 70fc905d3aSVladimir Sementsov-Ogievskiy def test_persistent(self): 71fc905d3aSVladimir Sementsov-Ogievskiy self.vm = self.mkVm() 72fc905d3aSVladimir Sementsov-Ogievskiy self.vm.launch() 73fc905d3aSVladimir Sementsov-Ogievskiy self.qmpAddBitmap() 74fc905d3aSVladimir Sementsov-Ogievskiy 75fc905d3aSVladimir Sementsov-Ogievskiy self.writeRegions(regions1) 76fc905d3aSVladimir Sementsov-Ogievskiy sha256 = self.getSha256() 77fc905d3aSVladimir Sementsov-Ogievskiy 78fc905d3aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 79fc905d3aSVladimir Sementsov-Ogievskiy 80fc905d3aSVladimir Sementsov-Ogievskiy self.vm = self.mkVmRo() 81fc905d3aSVladimir Sementsov-Ogievskiy self.vm.launch() 82fc905d3aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 83fc905d3aSVladimir Sementsov-Ogievskiy 84fc905d3aSVladimir Sementsov-Ogievskiy #catch 'Persistent bitmaps are lost' possible error 85fc905d3aSVladimir Sementsov-Ogievskiy log = self.vm.get_log() 86fc905d3aSVladimir Sementsov-Ogievskiy log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) 87fc905d3aSVladimir Sementsov-Ogievskiy log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) 88fc905d3aSVladimir Sementsov-Ogievskiy if log: 89f03868bdSEduardo Habkost print(log) 90fc905d3aSVladimir Sementsov-Ogievskiy 91fc905d3aSVladimir Sementsov-Ogievskiy self.vm = self.mkVm() 92fc905d3aSVladimir Sementsov-Ogievskiy self.vm.launch() 93fc905d3aSVladimir Sementsov-Ogievskiy 94fc905d3aSVladimir Sementsov-Ogievskiy self.checkBitmap(sha256) 95fc905d3aSVladimir Sementsov-Ogievskiy self.writeRegions(regions2) 96fc905d3aSVladimir Sementsov-Ogievskiy sha256 = self.getSha256() 97fc905d3aSVladimir Sementsov-Ogievskiy 98fc905d3aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 99fc905d3aSVladimir Sementsov-Ogievskiy self.vm.launch() 100fc905d3aSVladimir Sementsov-Ogievskiy 101fc905d3aSVladimir Sementsov-Ogievskiy self.checkBitmap(sha256) 102fc905d3aSVladimir Sementsov-Ogievskiy 103fc905d3aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 104fc905d3aSVladimir Sementsov-Ogievskiy 1055752f89aSVladimir Sementsov-Ogievskiy def test_reopen_rw(self): 1065752f89aSVladimir Sementsov-Ogievskiy self.vm = self.mkVm() 1075752f89aSVladimir Sementsov-Ogievskiy self.vm.launch() 1085752f89aSVladimir Sementsov-Ogievskiy self.qmpAddBitmap() 1095752f89aSVladimir Sementsov-Ogievskiy 1105752f89aSVladimir Sementsov-Ogievskiy # Calculate hashes 1115752f89aSVladimir Sementsov-Ogievskiy 1125752f89aSVladimir Sementsov-Ogievskiy self.writeRegions(regions1) 1135752f89aSVladimir Sementsov-Ogievskiy sha256_1 = self.getSha256() 1145752f89aSVladimir Sementsov-Ogievskiy 1155752f89aSVladimir Sementsov-Ogievskiy self.writeRegions(regions2) 1165752f89aSVladimir Sementsov-Ogievskiy sha256_2 = self.getSha256() 1175752f89aSVladimir Sementsov-Ogievskiy assert sha256_1 != sha256_2 # Otherwise, it's not very interesting. 1185752f89aSVladimir Sementsov-Ogievskiy 119*b6aed193SVladimir Sementsov-Ogievskiy self.vm.cmd('block-dirty-bitmap-clear', node='drive0', 1205752f89aSVladimir Sementsov-Ogievskiy name='bitmap0') 1215752f89aSVladimir Sementsov-Ogievskiy 1225752f89aSVladimir Sementsov-Ogievskiy # Start with regions1 1235752f89aSVladimir Sementsov-Ogievskiy 1245752f89aSVladimir Sementsov-Ogievskiy self.writeRegions(regions1) 1255752f89aSVladimir Sementsov-Ogievskiy assert sha256_1 == self.getSha256() 1265752f89aSVladimir Sementsov-Ogievskiy 1275752f89aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 1285752f89aSVladimir Sementsov-Ogievskiy 1295752f89aSVladimir Sementsov-Ogievskiy self.vm = self.mkVmRo() 1305752f89aSVladimir Sementsov-Ogievskiy self.vm.launch() 1315752f89aSVladimir Sementsov-Ogievskiy 1325752f89aSVladimir Sementsov-Ogievskiy assert sha256_1 == self.getSha256() 1335752f89aSVladimir Sementsov-Ogievskiy 1345752f89aSVladimir Sementsov-Ogievskiy # Check that we are in RO mode and can't modify bitmap. 1355752f89aSVladimir Sementsov-Ogievskiy self.writeRegions(regions2) 1365752f89aSVladimir Sementsov-Ogievskiy assert sha256_1 == self.getSha256() 1375752f89aSVladimir Sementsov-Ogievskiy 1385752f89aSVladimir Sementsov-Ogievskiy # Reopen to RW 139*b6aed193SVladimir Sementsov-Ogievskiy self.vm.cmd('blockdev-reopen', options=[{ 1405752f89aSVladimir Sementsov-Ogievskiy 'node-name': 'node0', 1415752f89aSVladimir Sementsov-Ogievskiy 'driver': iotests.imgfmt, 1425752f89aSVladimir Sementsov-Ogievskiy 'file': { 1435752f89aSVladimir Sementsov-Ogievskiy 'driver': 'file', 1445752f89aSVladimir Sementsov-Ogievskiy 'filename': disk 1455752f89aSVladimir Sementsov-Ogievskiy }, 1465752f89aSVladimir Sementsov-Ogievskiy 'read-only': False 1473908b7a8SAlberto Garcia }]) 1485752f89aSVladimir Sementsov-Ogievskiy 1495752f89aSVladimir Sementsov-Ogievskiy # Check that bitmap is reopened to RW and we can write to it. 1505752f89aSVladimir Sementsov-Ogievskiy self.writeRegions(regions2) 1515752f89aSVladimir Sementsov-Ogievskiy assert sha256_2 == self.getSha256() 1525752f89aSVladimir Sementsov-Ogievskiy 1535752f89aSVladimir Sementsov-Ogievskiy self.vm.shutdown() 1545752f89aSVladimir Sementsov-Ogievskiy 1555752f89aSVladimir Sementsov-Ogievskiy 156fc905d3aSVladimir Sementsov-Ogievskiyif __name__ == '__main__': 157103cbc77SMax Reitz iotests.main(supported_fmts=['qcow2'], 158b30b8077SVladimir Sementsov-Ogievskiy supported_protocols=['file'], 159b30b8077SVladimir Sementsov-Ogievskiy unsupported_imgopts=['compat']) 160