Blame SOURCES/kvm-block-Relax-restrictions-for-blockdev-snapshot.patch

902636
From 9ba321e18a357c1a3a238ceee301bbb174f96eee Mon Sep 17 00:00:00 2001
902636
From: Kevin Wolf <kwolf@redhat.com>
902636
Date: Fri, 13 Mar 2020 12:34:34 +0000
902636
Subject: [PATCH 14/20] block: Relax restrictions for blockdev-snapshot
902636
902636
RH-Author: Kevin Wolf <kwolf@redhat.com>
902636
Message-id: <20200313123439.10548-9-kwolf@redhat.com>
902636
Patchwork-id: 94285
902636
O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH v2 08/13] block: Relax restrictions for blockdev-snapshot
902636
Bugzilla: 1790482 1805143
902636
RH-Acked-by: John Snow <jsnow@redhat.com>
902636
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
902636
RH-Acked-by: Peter Krempa <pkrempa@redhat.com>
902636
902636
blockdev-snapshot returned an error if the overlay was already in use,
902636
which it defined as having any BlockBackend parent. This is in fact both
902636
too strict (some parents can tolerate the change of visible data caused
902636
by attaching a backing file) and too loose (some non-BlockBackend
902636
parents may not be happy with it).
902636
902636
One important use case that is prevented by the too strict check is live
902636
storage migration with blockdev-mirror. Here, the target node is
902636
usually opened without a backing file so that the active layer is
902636
mirrored while its backing chain can be copied in the background.
902636
902636
The backing chain should be attached to the mirror target node when
902636
finalising the job, just before switching the users of the source node
902636
to the new copy (at which point the mirror job still has a reference to
902636
the node). drive-mirror did this automatically, but with blockdev-mirror
902636
this is the job of the QMP client, so it needs a way to do this.
902636
902636
blockdev-snapshot is the obvious way, so this patch makes it work in
902636
this scenario. The new condition is that no parent uses CONSISTENT_READ
902636
permissions. This will ensure that the operation will still be blocked
902636
when the node is attached to the guest device, so blockdev-snapshot
902636
remains safe.
902636
902636
(For the sake of completeness, x-blockdev-reopen can be used to achieve
902636
the same, however it is a big hammer, performs the graph change
902636
completely unchecked and is still experimental. So even with the option
902636
of using x-blockdev-reopen, there are reasons why blockdev-snapshot
902636
should be able to perform this operation.)
902636
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
Message-Id: <20200310113831.27293-3-kwolf@redhat.com>
902636
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
902636
Tested-by: Peter Krempa <pkrempa@redhat.com>
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
(cherry picked from commit d29d3d1f80b3947fb26e7139645c83de66d146a9)
902636
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
902636
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
902636
---
902636
 blockdev.c                 | 14 ++++++++------
902636
 tests/qemu-iotests/085.out |  4 ++--
902636
 2 files changed, 10 insertions(+), 8 deletions(-)
902636
902636
diff --git a/blockdev.c b/blockdev.c
902636
index 4cd9a58..7918533 100644
902636
--- a/blockdev.c
902636
+++ b/blockdev.c
902636
@@ -1536,6 +1536,7 @@ static void external_snapshot_prepare(BlkActionState *common,
902636
     TransactionAction *action = common->action;
902636
     AioContext *aio_context;
902636
     AioContext *old_context;
902636
+    uint64_t perm, shared;
902636
     int ret;
902636
 
902636
     /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
902636
@@ -1656,16 +1657,17 @@ static void external_snapshot_prepare(BlkActionState *common,
902636
         goto out;
902636
     }
902636
 
902636
-    if (bdrv_has_blk(state->new_bs)) {
902636
+    /*
902636
+     * Allow attaching a backing file to an overlay that's already in use only
902636
+     * if the parents don't assume that they are already seeing a valid image.
902636
+     * (Specifically, allow it as a mirror target, which is write-only access.)
902636
+     */
902636
+    bdrv_get_cumulative_perm(state->new_bs, &perm, &shared);
902636
+    if (perm & BLK_PERM_CONSISTENT_READ) {
902636
         error_setg(errp, "The overlay is already in use");
902636
         goto out;
902636
     }
902636
 
902636
-    if (bdrv_op_is_blocked(state->new_bs, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
902636
-                           errp)) {
902636
-        goto out;
902636
-    }
902636
-
902636
     if (state->new_bs->backing != NULL) {
902636
         error_setg(errp, "The overlay already has a backing image");
902636
         goto out;
902636
diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out
902636
index bb50227..487d920 100644
902636
--- a/tests/qemu-iotests/085.out
902636
+++ b/tests/qemu-iotests/085.out
902636
@@ -82,7 +82,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
902636
 === Invalid command - cannot create a snapshot using a file BDS ===
902636
 
902636
 { 'execute': 'blockdev-snapshot', 'arguments': { 'node':'virtio0', 'overlay':'file_12' } }
902636
-{"error": {"class": "GenericError", "desc": "The overlay does not support backing images"}}
902636
+{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
902636
 
902636
 === Invalid command - snapshot node used as active layer ===
902636
 
902636
@@ -96,7 +96,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
902636
 === Invalid command - snapshot node used as backing hd ===
902636
 
902636
 { 'execute': 'blockdev-snapshot', 'arguments': { 'node': 'virtio0', 'overlay':'snap_11' } }
902636
-{"error": {"class": "GenericError", "desc": "Node 'snap_11' is busy: node is used as backing hd of 'snap_12'"}}
902636
+{"error": {"class": "GenericError", "desc": "The overlay is already in use"}}
902636
 
902636
 === Invalid command - snapshot node has a backing image ===
902636
 
902636
-- 
902636
1.8.3.1
902636