|
|
7f1c5b |
From ad52cb621daad45d3c2a0e2e670d6ca2e16690bd Mon Sep 17 00:00:00 2001
|
|
|
7f1c5b |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
7f1c5b |
Date: Fri, 18 Nov 2022 18:41:02 +0100
|
|
|
7f1c5b |
Subject: [PATCH 20/31] block: Drain individual nodes during reopen
|
|
|
7f1c5b |
|
|
|
7f1c5b |
RH-Author: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
7f1c5b |
RH-MergeRequest: 135: block: Simplify drain to prevent QEMU from crashing during snapshot
|
|
|
7f1c5b |
RH-Bugzilla: 2155112
|
|
|
7f1c5b |
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
|
|
|
7f1c5b |
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
|
|
7f1c5b |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
7f1c5b |
RH-Commit: [8/16] 5441b6f0ae9102ef40d1093e1db3084eea81e3b0 (sgarzarella/qemu-kvm-c-9-s)
|
|
|
7f1c5b |
|
|
|
7f1c5b |
bdrv_reopen() and friends use subtree drains as a lazy way of covering
|
|
|
7f1c5b |
all the nodes they touch. Turns out that this lazy way is a lot more
|
|
|
7f1c5b |
complicated than just draining the nodes individually, even not
|
|
|
7f1c5b |
accounting for the additional complexity in the drain mechanism itself.
|
|
|
7f1c5b |
|
|
|
7f1c5b |
Simplify the code by switching to draining the individual nodes that are
|
|
|
7f1c5b |
already managed in the BlockReopenQueue anyway.
|
|
|
7f1c5b |
|
|
|
7f1c5b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
7f1c5b |
Message-Id: <20221118174110.55183-8-kwolf@redhat.com>
|
|
|
7f1c5b |
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
|
|
|
7f1c5b |
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
|
|
7f1c5b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
7f1c5b |
(cherry picked from commit d22933acd2f470eeef779e4d444e848f76dcfaf8)
|
|
|
7f1c5b |
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
7f1c5b |
---
|
|
|
7f1c5b |
block.c | 16 +++++++++-------
|
|
|
7f1c5b |
block/replication.c | 6 ------
|
|
|
7f1c5b |
blockdev.c | 13 -------------
|
|
|
7f1c5b |
3 files changed, 9 insertions(+), 26 deletions(-)
|
|
|
7f1c5b |
|
|
|
7f1c5b |
diff --git a/block.c b/block.c
|
|
|
7f1c5b |
index 46df410b07..cb5e96b1cf 100644
|
|
|
7f1c5b |
--- a/block.c
|
|
|
7f1c5b |
+++ b/block.c
|
|
|
7f1c5b |
@@ -4150,7 +4150,7 @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
|
|
|
7f1c5b |
* returns a pointer to bs_queue, which is either the newly allocated
|
|
|
7f1c5b |
* bs_queue, or the existing bs_queue being used.
|
|
|
7f1c5b |
*
|
|
|
7f1c5b |
- * bs must be drained between bdrv_reopen_queue() and bdrv_reopen_multiple().
|
|
|
7f1c5b |
+ * bs is drained here and undrained by bdrv_reopen_queue_free().
|
|
|
7f1c5b |
*
|
|
|
7f1c5b |
* To be called with bs->aio_context locked.
|
|
|
7f1c5b |
*/
|
|
|
7f1c5b |
@@ -4172,12 +4172,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
|
|
7f1c5b |
int flags;
|
|
|
7f1c5b |
QemuOpts *opts;
|
|
|
7f1c5b |
|
|
|
7f1c5b |
- /* Make sure that the caller remembered to use a drained section. This is
|
|
|
7f1c5b |
- * important to avoid graph changes between the recursive queuing here and
|
|
|
7f1c5b |
- * bdrv_reopen_multiple(). */
|
|
|
7f1c5b |
- assert(bs->quiesce_counter > 0);
|
|
|
7f1c5b |
GLOBAL_STATE_CODE();
|
|
|
7f1c5b |
|
|
|
7f1c5b |
+ bdrv_drained_begin(bs);
|
|
|
7f1c5b |
+
|
|
|
7f1c5b |
if (bs_queue == NULL) {
|
|
|
7f1c5b |
bs_queue = g_new0(BlockReopenQueue, 1);
|
|
|
7f1c5b |
QTAILQ_INIT(bs_queue);
|
|
|
7f1c5b |
@@ -4328,6 +4326,12 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
|
|
|
7f1c5b |
if (bs_queue) {
|
|
|
7f1c5b |
BlockReopenQueueEntry *bs_entry, *next;
|
|
|
7f1c5b |
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
|
|
|
7f1c5b |
+ AioContext *ctx = bdrv_get_aio_context(bs_entry->state.bs);
|
|
|
7f1c5b |
+
|
|
|
7f1c5b |
+ aio_context_acquire(ctx);
|
|
|
7f1c5b |
+ bdrv_drained_end(bs_entry->state.bs);
|
|
|
7f1c5b |
+ aio_context_release(ctx);
|
|
|
7f1c5b |
+
|
|
|
7f1c5b |
qobject_unref(bs_entry->state.explicit_options);
|
|
|
7f1c5b |
qobject_unref(bs_entry->state.options);
|
|
|
7f1c5b |
g_free(bs_entry);
|
|
|
7f1c5b |
@@ -4475,7 +4479,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
|
|
7f1c5b |
|
|
|
7f1c5b |
GLOBAL_STATE_CODE();
|
|
|
7f1c5b |
|
|
|
7f1c5b |
- bdrv_subtree_drained_begin(bs);
|
|
|
7f1c5b |
queue = bdrv_reopen_queue(NULL, bs, opts, keep_old_opts);
|
|
|
7f1c5b |
|
|
|
7f1c5b |
if (ctx != qemu_get_aio_context()) {
|
|
|
7f1c5b |
@@ -4486,7 +4489,6 @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
|
|
7f1c5b |
if (ctx != qemu_get_aio_context()) {
|
|
|
7f1c5b |
aio_context_acquire(ctx);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
- bdrv_subtree_drained_end(bs);
|
|
|
7f1c5b |
|
|
|
7f1c5b |
return ret;
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
diff --git a/block/replication.c b/block/replication.c
|
|
|
7f1c5b |
index f1eed25e43..c62f48a874 100644
|
|
|
7f1c5b |
--- a/block/replication.c
|
|
|
7f1c5b |
+++ b/block/replication.c
|
|
|
7f1c5b |
@@ -374,9 +374,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
|
|
|
7f1c5b |
s->orig_secondary_read_only = bdrv_is_read_only(secondary_disk->bs);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
|
|
|
7f1c5b |
- bdrv_subtree_drained_begin(hidden_disk->bs);
|
|
|
7f1c5b |
- bdrv_subtree_drained_begin(secondary_disk->bs);
|
|
|
7f1c5b |
-
|
|
|
7f1c5b |
if (s->orig_hidden_read_only) {
|
|
|
7f1c5b |
QDict *opts = qdict_new();
|
|
|
7f1c5b |
qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
|
|
|
7f1c5b |
@@ -401,9 +398,6 @@ static void reopen_backing_file(BlockDriverState *bs, bool writable,
|
|
|
7f1c5b |
aio_context_acquire(ctx);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
-
|
|
|
7f1c5b |
- bdrv_subtree_drained_end(hidden_disk->bs);
|
|
|
7f1c5b |
- bdrv_subtree_drained_end(secondary_disk->bs);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
|
|
|
7f1c5b |
static void backup_job_cleanup(BlockDriverState *bs)
|
|
|
7f1c5b |
diff --git a/blockdev.c b/blockdev.c
|
|
|
7f1c5b |
index 3f1dec6242..8ffb3d9537 100644
|
|
|
7f1c5b |
--- a/blockdev.c
|
|
|
7f1c5b |
+++ b/blockdev.c
|
|
|
7f1c5b |
@@ -3547,8 +3547,6 @@ fail:
|
|
|
7f1c5b |
void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
|
|
7f1c5b |
{
|
|
|
7f1c5b |
BlockReopenQueue *queue = NULL;
|
|
|
7f1c5b |
- GSList *drained = NULL;
|
|
|
7f1c5b |
- GSList *p;
|
|
|
7f1c5b |
|
|
|
7f1c5b |
/* Add each one of the BDS that we want to reopen to the queue */
|
|
|
7f1c5b |
for (; reopen_list != NULL; reopen_list = reopen_list->next) {
|
|
|
7f1c5b |
@@ -3585,9 +3583,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
|
|
7f1c5b |
ctx = bdrv_get_aio_context(bs);
|
|
|
7f1c5b |
aio_context_acquire(ctx);
|
|
|
7f1c5b |
|
|
|
7f1c5b |
- bdrv_subtree_drained_begin(bs);
|
|
|
7f1c5b |
queue = bdrv_reopen_queue(queue, bs, qdict, false);
|
|
|
7f1c5b |
- drained = g_slist_prepend(drained, bs);
|
|
|
7f1c5b |
|
|
|
7f1c5b |
aio_context_release(ctx);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
@@ -3598,15 +3594,6 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp)
|
|
|
7f1c5b |
|
|
|
7f1c5b |
fail:
|
|
|
7f1c5b |
bdrv_reopen_queue_free(queue);
|
|
|
7f1c5b |
- for (p = drained; p; p = p->next) {
|
|
|
7f1c5b |
- BlockDriverState *bs = p->data;
|
|
|
7f1c5b |
- AioContext *ctx = bdrv_get_aio_context(bs);
|
|
|
7f1c5b |
-
|
|
|
7f1c5b |
- aio_context_acquire(ctx);
|
|
|
7f1c5b |
- bdrv_subtree_drained_end(bs);
|
|
|
7f1c5b |
- aio_context_release(ctx);
|
|
|
7f1c5b |
- }
|
|
|
7f1c5b |
- g_slist_free(drained);
|
|
|
7f1c5b |
}
|
|
|
7f1c5b |
|
|
|
7f1c5b |
void qmp_blockdev_del(const char *node_name, Error **errp)
|
|
|
7f1c5b |
--
|
|
|
7f1c5b |
2.31.1
|
|
|
7f1c5b |
|