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

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