Blame SOURCES/kvm-blockdev-Return-bs-to-the-proper-context-on-snapshot.patch

902636
From 24e5eca4218b294bd013e2d85a38345045506bec Mon Sep 17 00:00:00 2001
902636
From: Sergio Lopez Pascual <slp@redhat.com>
902636
Date: Fri, 7 Feb 2020 11:27:48 +0000
902636
Subject: [PATCH 15/18] blockdev: Return bs to the proper context on snapshot
902636
 abort
902636
902636
RH-Author: Sergio Lopez Pascual <slp@redhat.com>
902636
Message-id: <20200207112749.25073-9-slp@redhat.com>
902636
Patchwork-id: 93761
902636
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 8/9] blockdev: Return bs to the proper context on snapshot abort
902636
Bugzilla: 1745606 1746217 1773517 1779036 1782111 1782175 1783965
902636
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
902636
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
902636
RH-Acked-by: Max Reitz <mreitz@redhat.com>
902636
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
902636
902636
external_snapshot_abort() calls to bdrv_set_backing_hd(), which
902636
returns state->old_bs to the main AioContext, as it's intended to be
902636
used then the BDS is going to be released. As that's not the case when
902636
aborting an external snapshot, return it to the AioContext it was
902636
before the call.
902636
902636
This issue can be triggered by issuing a transaction with two actions,
902636
a proper blockdev-snapshot-sync and a bogus one, so the second will
902636
trigger a transaction abort. This results in a crash with an stack
902636
trace like this one:
902636
902636
 #0  0x00007fa1048b28df in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
902636
 #1  0x00007fa10489ccf5 in __GI_abort () at abort.c:79
902636
 #2  0x00007fa10489cbc9 in __assert_fail_base
902636
     (fmt=0x7fa104a03300 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x5572240b44d8 "bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs)", file=0x557224014d30 "block.c", line=2240, function=<optimized out>) at assert.c:92
902636
 #3  0x00007fa1048aae96 in __GI___assert_fail
902636
     (assertion=assertion@entry=0x5572240b44d8 "bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs)", file=file@entry=0x557224014d30 "block.c", line=line@entry=2240, function=function@entry=0x5572240b5d60 <__PRETTY_FUNCTION__.31620> "bdrv_replace_child_noperm") at assert.c:101
902636
 #4  0x0000557223e631f8 in bdrv_replace_child_noperm (child=0x557225b9c980, new_bs=new_bs@entry=0x557225c42e40) at block.c:2240
902636
 #5  0x0000557223e68be7 in bdrv_replace_node (from=0x557226951a60, to=0x557225c42e40, errp=0x5572247d6138 <error_abort>) at block.c:4196
902636
 #6  0x0000557223d069c4 in external_snapshot_abort (common=0x557225d7e170) at blockdev.c:1731
902636
 #7  0x0000557223d069c4 in external_snapshot_abort (common=0x557225d7e170) at blockdev.c:1717
902636
 #8  0x0000557223d09013 in qmp_transaction (dev_list=<optimized out>, has_props=<optimized out>, props=0x557225cc7d70, errp=errp@entry=0x7ffe704c0c98) at blockdev.c:2360
902636
 #9  0x0000557223e32085 in qmp_marshal_transaction (args=<optimized out>, ret=<optimized out>, errp=0x7ffe704c0d08) at qapi/qapi-commands-transaction.c:44
902636
 #10 0x0000557223ee798c in do_qmp_dispatch (errp=0x7ffe704c0d00, allow_oob=<optimized out>, request=<optimized out>, cmds=0x5572247d3cc0 <qmp_commands>) at qapi/qmp-dispatch.c:132
902636
 #11 0x0000557223ee798c in qmp_dispatch (cmds=0x5572247d3cc0 <qmp_commands>, request=<optimized out>, allow_oob=<optimized out>) at qapi/qmp-dispatch.c:175
902636
 #12 0x0000557223e06141 in monitor_qmp_dispatch (mon=0x557225c69ff0, req=<optimized out>) at monitor/qmp.c:120
902636
 #13 0x0000557223e0678a in monitor_qmp_bh_dispatcher (data=<optimized out>) at monitor/qmp.c:209
902636
 #14 0x0000557223f2f366 in aio_bh_call (bh=0x557225b9dc60) at util/async.c:117
902636
 #15 0x0000557223f2f366 in aio_bh_poll (ctx=ctx@entry=0x557225b9c840) at util/async.c:117
902636
 #16 0x0000557223f32754 in aio_dispatch (ctx=0x557225b9c840) at util/aio-posix.c:459
902636
 #17 0x0000557223f2f242 in aio_ctx_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at util/async.c:260
902636
 #18 0x00007fa10913467d in g_main_dispatch (context=0x557225c28e80) at gmain.c:3176
902636
 #19 0x00007fa10913467d in g_main_context_dispatch (context=context@entry=0x557225c28e80) at gmain.c:3829
902636
 #20 0x0000557223f31808 in glib_pollfds_poll () at util/main-loop.c:219
902636
 #21 0x0000557223f31808 in os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:242
902636
 #22 0x0000557223f31808 in main_loop_wait (nonblocking=<optimized out>) at util/main-loop.c:518
902636
 #23 0x0000557223d13201 in main_loop () at vl.c:1828
902636
 #24 0x0000557223bbfb82 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4504
902636
902636
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1779036
902636
Signed-off-by: Sergio Lopez <slp@redhat.com>
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
(cherry picked from commit 377410f6fb4f6b0d26d4a028c20766fae05de17e)
902636
Signed-off-by: Sergio Lopez <slp@redhat.com>
902636
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
902636
---
902636
 blockdev.c | 21 +++++++++++++++++++++
902636
 1 file changed, 21 insertions(+)
902636
902636
diff --git a/blockdev.c b/blockdev.c
902636
index d4ef6cd..4cd9a58 100644
902636
--- a/blockdev.c
902636
+++ b/blockdev.c
902636
@@ -1731,6 +1731,8 @@ static void external_snapshot_abort(BlkActionState *common)
902636
     if (state->new_bs) {
902636
         if (state->overlay_appended) {
902636
             AioContext *aio_context;
902636
+            AioContext *tmp_context;
902636
+            int ret;
902636
 
902636
             aio_context = bdrv_get_aio_context(state->old_bs);
902636
             aio_context_acquire(aio_context);
902636
@@ -1738,6 +1740,25 @@ static void external_snapshot_abort(BlkActionState *common)
902636
             bdrv_ref(state->old_bs);   /* we can't let bdrv_set_backind_hd()
902636
                                           close state->old_bs; we need it */
902636
             bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
902636
+
902636
+            /*
902636
+             * The call to bdrv_set_backing_hd() above returns state->old_bs to
902636
+             * the main AioContext. As we're still going to be using it, return
902636
+             * it to the AioContext it was before.
902636
+             */
902636
+            tmp_context = bdrv_get_aio_context(state->old_bs);
902636
+            if (aio_context != tmp_context) {
902636
+                aio_context_release(aio_context);
902636
+                aio_context_acquire(tmp_context);
902636
+
902636
+                ret = bdrv_try_set_aio_context(state->old_bs,
902636
+                                               aio_context, NULL);
902636
+                assert(ret == 0);
902636
+
902636
+                aio_context_release(tmp_context);
902636
+                aio_context_acquire(aio_context);
902636
+            }
902636
+
902636
             bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
902636
             bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
902636
 
902636
-- 
902636
1.8.3.1
902636