| From 1e0582ad34e77a060e2067a35992979c9eae82c9 Mon Sep 17 00:00:00 2001 |
| From: Kevin Wolf <kwolf@redhat.com> |
| Date: Fri, 13 Mar 2020 12:34:31 +0000 |
| Subject: [PATCH 11/20] block: bdrv_reopen() with backing file in different |
| AioContext |
| |
| RH-Author: Kevin Wolf <kwolf@redhat.com> |
| Message-id: <20200313123439.10548-6-kwolf@redhat.com> |
| Patchwork-id: 94282 |
| O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 05/13] block: bdrv_reopen() with backing file in different AioContext |
| Bugzilla: 1790482 1805143 |
| RH-Acked-by: John Snow <jsnow@redhat.com> |
| RH-Acked-by: Daniel P. Berrange <berrange@redhat.com> |
| RH-Acked-by: Peter Krempa <pkrempa@redhat.com> |
| |
| This patch allows bdrv_reopen() (and therefore the x-blockdev-reopen QMP |
| command) to attach a node as the new backing file even if the node is in |
| a different AioContext than the parent if one of both nodes can be moved |
| to the AioContext of the other node. |
| |
| Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| Tested-by: Peter Krempa <pkrempa@redhat.com> |
| Message-Id: <20200306141413.30705-3-kwolf@redhat.com> |
| Reviewed-by: Alberto Garcia <berto@igalia.com> |
| Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| (cherry picked from commit 1de6b45fb5c1489b450df7d1a4c692bba9678ce6) |
| Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com> |
| |
| block.c | 32 ++++++++++++++++++++++++++------ |
| tests/qemu-iotests/245 | 8 +++----- |
| 2 files changed, 29 insertions(+), 11 deletions(-) |
| |
| diff --git a/block.c b/block.c |
| index a744bb5..39e4647 100644 |
| |
| |
| @@ -3749,6 +3749,29 @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs, |
| *shared = cumulative_shared_perms; |
| } |
| |
| +static bool bdrv_reopen_can_attach(BlockDriverState *parent, |
| + BdrvChild *child, |
| + BlockDriverState *new_child, |
| + Error **errp) |
| +{ |
| + AioContext *parent_ctx = bdrv_get_aio_context(parent); |
| + AioContext *child_ctx = bdrv_get_aio_context(new_child); |
| + GSList *ignore; |
| + bool ret; |
| + |
| + ignore = g_slist_prepend(NULL, child); |
| + ret = bdrv_can_set_aio_context(new_child, parent_ctx, &ignore, NULL); |
| + g_slist_free(ignore); |
| + if (ret) { |
| + return ret; |
| + } |
| + |
| + ignore = g_slist_prepend(NULL, child); |
| + ret = bdrv_can_set_aio_context(parent, child_ctx, &ignore, errp); |
| + g_slist_free(ignore); |
| + return ret; |
| +} |
| + |
| /* |
| * Take a BDRVReopenState and check if the value of 'backing' in the |
| * reopen_state->options QDict is valid or not. |
| @@ -3800,14 +3823,11 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, |
| } |
| |
| /* |
| - * TODO: before removing the x- prefix from x-blockdev-reopen we |
| - * should move the new backing file into the right AioContext |
| - * instead of returning an error. |
| + * Check AioContext compatibility so that the bdrv_set_backing_hd() call in |
| + * bdrv_reopen_commit() won't fail. |
| */ |
| if (new_backing_bs) { |
| - if (bdrv_get_aio_context(new_backing_bs) != bdrv_get_aio_context(bs)) { |
| - error_setg(errp, "Cannot use a new backing file " |
| - "with a different AioContext"); |
| + if (!bdrv_reopen_can_attach(bs, bs->backing, new_backing_bs, errp)) { |
| return -EINVAL; |
| } |
| } |
| diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 |
| index f69c2fa..919131d 100644 |
| |
| |
| @@ -1013,18 +1013,16 @@ class TestBlockdevReopen(iotests.QMPTestCase): |
| # neither of them can switch to the other AioContext |
| def test_iothreads_error(self): |
| self.run_test_iothreads('iothread0', 'iothread1', |
| - "Cannot use a new backing file with a different AioContext") |
| + "Cannot change iothread of active block backend") |
| |
| def test_iothreads_compatible_users(self): |
| self.run_test_iothreads('iothread0', 'iothread0') |
| |
| def test_iothreads_switch_backing(self): |
| - self.run_test_iothreads('iothread0', None, |
| - "Cannot use a new backing file with a different AioContext") |
| + self.run_test_iothreads('iothread0', None) |
| |
| def test_iothreads_switch_overlay(self): |
| - self.run_test_iothreads(None, 'iothread0', |
| - "Cannot use a new backing file with a different AioContext") |
| + self.run_test_iothreads(None, 'iothread0') |
| |
| if __name__ == '__main__': |
| iotests.main(supported_fmts=["qcow2"], |
| -- |
| 1.8.3.1 |
| |