Commit 8bdee9f1 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

iotests: Test mirror with temporarily disabled target backing file



The newly tested scenario is a common live storage migration scenario:
The target node is opened without a backing file so that the active
layer is mirrored while its backing chain can be copied in the
background.

The backing chain should be attached to the mirror target node when
finalising the job, just before switching the users of the source node
to the new copy (at which point the mirror job still has a reference to
the node). drive-mirror did this automatically, but with blockdev-mirror
this is the job of the QMP client.

This patch adds test cases for two ways to achieve the desired result,
using either x-blockdev-reopen or blockdev-snapshot.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Message-Id: <20200310113831.27293-5-kwolf@redhat.com>
Reviewed-by: default avatarPeter Krempa <pkrempa@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent b31b5321
Loading
Loading
Loading
Loading
+51 −5
Original line number Diff line number Diff line
@@ -45,10 +45,15 @@ target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt)
#                      image during runtime, only makes sense if
#                      target_blockdev_backing is not None
#                      (None: same as target_backing)
# target_open_with_backing: If True, the target image is added with its backing
#                           chain opened right away. If False, blockdev-add
#                           opens it without a backing file and job completion
#                           is supposed to open the backing chain.

class BaseClass(iotests.QMPTestCase):
    target_blockdev_backing = None
    target_real_backing = None
    target_open_with_backing = True

    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, back0_img, '1440K')
@@ -80,8 +85,12 @@ class BaseClass(iotests.QMPTestCase):
                options = { 'node-name': 'target',
                            'driver': iotests.imgfmt,
                            'file': { 'driver': 'file',
                                      'node-name': 'target-file',
                                      'filename': target_img } }
                if self.target_blockdev_backing:

                if not self.target_open_with_backing:
                        options['backing'] = None
                elif self.target_blockdev_backing:
                        options['backing'] = self.target_blockdev_backing

                result = self.vm.qmp('blockdev-add', **options)
@@ -147,10 +156,14 @@ class BaseClass(iotests.QMPTestCase):
# cmd: Mirroring command to execute, either drive-mirror or blockdev-mirror

class MirrorBaseClass(BaseClass):
    def openBacking(self):
        pass

    def runMirror(self, sync):
        if self.cmd == 'blockdev-mirror':
            result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source',
                                 sync=sync, target='target')
                                 sync=sync, target='target',
                                 auto_finalize=False)
        else:
            if self.existing:
                mode = 'existing'
@@ -159,11 +172,12 @@ class MirrorBaseClass(BaseClass):
            result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source',
                                 sync=sync, target=target_img,
                                 format=iotests.imgfmt, mode=mode,
                                 node_name='target')
                                 node_name='target', auto_finalize=False)

        self.assert_qmp(result, 'return', {})

        self.complete_and_wait('mirror-job')
        self.vm.run_job('mirror-job', use_log=False, auto_finalize=False,
                        pre_finalize=self.openBacking, auto_dismiss=True)

    def testFull(self):
        self.runMirror('full')
@@ -221,6 +235,38 @@ class TestBlockdevMirrorForcedBacking(MirrorBaseClass):
    target_blockdev_backing = { 'driver': 'null-co' }
    target_real_backing = 'null-co://'

# Attach the backing chain only during completion, with blockdev-reopen
class TestBlockdevMirrorReopen(MirrorBaseClass):
    cmd = 'blockdev-mirror'
    existing = True
    target_backing = 'null-co://'
    target_open_with_backing = False

    def openBacking(self):
        if not self.target_open_with_backing:
            result = self.vm.qmp('blockdev-add', node_name="backing",
                                 driver="null-co")
            self.assert_qmp(result, 'return', {})
            result = self.vm.qmp('x-blockdev-reopen', node_name="target",
                                 driver=iotests.imgfmt, file="target-file",
                                 backing="backing")
            self.assert_qmp(result, 'return', {})

# Attach the backing chain only during completion, with blockdev-snapshot
class TestBlockdevMirrorSnapshot(MirrorBaseClass):
    cmd = 'blockdev-mirror'
    existing = True
    target_backing = 'null-co://'
    target_open_with_backing = False

    def openBacking(self):
        if not self.target_open_with_backing:
            result = self.vm.qmp('blockdev-add', node_name="backing",
                                 driver="null-co")
            self.assert_qmp(result, 'return', {})
            result = self.vm.qmp('blockdev-snapshot', node="backing",
                                 overlay="target")
            self.assert_qmp(result, 'return', {})

class TestCommit(BaseClass):
    existing = False
+2 −2
Original line number Diff line number Diff line
...................
.........................
----------------------------------------------------------------------
Ran 19 tests
Ran 25 tests

OK