1#!/usr/bin/env python 2# 3# Tests for dirty bitmaps postcopy migration. 4# 5# Copyright (c) 2016-2017 Virtuozzo International GmbH. All rights reserved. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20 21import os 22import iotests 23import time 24from iotests import qemu_img 25 26disk_a = os.path.join(iotests.test_dir, 'disk_a') 27disk_b = os.path.join(iotests.test_dir, 'disk_b') 28size = '256G' 29fifo = os.path.join(iotests.test_dir, 'mig_fifo') 30 31class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): 32 33 def tearDown(self): 34 self.vm_a.shutdown() 35 self.vm_b.shutdown() 36 os.remove(disk_a) 37 os.remove(disk_b) 38 os.remove(fifo) 39 40 def setUp(self): 41 os.mkfifo(fifo) 42 qemu_img('create', '-f', iotests.imgfmt, disk_a, size) 43 qemu_img('create', '-f', iotests.imgfmt, disk_b, size) 44 self.vm_a = iotests.VM(path_suffix='a').add_drive(disk_a) 45 self.vm_b = iotests.VM(path_suffix='b').add_drive(disk_b) 46 self.vm_b.add_incoming("exec: cat '" + fifo + "'") 47 self.vm_a.launch() 48 self.vm_b.launch() 49 50 def test_postcopy(self): 51 write_size = 0x40000000 52 granularity = 512 53 chunk = 4096 54 55 result = self.vm_a.qmp('block-dirty-bitmap-add', node='drive0', 56 name='bitmap', granularity=granularity) 57 self.assert_qmp(result, 'return', {}); 58 59 s = 0 60 while s < write_size: 61 self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) 62 s += 0x10000 63 s = 0x8000 64 while s < write_size: 65 self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) 66 s += 0x10000 67 68 result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256', 69 node='drive0', name='bitmap') 70 sha256 = result['return']['sha256'] 71 72 result = self.vm_a.qmp('block-dirty-bitmap-clear', node='drive0', 73 name='bitmap') 74 self.assert_qmp(result, 'return', {}); 75 s = 0 76 while s < write_size: 77 self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) 78 s += 0x10000 79 80 bitmaps_cap = {'capability': 'dirty-bitmaps', 'state': True} 81 events_cap = {'capability': 'events', 'state': True} 82 83 result = self.vm_a.qmp('migrate-set-capabilities', 84 capabilities=[bitmaps_cap, events_cap]) 85 self.assert_qmp(result, 'return', {}) 86 87 result = self.vm_b.qmp('migrate-set-capabilities', 88 capabilities=[bitmaps_cap]) 89 self.assert_qmp(result, 'return', {}) 90 91 result = self.vm_a.qmp('migrate', uri='exec:cat>' + fifo) 92 self.assert_qmp(result, 'return', {}) 93 94 result = self.vm_a.qmp('migrate-start-postcopy') 95 self.assert_qmp(result, 'return', {}) 96 97 while True: 98 event = self.vm_a.event_wait('MIGRATION') 99 if event['data']['status'] == 'completed': 100 break 101 102 s = 0x8000 103 while s < write_size: 104 self.vm_b.hmp_qemu_io('drive0', 'write %d %d' % (s, chunk)) 105 s += 0x10000 106 107 result = self.vm_b.qmp('query-block'); 108 while len(result['return'][0]['dirty-bitmaps']) > 1: 109 time.sleep(2) 110 result = self.vm_b.qmp('query-block'); 111 112 result = self.vm_b.qmp('x-debug-block-dirty-bitmap-sha256', 113 node='drive0', name='bitmap') 114 115 self.assert_qmp(result, 'return/sha256', sha256); 116 117if __name__ == '__main__': 118 iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'], 119 supported_protocols=['file']) 120