[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 22/27] mirror: implement mirror_change method
From: |
Kevin Wolf |
Subject: |
[PULL 22/27] mirror: implement mirror_change method |
Date: |
Tue, 31 Oct 2023 19:59:13 +0100 |
From: Fiona Ebner <f.ebner@proxmox.com>
which allows switching the @copy-mode from 'background' to
'write-blocking'.
This is useful for management applications, so they can start out in
background mode to avoid limiting guest write speed and switch to
active mode when certain criteria are fulfilled.
In presence of an iothread, the copy_mode member is now shared between
the iothread and the main thread, so turn accesses to it atomic.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20231031135431.393137-6-f.ebner@proxmox.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qapi/block-core.json | 13 ++++++++++++-
block/mirror.c | 44 +++++++++++++++++++++++++++++++++++++++++---
2 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index c6f31a9399..6369207be2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3044,6 +3044,17 @@
{ 'command': 'block-job-finalize', 'data': { 'id': 'str' },
'allow-preconfig': true }
+##
+# @BlockJobChangeOptionsMirror:
+#
+# @copy-mode: Switch to this copy mode. Currently, only the switch
+# from 'background' to 'write-blocking' is implemented.
+#
+# Since: 8.2
+##
+{ 'struct': 'BlockJobChangeOptionsMirror',
+ 'data': { 'copy-mode' : 'MirrorCopyMode' } }
+
##
# @BlockJobChangeOptions:
#
@@ -3058,7 +3069,7 @@
{ 'union': 'BlockJobChangeOptions',
'base': { 'id': 'str', 'type': 'JobType' },
'discriminator': 'type',
- 'data': {} }
+ 'data': { 'mirror': 'BlockJobChangeOptionsMirror' } }
##
# @block-job-change:
diff --git a/block/mirror.c b/block/mirror.c
index 31da1526eb..4016d89253 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -55,6 +55,10 @@ typedef struct MirrorBlockJob {
BlockMirrorBackingMode backing_mode;
/* Whether the target image requires explicit zero-initialization */
bool zero_target;
+ /*
+ * To be accesssed with atomics. Written only under the BQL (required by
the
+ * current implementation of mirror_change()).
+ */
MirrorCopyMode copy_mode;
BlockdevOnError on_source_error, on_target_error;
/* Set when the target is synced (dirty bitmap is clean, nothing
@@ -1075,7 +1079,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
*/
job_transition_to_ready(&s->common.job);
}
- if (s->copy_mode != MIRROR_COPY_MODE_BACKGROUND) {
+ if (qatomic_read(&s->copy_mode) != MIRROR_COPY_MODE_BACKGROUND) {
s->actively_synced = true;
}
@@ -1246,6 +1250,39 @@ static bool commit_active_cancel(Job *job, bool force)
return force || !job_is_ready(job);
}
+static void mirror_change(BlockJob *job, BlockJobChangeOptions *opts,
+ Error **errp)
+{
+ MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
+ BlockJobChangeOptionsMirror *change_opts = &opts->u.mirror;
+ MirrorCopyMode current;
+
+ /*
+ * The implementation relies on the fact that copy_mode is only written
+ * under the BQL. Otherwise, further synchronization would be required.
+ */
+
+ GLOBAL_STATE_CODE();
+
+ if (qatomic_read(&s->copy_mode) == change_opts->copy_mode) {
+ return;
+ }
+
+ if (change_opts->copy_mode != MIRROR_COPY_MODE_WRITE_BLOCKING) {
+ error_setg(errp, "Change to copy mode '%s' is not implemented",
+ MirrorCopyMode_str(change_opts->copy_mode));
+ return;
+ }
+
+ current = qatomic_cmpxchg(&s->copy_mode, MIRROR_COPY_MODE_BACKGROUND,
+ change_opts->copy_mode);
+ if (current != MIRROR_COPY_MODE_BACKGROUND) {
+ error_setg(errp, "Expected current copy mode '%s', got '%s'",
+ MirrorCopyMode_str(MIRROR_COPY_MODE_BACKGROUND),
+ MirrorCopyMode_str(current));
+ }
+}
+
static const BlockJobDriver mirror_job_driver = {
.job_driver = {
.instance_size = sizeof(MirrorBlockJob),
@@ -1260,6 +1297,7 @@ static const BlockJobDriver mirror_job_driver = {
.cancel = mirror_cancel,
},
.drained_poll = mirror_drained_poll,
+ .change = mirror_change,
};
static const BlockJobDriver commit_active_job_driver = {
@@ -1467,7 +1505,7 @@ static bool should_copy_to_target(MirrorBDSOpaque *s)
{
return s->job && s->job->ret >= 0 &&
!job_is_cancelled(&s->job->common.job) &&
- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+ qatomic_read(&s->job->copy_mode) == MIRROR_COPY_MODE_WRITE_BLOCKING;
}
static int coroutine_fn GRAPH_RDLOCK
@@ -1813,7 +1851,7 @@ static BlockJob *mirror_start_job(
s->is_none_mode = is_none_mode;
s->backing_mode = backing_mode;
s->zero_target = zero_target;
- s->copy_mode = copy_mode;
+ qatomic_set(&s->copy_mode, copy_mode);
s->base = base;
s->base_overlay = bdrv_find_overlay(bs, base);
s->granularity = granularity;
--
2.41.0
- [PULL 17/27] virtio-blk: remove batch notification BH, (continued)
- [PULL 17/27] virtio-blk: remove batch notification BH, Kevin Wolf, 2023/10/31
- [PULL 13/27] blockdev: mirror: avoid potential deadlock when using iothread, Kevin Wolf, 2023/10/31
- [PULL 18/27] blockjob: introduce block-job-change QMP command, Kevin Wolf, 2023/10/31
- [PULL 09/27] block: Fix locking in media change monitor commands, Kevin Wolf, 2023/10/31
- [PULL 11/27] blockjob: drop AioContext lock before calling bdrv_graph_wrlock(), Kevin Wolf, 2023/10/31
- [PULL 25/27] blockjob: query driver-specific info via a new 'query' driver method, Kevin Wolf, 2023/10/31
- [PULL 12/27] block: avoid potential deadlock during bdrv_graph_wrlock() in bdrv_close(), Kevin Wolf, 2023/10/31
- [PULL 14/27] block: rename blk_io_plug_call() API to defer_call(), Kevin Wolf, 2023/10/31
- [PULL 10/27] iotests: Test media change with iothreads, Kevin Wolf, 2023/10/31
- [PULL 23/27] qapi/block-core: use JobType for BlockJobInfo's type, Kevin Wolf, 2023/10/31
- [PULL 22/27] mirror: implement mirror_change method,
Kevin Wolf <=
- [PULL 26/27] mirror: return mirror-specific information upon query, Kevin Wolf, 2023/10/31
- [PULL 27/27] iotests: add test for changing mirror's copy_mode, Kevin Wolf, 2023/10/31
- [PULL 24/27] qapi/block-core: turn BlockJobInfo into a union, Kevin Wolf, 2023/10/31
- [PULL 08/27] iotests: add tests for "qemu-img rebase" with compression, Kevin Wolf, 2023/10/31
- Re: [PULL 00/27] Block layer patches, Stefan Hajnoczi, 2023/10/31