From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>,
Fam Zheng <famz@redhat.com>, Kevin Wolf <kwolf@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH 00/18] block/mirror: Add active-sync mirroring
Date: Wed, 13 Sep 2017 20:18:52 +0200 [thread overview]
Message-ID: <20170913181910.29688-1-mreitz@redhat.com> (raw)
This series implements an active and synchronous mirroring mode.
Currently, the mirror block job is passive an asynchronous: Depending on
your start conditions, some part of the source disk starts as "dirty".
Then, the block job will (as a background operation) continuously copy
dirty parts to the target disk until all of the source disk is clean.
In the meantime, any write to the source disk dirties the affected area.
One effect of this operational mode is that the job may never converge:
If the writes to the source happen faster than the block job copies data
to the target, the job can never finish.
When the active mode implemented in this series is enabled, every write
request to the source will automatically trigger a synchronous write to
the target right afterwards. Therefore, the source can never get dirty
faster than data is copied to the target. Most importantly, once source
and target are in sync (BLOCK_JOB_READY is emitted), they will not
diverge (unless e.g. an I/O error occurs).
Active mirroring also improves on a second issue of the passive mode: We
do not have to read data from the source in order to write it to the
target. When new data is written to the source in active mode, it is
automatically mirrored to the target, which saves us the superfluous
read from the source.
(Optionally, one can choose to also mirror data read from the source.
This does not necessarily help with convergence, but it saves an extra
read operation (in exchange for slower read access to the source because
this mirroring is implemented synchronously).)
There may be a couple of things to do on top of this series:
- Allow switching between active and passive mode at runtime: This
should not be too difficult to implement, the main question is how to
expose it to the user.
(I seem to recall we wanted some form of block-job-set-option
command...?)
- Implement an asynchronous active mode: May be detrimental when it
comes to convergence, but it might be nice to have anyway. May or may
not be complicated to implement.
- Make the target a BdrvChild of the mirror BDS: This series does some
work to make the mirror BDS a more integral part of the block job (see
below for more). One of the things I wanted to do is to make both the
source and the target plain children of that BDS, and I did have
patches to do this. However, at some point continuing to do this for
the target seemed rather difficult, and also a bit pointless, so I
decided to keep it for later.
(To be specific, that "some point" was exactly when I tried to rebase
onto 045a2f8254c.)
=== Structure of this series ===
The first half (up until patch 10) restructures parts of the mirror
block job:
- Patches 4/5:
The job is converted to use coroutines instead of AIO.
(because this is probably where we want to go, and also because active
mirroring will need to wait on conflicting in-flight operations, and
I really don't want to wait on in-flight AIO requests)
This is done primarily by patch 5, with patch 4 being necessary
beforehand.
- Patches 6/7:
Every in-flight operation gets a CoQueue so it can be waited on
(because this allows active mirroring operations to wait for
conflicting writes)
This is started by patch 6, and with patch 7, every bit in the
in-flight bitmap has at least one corresponding operation in the
MirrorBlockJob.ops_in_flight list that can be waited on.
- Patches 1/2/3/8/9/10:
The source node is now no longer used through a BlockBackend (patch 8)
and also it is now attached to the mirror BDS as the "file" child
instead of the "backing" child (patch 10).
This is mostly because I'd personally like the mirror BDS to be a real
filter BDS instead of some technicality that needs to be there to
solve op blocker issues.
Patches 3 and 9 are necessary for patch 10.
Patches 1 and 2 were necessary for this when I decided to include
another patch to make the target node an immediate child of the mirror
BDS, too. However, as I wrote above, I later decided to put this idea
off until later, and as long as the mirror BDS only has a single
child, those patches are not strictly necessary.
However, I think that those patches are good to have anyway, so I
decided to keep them.
The second half (patches 11 to 18) implement active mirroring:
- Patch 11 is required by patch 12. This in turn is required by the
active-sync mode when mirroring data read from the source to the
target, because that functionality needs to be able to find all the
parts of the data read which are actually dirty so we don't copy clean
data.
- Patches 13 and 14 prepare for the job for active operations.
- Patch 15 implements active mirroring.
- Patch 16 allows it to be used (by adding a parameter to
blockdev-mirror and drive-mirror).
- Patch 18 adds an iotest which relies on functionality introduced by
patch 17.
Max Reitz (18):
block: Add BdrvDeletedStatus
block: BDS deletion during bdrv_drain_recurse
blockjob: Make drained_{begin,end} public
block/mirror: Pull out mirror_perform()
block/mirror: Convert to coroutines
block/mirror: Use CoQueue to wait on in-flight ops
block/mirror: Wait for in-flight op conflicts
block/mirror: Use source as a BdrvChild
block: Generalize should_update_child() rule
block/mirror: Make source the file child
hbitmap: Add @advance param to hbitmap_iter_next()
block/dirty-bitmap: Add bdrv_dirty_iter_next_area
block/mirror: Keep write perm for pending writes
block/mirror: Distinguish active from passive ops
block/mirror: Add active mirroring
block/mirror: Add copy mode QAPI interface
qemu-io: Add background write
iotests: Add test for active mirroring
qapi/block-core.json | 34 ++-
include/block/block_int.h | 18 +-
include/block/blockjob.h | 15 +
include/block/dirty-bitmap.h | 2 +
include/qemu/hbitmap.h | 4 +-
block.c | 50 +++-
block/dirty-bitmap.c | 54 +++-
block/io.c | 72 +++--
block/mirror.c | 633 +++++++++++++++++++++++++++++++++----------
block/qapi.c | 25 +-
blockdev.c | 9 +-
blockjob.c | 20 +-
qemu-io-cmds.c | 83 +++++-
tests/test-hbitmap.c | 26 +-
util/hbitmap.c | 10 +-
tests/qemu-iotests/141.out | 4 +-
tests/qemu-iotests/151 | 111 ++++++++
tests/qemu-iotests/151.out | 5 +
tests/qemu-iotests/group | 1 +
19 files changed, 964 insertions(+), 212 deletions(-)
create mode 100755 tests/qemu-iotests/151
create mode 100644 tests/qemu-iotests/151.out
--
2.13.5
next reply other threads:[~2017-09-13 18:19 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-13 18:18 Max Reitz [this message]
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
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=20170913181910.29688-1-mreitz@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.