From 6dd64919ea36db9fd7e754ed394c25ced45ea39a Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 6 Dec 2017 14:45:50 +0000 Subject: qemu-iotests: add 202 external snapshots IOThread test QMP 'transaction' blockdev-snapshot-sync with multiple disks in an IOThread is an untested code path. Several bugs have been found in connection with this command. This patch adds a test case to prevent future regressions. Signed-off-by: Stefan Hajnoczi Reviewed-by: Kevin Wolf Reviewed-by: Eric Blake Message-id: 20171206144550.22295-10-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/202 | 95 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/202.out | 11 ++++++ tests/qemu-iotests/group | 1 + 3 files changed, 107 insertions(+) create mode 100755 tests/qemu-iotests/202 create mode 100644 tests/qemu-iotests/202.out (limited to 'tests') diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202 new file mode 100755 index 0000000..581ca34 --- /dev/null +++ b/tests/qemu-iotests/202 @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 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 . +# +# Creator/Owner: Stefan Hajnoczi +# +# Check that QMP 'transaction' blockdev-snapshot-sync with multiple drives on a +# single IOThread completes successfully. This particular command triggered a +# hang due to recursive AioContext locking and BDRV_POLL_WHILE(). Protect +# against regressions. + +import iotests + +iotests.verify_image_format(supported_fmts=['qcow2']) +iotests.verify_platform(['linux']) + +with iotests.FilePath('disk0.img') as disk0_img_path, \ + iotests.FilePath('disk1.img') as disk1_img_path, \ + iotests.FilePath('disk0-snap.img') as disk0_snap_img_path, \ + iotests.FilePath('disk1-snap.img') as disk1_snap_img_path, \ + iotests.VM() as vm: + + img_size = '10M' + iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size) + iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size) + + iotests.log('Launching VM...') + vm.launch() + + iotests.log('Adding IOThread...') + iotests.log(vm.qmp('object-add', + qom_type='iothread', + id='iothread0')) + + iotests.log('Adding blockdevs...') + iotests.log(vm.qmp('blockdev-add', + driver=iotests.imgfmt, + node_name='disk0', + file={ + 'driver': 'file', + 'filename': disk0_img_path, + })) + iotests.log(vm.qmp('blockdev-add', + driver=iotests.imgfmt, + node_name='disk1', + file={ + 'driver': 'file', + 'filename': disk1_img_path, + })) + + iotests.log('Setting iothread...') + iotests.log(vm.qmp('x-blockdev-set-iothread', + node_name='disk0', + iothread='iothread0')) + iotests.log(vm.qmp('x-blockdev-set-iothread', + node_name='disk1', + iothread='iothread0')) + + iotests.log('Creating external snapshots...') + iotests.log(vm.qmp( + 'transaction', + actions=[ + { + 'data': { + 'node-name': 'disk0', + 'snapshot-file': disk0_snap_img_path, + 'snapshot-node-name': 'disk0-snap', + 'mode': 'absolute-paths', + 'format': iotests.imgfmt, + }, + 'type': 'blockdev-snapshot-sync' + }, { + 'data': { + 'node-name': 'disk1', + 'snapshot-file': disk1_snap_img_path, + 'snapshot-node-name': 'disk1-snap', + 'mode': 'absolute-paths', + 'format': iotests.imgfmt + }, + 'type': 'blockdev-snapshot-sync' + } + ])) diff --git a/tests/qemu-iotests/202.out b/tests/qemu-iotests/202.out new file mode 100644 index 0000000..d5ea374 --- /dev/null +++ b/tests/qemu-iotests/202.out @@ -0,0 +1,11 @@ +Launching VM... +Adding IOThread... +{u'return': {}} +Adding blockdevs... +{u'return': {}} +{u'return': {}} +Setting iothread... +{u'return': {}} +{u'return': {}} +Creating external snapshots... +{u'return': {}} diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 3e68867..d0ee1e2 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -197,3 +197,4 @@ 197 rw auto quick 198 rw auto 200 rw auto +202 rw auto quick -- cgit v1.1 From ccc15f7dafff63cbcc3f6a7c51e380025d67f7f4 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 7 Dec 2017 20:13:18 +0000 Subject: iotests: add VM.add_object() The VM.add_object() method can be used to add IOThreads or memory backend objects. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake Message-id: 20171207201320.19284-5-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/iotests.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests') diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 6f05790..44477e9 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -197,6 +197,11 @@ class VM(qtest.QEMUQtestMachine): socket_scm_helper=socket_scm_helper) self._num_drives = 0 + def add_object(self, opts): + self._args.append('-object') + self._args.append(opts) + return self + def add_device(self, opts): self._args.append('-device') self._args.append(opts) -- cgit v1.1 From 7a9dda0d7f9831c2432620dcfefdadbb7ae888dc Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Thu, 7 Dec 2017 20:13:20 +0000 Subject: qemu-iotests: add 203 savevm with IOThreads test This test case will prevent future regressions with savevm and IOThreads. Signed-off-by: Stefan Hajnoczi Reviewed-by: Eric Blake Message-id: 20171207201320.19284-7-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi --- tests/qemu-iotests/203 | 59 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/203.out | 6 +++++ tests/qemu-iotests/group | 1 + 3 files changed, 66 insertions(+) create mode 100755 tests/qemu-iotests/203 create mode 100644 tests/qemu-iotests/203.out (limited to 'tests') diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203 new file mode 100755 index 0000000..2c81191 --- /dev/null +++ b/tests/qemu-iotests/203 @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 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 . +# +# Creator/Owner: Stefan Hajnoczi +# +# Check that QMP 'migrate' with multiple drives on a single IOThread completes +# successfully. This particular command triggered a hang in the source QEMU +# process due to recursive AioContext locking in bdrv_invalidate_all() and +# BDRV_POLL_WHILE(). + +import iotests + +iotests.verify_image_format(supported_fmts=['qcow2']) +iotests.verify_platform(['linux']) + +with iotests.FilePath('disk0.img') as disk0_img_path, \ + iotests.FilePath('disk1.img') as disk1_img_path, \ + iotests.VM() as vm: + + img_size = '10M' + iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk0_img_path, img_size) + iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk1_img_path, img_size) + + iotests.log('Launching VM...') + (vm.add_object('iothread,id=iothread0') + .add_drive(disk0_img_path, 'node-name=drive0-node', interface='none') + .add_drive(disk1_img_path, 'node-name=drive1-node', interface='none') + .launch()) + + iotests.log('Setting IOThreads...') + iotests.log(vm.qmp('x-blockdev-set-iothread', + node_name='drive0-node', iothread='iothread0', + force=True)) + iotests.log(vm.qmp('x-blockdev-set-iothread', + node_name='drive1-node', iothread='iothread0', + force=True)) + + iotests.log('Starting migration...') + iotests.log(vm.qmp('migrate', uri='exec:cat >/dev/null')) + while True: + vm.get_qmp_event(wait=60.0) + result = vm.qmp('query-migrate') + status = result.get('return', {}).get('status', None) + if status == 'completed': + break diff --git a/tests/qemu-iotests/203.out b/tests/qemu-iotests/203.out new file mode 100644 index 0000000..3f1ff90 --- /dev/null +++ b/tests/qemu-iotests/203.out @@ -0,0 +1,6 @@ +Launching VM... +Setting IOThreads... +{u'return': {}} +{u'return': {}} +Starting migration... +{u'return': {}} diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index d0ee1e2..93d96fb 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -198,3 +198,4 @@ 198 rw auto 200 rw auto 202 rw auto quick +203 rw auto -- cgit v1.1