qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Fam Zheng <famz@redhat.com>
Cc: qemu-block@nongnu.org, qemu-devel@nongnu.org,
	Kevin Wolf <kwolf@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	John Snow <jsnow@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 18/18] iotests: Add test for active mirroring
Date: Mon, 18 Sep 2017 18:53:51 +0200	[thread overview]
Message-ID: <ea1f7b60-4b95-f40a-2dc9-e368a74b3de5@redhat.com> (raw)
In-Reply-To: <20170918064515.GF15551@lemon.lan>

[-- Attachment #1: Type: text/plain, Size: 7255 bytes --]

On 2017-09-18 08:45, Fam Zheng wrote:
> On Wed, 09/13 20:19, Max Reitz wrote:
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>  tests/qemu-iotests/151     | 111 +++++++++++++++++++++++++++++++++++++++++++++
>>  tests/qemu-iotests/151.out |   5 ++
>>  tests/qemu-iotests/group   |   1 +
>>  3 files changed, 117 insertions(+)
>>  create mode 100755 tests/qemu-iotests/151
>>  create mode 100644 tests/qemu-iotests/151.out
>>
>> diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
>> new file mode 100755
>> index 0000000000..49a60773f9
>> --- /dev/null
>> +++ b/tests/qemu-iotests/151
>> @@ -0,0 +1,111 @@
>> +#!/usr/bin/env python
>> +#
>> +# Tests for active mirroring
>> +#
>> +# 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 <http://www.gnu.org/licenses/>.
>> +#
>> +
>> +import os
>> +import iotests
>> +from iotests import qemu_img
>> +
>> +source_img = os.path.join(iotests.test_dir, 'source.' + iotests.imgfmt)
>> +target_img = os.path.join(iotests.test_dir, 'target.' + iotests.imgfmt)
>> +
>> +class TestActiveMirror(iotests.QMPTestCase):
>> +    image_len = 128 * 1024 * 1024 # MB
>> +    potential_writes_in_flight = True
>> +
>> +    def setUp(self):
>> +        qemu_img('create', '-f', iotests.imgfmt, source_img, '128M')
>> +        qemu_img('create', '-f', iotests.imgfmt, target_img, '128M')
>> +
>> +        blk_source = {'node-name': 'source',
>> +                      'driver': iotests.imgfmt,
>> +                      'file': {'driver': 'file',
>> +                               'filename': source_img}}
>> +
>> +        blk_target = {'node-name': 'target',
>> +                      'driver': iotests.imgfmt,
>> +                      'file': {'driver': 'file',
>> +                               'filename': target_img}}
>> +
>> +        self.vm = iotests.VM()
>> +        self.vm.add_blockdev(self.qmp_to_opts(blk_source))
>> +        self.vm.add_blockdev(self.qmp_to_opts(blk_target))
>> +        self.vm.launch()
>> +
>> +    def tearDown(self):
>> +        self.vm.shutdown()
>> +
>> +        if not self.potential_writes_in_flight:
>> +            self.assertTrue(iotests.compare_images(source_img, target_img),
>> +                            'mirror target does not match source')
>> +
>> +        os.remove(source_img)
>> +        os.remove(target_img)
>> +
>> +    def doActiveIO(self, sync_source_and_target):
>> +        # Fill the source image
>> +        self.vm.hmp_qemu_io('source',
>> +                            'write -P 1 0 %i' % self.image_len);
>> +
>> +        # Start some background requests
>> +        for offset in range(0, self.image_len, 1024 * 1024):
>> +            self.vm.hmp_qemu_io('source', 'write -B -P 2 %i 1M' % offset)
>> +
>> +        # Start the block job
>> +        result = self.vm.qmp('blockdev-mirror',
>> +                             job_id='mirror',
>> +                             filter_node_name='mirror-node',
>> +                             device='source',
>> +                             target='target',
>> +                             sync='full',
>> +                             copy_mode='active-write')
>> +        self.assert_qmp(result, 'return', {})
>> +
>> +        # Start some more requests
>> +        for offset in range(0, self.image_len, 1024 * 1024):
>> +            self.vm.hmp_qemu_io('mirror-node', 'write -B -P 3 %i 1M' % offset)
>> +
>> +        # Wait for the READY event
>> +        self.wait_ready(drive='mirror')
>> +
>> +        # Now start some final requests; all of these (which land on
>> +        # the source) should be settled using the active mechanism.
>> +        # The mirror code itself asserts that the source BDS's dirty
>> +        # bitmap will stay clean between READY and COMPLETED.
>> +        for offset in range(0, self.image_len, 1024 * 1024):
>> +            self.vm.hmp_qemu_io('mirror-node', 'write -B -P 4 %i 1M' % offset)
>> +
>> +        if sync_source_and_target:
>> +            # If source and target should be in sync after the mirror,
>> +            # we have to flush before completion
> 
> Not sure I understand this requirements, does it apply to libvirt and user too?
> I.e. it's a part of the interface ? Why cannot mirror_complete do it
> automatically?

Well, it seems to pass without this flush, but the original intention
was this: When mirror is completed, the source node is replaced by the
target.  All further writes are then only executed on the (former)
target node.  So what might happen (or at least I think it could) is
that qemu-io submits some writes, but before they are actually
performed, the mirror block job is completed and the source is replaced
by the target.  Then, the write operations are performed on the target
but no longer on the source, so source and target are then out of sync.

For the mirror block job, that is fine -- at the point of completion,
source and target were in sync.  The job doesn't care that they get out
of sync after completion.  But here, we have to care or we can't compare
source and target.

The reason for why it always seems to pass without a flush is that every
submitted write is actually sent to the mirror node before it yields for
the first time.  But I wouldn't bet on that, so I think it's better to
keep the flush before completing the block job.

Max

> 
> Fam
> 
>> +            self.vm.hmp_qemu_io('mirror-node', 'flush')
>> +            self.potential_writes_in_flight = False
>> +
>> +        self.complete_and_wait(drive='mirror', wait_ready=False)
>> +
>> +    def testActiveIO(self):
>> +        self.doActiveIO(False)
>> +
>> +    def testActiveIOFlushed(self):
>> +        self.doActiveIO(True)
>> +
>> +
>> +
>> +if __name__ == '__main__':
>> +    iotests.main(supported_fmts=['qcow2', 'raw'])
>> diff --git a/tests/qemu-iotests/151.out b/tests/qemu-iotests/151.out
>> new file mode 100644
>> index 0000000000..fbc63e62f8
>> --- /dev/null
>> +++ b/tests/qemu-iotests/151.out
>> @@ -0,0 +1,5 @@
>> +..
>> +----------------------------------------------------------------------
>> +Ran 2 tests
>> +
>> +OK
>> diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
>> index 94e764865a..c64adbe5bf 100644
>> --- a/tests/qemu-iotests/group
>> +++ b/tests/qemu-iotests/group
>> @@ -156,6 +156,7 @@
>>  148 rw auto quick
>>  149 rw auto sudo
>>  150 rw auto quick
>> +151 rw auto
>>  152 rw auto quick
>>  153 rw auto quick
>>  154 rw auto backing quick
>> -- 
>> 2.13.5
>>



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

  reply	other threads:[~2017-09-18 16:54 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-13 18:18 [Qemu-devel] [PATCH 00/18] block/mirror: Add active-sync mirroring Max Reitz
2017-09-13 18:18 ` [Qemu-devel] [PATCH 01/18] block: Add BdrvDeletedStatus Max Reitz
2017-09-13 18:18 ` [Qemu-devel] [PATCH 02/18] block: BDS deletion during bdrv_drain_recurse Max Reitz
2017-09-18  3:44   ` Fam Zheng
2017-09-18 16:13     ` Max Reitz
2017-10-09 18:30       ` Max Reitz
2017-10-10  8:36   ` Kevin Wolf
2017-10-11 11:41     ` Max Reitz
2017-09-13 18:18 ` [Qemu-devel] [PATCH 03/18] blockjob: Make drained_{begin, end} public Max Reitz
2017-09-18  3:46   ` Fam Zheng
2017-09-13 18:18 ` [Qemu-devel] [PATCH 04/18] block/mirror: Pull out mirror_perform() Max Reitz
2017-09-18  3:48   ` Fam Zheng
2017-09-25  9:38   ` Vladimir Sementsov-Ogievskiy
2017-09-13 18:18 ` [Qemu-devel] [PATCH 05/18] block/mirror: Convert to coroutines Max Reitz
2017-09-18  6:02   ` Fam Zheng
2017-09-18 16:41     ` Max Reitz
2017-10-10  9:14   ` Kevin Wolf
2017-10-11 11:43     ` Max Reitz
2017-09-13 18:18 ` [Qemu-devel] [PATCH 06/18] block/mirror: Use CoQueue to wait on in-flight ops Max Reitz
2017-09-13 18:18 ` [Qemu-devel] [PATCH 07/18] block/mirror: Wait for in-flight op conflicts Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 08/18] block/mirror: Use source as a BdrvChild Max Reitz
2017-10-10  9:27   ` Kevin Wolf
2017-10-11 11:46     ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 09/18] block: Generalize should_update_child() rule Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 10/18] block/mirror: Make source the file child Max Reitz
2017-10-10  9:47   ` Kevin Wolf
2017-10-11 12:02     ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 11/18] hbitmap: Add @advance param to hbitmap_iter_next() Max Reitz
2017-09-25 15:38   ` Vladimir Sementsov-Ogievskiy
2017-09-25 20:40     ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 12/18] block/dirty-bitmap: Add bdrv_dirty_iter_next_area Max Reitz
2017-09-25 15:49   ` Vladimir Sementsov-Ogievskiy
2017-09-25 20:43     ` Max Reitz
2017-10-02 13:32     ` Vladimir Sementsov-Ogievskiy
2017-09-13 18:19 ` [Qemu-devel] [PATCH 13/18] block/mirror: Keep write perm for pending writes Max Reitz
2017-10-10  9:58   ` Kevin Wolf
2017-10-11 12:20     ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 14/18] block/mirror: Distinguish active from passive ops Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 15/18] block/mirror: Add active mirroring Max Reitz
2017-09-14 15:57   ` Stefan Hajnoczi
2017-09-16 13:58     ` Max Reitz
2017-09-18 10:06       ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-09-18 16:26         ` Max Reitz
2017-09-19  9:44           ` Stefan Hajnoczi
2017-09-19  9:57             ` Daniel P. Berrange
2017-09-20 14:56               ` Stefan Hajnoczi
2017-10-10 10:16           ` Kevin Wolf
2017-10-11 12:33             ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 16/18] block/mirror: Add copy mode QAPI interface Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 17/18] qemu-io: Add background write Max Reitz
2017-09-18  6:46   ` Fam Zheng
2017-09-18 17:53     ` Max Reitz
2017-09-19  8:03       ` Fam Zheng
2017-09-21 14:40         ` Max Reitz
2017-09-21 14:59           ` Fam Zheng
2017-09-21 15:03             ` Max Reitz
2017-09-13 18:19 ` [Qemu-devel] [PATCH 18/18] iotests: Add test for active mirroring Max Reitz
2017-09-18  6:45   ` Fam Zheng
2017-09-18 16:53     ` Max Reitz [this message]
2017-09-19  8:08       ` Fam Zheng
2017-09-14 15:42 ` [Qemu-devel] [PATCH 00/18] block/mirror: Add active-sync mirroring Stefan Hajnoczi
2017-09-16 14:02   ` Max Reitz
2017-09-18 10:02     ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-09-18 15:42       ` Max Reitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ea1f7b60-4b95-f40a-2dc9-e368a74b3de5@redhat.com \
    --to=mreitz@redhat.com \
    --cc=famz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).