Philippe Mathieu-Daudé | 7c47752 | 2020-01-30 17:32:30 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Vladimir Sementsov-Ogievskiy | 9dd003a | 2021-01-16 16:44:19 +0300 | [diff] [blame] | 2 | # group: rw |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 3 | # |
| 4 | # Test nbd reconnect |
| 5 | # |
| 6 | # Copyright (c) 2019 Virtuozzo International GmbH. |
| 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 time |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 23 | import os |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 24 | |
| 25 | import iotests |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 26 | from iotests import qemu_img_create, file_path, qemu_nbd_popen |
Vladimir Sementsov-Ogievskiy | ba9c451 | 2019-10-25 17:50:22 +0300 | [diff] [blame] | 27 | |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 28 | disk_a, disk_b, nbd_sock = file_path('disk_a', 'disk_b', 'nbd-sock') |
| 29 | nbd_uri = 'nbd+unix:///?socket=' + nbd_sock |
Vladimir Sementsov-Ogievskiy | 51223cb | 2020-11-18 21:04:28 +0300 | [diff] [blame] | 30 | wait_limit = 3.0 |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 31 | wait_step = 0.2 |
| 32 | |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 33 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 34 | class TestNbdReconnect(iotests.QMPTestCase): |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 35 | def init_vm(self, disk_size): |
| 36 | qemu_img_create('-f', iotests.imgfmt, disk_a, str(disk_size)) |
| 37 | qemu_img_create('-f', iotests.imgfmt, disk_b, str(disk_size)) |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 38 | self.vm = iotests.VM().add_drive(disk_a) |
| 39 | self.vm.launch() |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 40 | self.vm.hmp_qemu_io('drive0', 'write 0 {}'.format(disk_size)) |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 41 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 42 | def tearDown(self): |
| 43 | self.vm.shutdown() |
| 44 | os.remove(disk_a) |
| 45 | os.remove(disk_b) |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 46 | |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 47 | def start_job(self, job): |
| 48 | """Stat job with nbd target and kill the server""" |
| 49 | assert job in ('blockdev-backup', 'blockdev-mirror') |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 50 | with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b): |
| 51 | result = self.vm.qmp('blockdev-add', |
| 52 | **{'node_name': 'backup0', |
| 53 | 'driver': 'raw', |
| 54 | 'file': {'driver': 'nbd', |
| 55 | 'server': {'type': 'unix', |
| 56 | 'path': nbd_sock}, |
| 57 | 'reconnect-delay': 10}}) |
| 58 | self.assert_qmp(result, 'return', {}) |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 59 | result = self.vm.qmp(job, device='drive0', |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 60 | sync='full', target='backup0', |
| 61 | speed=(1 * 1024 * 1024)) |
| 62 | self.assert_qmp(result, 'return', {}) |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 63 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 64 | # Wait for some progress |
| 65 | t = 0.0 |
| 66 | while t < wait_limit: |
| 67 | jobs = self.vm.qmp('query-block-jobs')['return'] |
| 68 | if jobs and jobs[0]['offset'] > 0: |
| 69 | break |
| 70 | time.sleep(wait_step) |
| 71 | t += wait_step |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 72 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 73 | self.assertTrue(jobs and jobs[0]['offset'] > 0) # job started |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 74 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 75 | jobs = self.vm.qmp('query-block-jobs')['return'] |
| 76 | # Check that job is still in progress |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 77 | self.assertTrue(jobs) |
| 78 | self.assertTrue(jobs[0]['offset'] < jobs[0]['len']) |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 79 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 80 | result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) |
| 81 | self.assert_qmp(result, 'return', {}) |
Vladimir Sementsov-Ogievskiy | 23ee0ec | 2019-10-09 11:41:58 +0300 | [diff] [blame] | 82 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 83 | # Emulate server down time for 1 second |
| 84 | time.sleep(1) |
| 85 | |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 86 | def test_backup(self): |
| 87 | size = 5 * 1024 * 1024 |
| 88 | self.init_vm(size) |
| 89 | self.start_job('blockdev-backup') |
| 90 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 91 | with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b): |
| 92 | e = self.vm.event_wait('BLOCK_JOB_COMPLETED') |
| 93 | self.assertEqual(e['data']['offset'], size) |
| 94 | result = self.vm.qmp('blockdev-del', node_name='backup0') |
| 95 | self.assert_qmp(result, 'return', {}) |
| 96 | |
Vladimir Sementsov-Ogievskiy | 594427f | 2021-02-05 19:37:20 +0300 | [diff] [blame] | 97 | def cancel_job(self): |
Vladimir Sementsov-Ogievskiy | 9c785cd | 2021-04-21 10:58:58 +0300 | [diff] [blame] | 98 | result = self.vm.qmp('block-job-cancel', device='drive0', force=True) |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 99 | self.assert_qmp(result, 'return', {}) |
| 100 | |
| 101 | start_t = time.time() |
| 102 | self.vm.event_wait('BLOCK_JOB_CANCELLED') |
| 103 | delta_t = time.time() - start_t |
Thomas Huth | 4076349 | 2022-08-02 14:31:01 +0200 | [diff] [blame] | 104 | self.assertTrue(delta_t < 5.0) |
Vladimir Sementsov-Ogievskiy | d00dd63 | 2021-02-05 19:37:18 +0300 | [diff] [blame] | 105 | |
Vladimir Sementsov-Ogievskiy | 594427f | 2021-02-05 19:37:20 +0300 | [diff] [blame] | 106 | def test_mirror_cancel(self): |
| 107 | # Mirror speed limit doesn't work well enough, it seems that mirror |
| 108 | # will run many parallel requests anyway. MAX_IN_FLIGHT is 16 and |
| 109 | # MAX_IO_BYTES is 1M in mirror.c, so let's use 20M disk. |
| 110 | self.init_vm(20 * 1024 * 1024) |
| 111 | self.start_job('blockdev-mirror') |
| 112 | self.cancel_job() |
| 113 | |
| 114 | def test_backup_cancel(self): |
| 115 | self.init_vm(5 * 1024 * 1024) |
| 116 | self.start_job('blockdev-backup') |
| 117 | self.cancel_job() |
| 118 | |
Vladimir Sementsov-Ogievskiy | 46bd6f8 | 2021-02-05 19:37:16 +0300 | [diff] [blame] | 119 | |
| 120 | if __name__ == '__main__': |
| 121 | iotests.main(supported_fmts=['qcow2']) |