Pablo Greco e6a3ae
From 6123c29fcf385010a683061fd7f948f256713b48 Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Date: Fri, 17 May 2019 14:23:15 +0100
Pablo Greco e6a3ae
Subject: [PATCH 4/5] block: Fix invalidate_cache error path for parent
Pablo Greco e6a3ae
 activation
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Message-id: <20190517142315.16266-2-kwolf@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 88024
Pablo Greco e6a3ae
O-Subject: [RHEL-8.1 qemu-kvm PATCH 1/1] block: Fix invalidate_cache error path for parent activation
Pablo Greco e6a3ae
Bugzilla: 1673010
Pablo Greco e6a3ae
RH-Acked-by: John Snow <jsnow@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
bdrv_co_invalidate_cache() clears the BDRV_O_INACTIVE flag before
Pablo Greco e6a3ae
actually activating a node so that the correct permissions etc. are
Pablo Greco e6a3ae
taken. In case of errors, the flag must be restored so that the next
Pablo Greco e6a3ae
call to bdrv_co_invalidate_cache() retries activation.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Restoring the flag was missing in the error path for a failed
Pablo Greco e6a3ae
parent->role->activate() call. The consequence is that this attempt to
Pablo Greco e6a3ae
activate all images correctly fails because we still set errp, however
Pablo Greco e6a3ae
on the next attempt BDRV_O_INACTIVE is already clear, so we return
Pablo Greco e6a3ae
success without actually retrying the failed action.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
An example where this is observable in practice is migration to a QEMU
Pablo Greco e6a3ae
instance that has a raw format block node attached to a guest device
Pablo Greco e6a3ae
with share-rw=off (the default) while another process holds
Pablo Greco e6a3ae
BLK_PERM_WRITE for the same image. In this case, all activation steps
Pablo Greco e6a3ae
before parent->role->activate() succeed because raw can tolerate other
Pablo Greco e6a3ae
writers to the image. Only the parent callback (in particular
Pablo Greco e6a3ae
blk_root_activate()) tries to implement the share-rw=on property and
Pablo Greco e6a3ae
requests exclusive write permissions. This fails when the migration
Pablo Greco e6a3ae
completes and correctly displays an error. However, a manual 'cont' will
Pablo Greco e6a3ae
incorrectly resume the VM without calling blk_root_activate() again.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
This case is described in more detail in the following bug report:
Pablo Greco e6a3ae
https://bugzilla.redhat.com/show_bug.cgi?id=1531888
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Fix this by correctly restoring the BDRV_O_INACTIVE flag in the error
Pablo Greco e6a3ae
path.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Cc: qemu-stable@nongnu.org
Pablo Greco e6a3ae
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Tested-by: Markus Armbruster <armbru@redhat.com>
Pablo Greco e6a3ae
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit 78fc3b3a26c145eebcdee992988644974b243a74)
Pablo Greco e6a3ae
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 block.c | 1 +
Pablo Greco e6a3ae
 1 file changed, 1 insertion(+)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/block.c b/block.c
Pablo Greco e6a3ae
index d0f0dc6..82b16df 100644
Pablo Greco e6a3ae
--- a/block.c
Pablo Greco e6a3ae
+++ b/block.c
Pablo Greco e6a3ae
@@ -4417,6 +4417,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
Pablo Greco e6a3ae
         if (parent->role->activate) {
Pablo Greco e6a3ae
             parent->role->activate(parent, &local_err);
Pablo Greco e6a3ae
             if (local_err) {
Pablo Greco e6a3ae
+                bs->open_flags |= BDRV_O_INACTIVE;
Pablo Greco e6a3ae
                 error_propagate(errp, local_err);
Pablo Greco e6a3ae
                 return;
Pablo Greco e6a3ae
             }
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae