[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 32/53] block/block-copy: add block_copy_cancel
From: |
Max Reitz |
Subject: |
[PULL 32/53] block/block-copy: add block_copy_cancel |
Date: |
Tue, 26 Jan 2021 15:19:55 +0100 |
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Add function to cancel running async block-copy call. It will be used
in backup.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210116214705.822267-8-vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
include/block/block-copy.h | 13 +++++++++++++
block/block-copy.c | 24 +++++++++++++++++++-----
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
index b5a53ad59e..7821850f88 100644
--- a/include/block/block-copy.h
+++ b/include/block/block-copy.h
@@ -74,11 +74,24 @@ void block_copy_call_free(BlockCopyCallState *call_state);
bool block_copy_call_finished(BlockCopyCallState *call_state);
bool block_copy_call_succeeded(BlockCopyCallState *call_state);
bool block_copy_call_failed(BlockCopyCallState *call_state);
+bool block_copy_call_cancelled(BlockCopyCallState *call_state);
int block_copy_call_status(BlockCopyCallState *call_state, bool
*error_is_read);
void block_copy_set_speed(BlockCopyState *s, uint64_t speed);
void block_copy_kick(BlockCopyCallState *call_state);
+/*
+ * Cancel running block-copy call.
+ *
+ * Cancel leaves block-copy state valid: dirty bits are correct and you may use
+ * cancel + <run block_copy with same parameters> to emulate pause/resume.
+ *
+ * Note also, that the cancel is async: it only marks block-copy call to be
+ * cancelled. So, the call may be cancelled (block_copy_call_cancelled()
reports
+ * true) but not yet finished (block_copy_call_finished() reports false).
+ */
+void block_copy_call_cancel(BlockCopyCallState *call_state);
+
BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s);
void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip);
diff --git a/block/block-copy.c b/block/block-copy.c
index fa27450b14..82cf945693 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -51,6 +51,7 @@ typedef struct BlockCopyCallState {
int ret;
bool finished;
QemuCoSleepState *sleep_state;
+ bool cancelled;
/* OUT parameters */
bool error_is_read;
@@ -594,7 +595,7 @@ block_copy_dirty_clusters(BlockCopyCallState *call_state)
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
assert(QEMU_IS_ALIGNED(bytes, s->cluster_size));
- while (bytes && aio_task_pool_status(aio) == 0) {
+ while (bytes && aio_task_pool_status(aio) == 0 && !call_state->cancelled) {
BlockCopyTask *task;
int64_t status_bytes;
@@ -707,7 +708,7 @@ static int coroutine_fn
block_copy_common(BlockCopyCallState *call_state)
do {
ret = block_copy_dirty_clusters(call_state);
- if (ret == 0) {
+ if (ret == 0 && !call_state->cancelled) {
ret = block_copy_wait_one(call_state->s, call_state->offset,
call_state->bytes);
}
@@ -721,7 +722,7 @@ static int coroutine_fn
block_copy_common(BlockCopyCallState *call_state)
* 2. We have waited for some intersecting block-copy request
* It may have failed and produced new dirty bits.
*/
- } while (ret > 0);
+ } while (ret > 0 && !call_state->cancelled);
call_state->finished = true;
@@ -801,12 +802,19 @@ bool block_copy_call_finished(BlockCopyCallState
*call_state)
bool block_copy_call_succeeded(BlockCopyCallState *call_state)
{
- return call_state->finished && call_state->ret == 0;
+ return call_state->finished && !call_state->cancelled &&
+ call_state->ret == 0;
}
bool block_copy_call_failed(BlockCopyCallState *call_state)
{
- return call_state->finished && call_state->ret < 0;
+ return call_state->finished && !call_state->cancelled &&
+ call_state->ret < 0;
+}
+
+bool block_copy_call_cancelled(BlockCopyCallState *call_state)
+{
+ return call_state->cancelled;
}
int block_copy_call_status(BlockCopyCallState *call_state, bool *error_is_read)
@@ -818,6 +826,12 @@ int block_copy_call_status(BlockCopyCallState *call_state,
bool *error_is_read)
return call_state->ret;
}
+void block_copy_call_cancel(BlockCopyCallState *call_state)
+{
+ call_state->cancelled = true;
+ block_copy_kick(call_state);
+}
+
BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s)
{
return s->copy_bitmap;
--
2.29.2
- [PULL 26/53] qapi: backup: add perf.use-copy-range parameter, (continued)
- [PULL 26/53] qapi: backup: add perf.use-copy-range parameter, Max Reitz, 2021/01/26
- [PULL 21/53] iotests/129: Actually test a commit job, Max Reitz, 2021/01/26
- [PULL 24/53] iotests/300: Clean up pylint and mypy complaints, Max Reitz, 2021/01/26
- [PULL 28/53] block/block-copy: implement block_copy_async, Max Reitz, 2021/01/26
- [PULL 30/53] block/block-copy: add list of all call-states, Max Reitz, 2021/01/26
- [PULL 29/53] block/block-copy: add max_chunk and max_workers parameters, Max Reitz, 2021/01/26
- [PULL 31/53] block/block-copy: add ratelimit to block-copy, Max Reitz, 2021/01/26
- [PULL 33/53] blockjob: add set_speed to BlockJobDriver, Max Reitz, 2021/01/26
- [PULL 34/53] job: call job_enter from job_pause, Max Reitz, 2021/01/26
- [PULL 35/53] qapi: backup: add max-chunk and max-workers to x-perf struct, Max Reitz, 2021/01/26
- [PULL 32/53] block/block-copy: add block_copy_cancel,
Max Reitz <=
- [PULL 36/53] iotests: 56: prepare for backup over block-copy, Max Reitz, 2021/01/26
- [PULL 37/53] iotests/129: Limit backup's max-chunk/max-workers, Max Reitz, 2021/01/26
- [PULL 38/53] iotests: 185: prepare for backup over block-copy, Max Reitz, 2021/01/26
- [PULL 39/53] iotests: 219: prepare for backup over block-copy, Max Reitz, 2021/01/26
- [PULL 40/53] iotests: 257: prepare for backup over block-copy, Max Reitz, 2021/01/26
- [PULL 41/53] block/block-copy: make progress_bytes_callback optional, Max Reitz, 2021/01/26
- [PULL 42/53] block/backup: drop extra gotos from backup_run(), Max Reitz, 2021/01/26
- [PULL 43/53] backup: move to block-copy, Max Reitz, 2021/01/26
- [PULL 44/53] qapi: backup: disable copy_range by default, Max Reitz, 2021/01/26
- [PULL 48/53] simplebench: bench_block_job: add cmd_options argument, Max Reitz, 2021/01/26