* Thu Feb 09 2023 Miroslav Rezanina <mrezanin@redhat.com> - 7.2.0-8
- kvm-qcow2-Fix-theoretical-corruption-in-store_bitmap-err.patch [bz#2150180] - kvm-qemu-img-commit-Report-errors-while-closing-the-imag.patch [bz#2150180] - kvm-qemu-img-bitmap-Report-errors-while-closing-the-imag.patch [bz#2150180] - kvm-qemu-iotests-Test-qemu-img-bitmap-commit-exit-code-o.patch [bz#2150180] - kvm-accel-tcg-Test-CPUJumpCache-in-tb_jmp_cache_clear_pa.patch [bz#2165280] - kvm-block-Improve-empty-format-specific-info-dump.patch [bz#1860292] - kvm-block-file-Add-file-specific-image-info.patch [bz#1860292] - kvm-block-vmdk-Change-extent-info-type.patch [bz#1860292] - kvm-block-Split-BlockNodeInfo-off-of-ImageInfo.patch [bz#1860292] - kvm-qemu-img-Use-BlockNodeInfo.patch [bz#1860292] - kvm-block-qapi-Let-bdrv_query_image_info-recurse.patch [bz#1860292] - kvm-block-qapi-Introduce-BlockGraphInfo.patch [bz#1860292] - kvm-block-qapi-Add-indentation-to-bdrv_node_info_dump.patch [bz#1860292] - kvm-iotests-Filter-child-node-information.patch [bz#1860292] - kvm-iotests-106-214-308-Read-only-one-size-line.patch [bz#1860292] - kvm-qemu-img-Let-info-print-block-graph.patch [bz#1860292] - kvm-qemu-img-Change-info-key-names-for-protocol-nodes.patch [bz#1860292] - kvm-Revert-vhost-user-Monitor-slave-channel-in-vhost_use.patch [bz#2155173] - kvm-Revert-vhost-user-Introduce-nested-event-loop-in-vho.patch [bz#2155173] - kvm-virtio-rng-pci-fix-transitional-migration-compat-for.patch [bz#2162569] - Resolves: bz#2150180 (qemu-img finishes successfully while having errors in commit or bitmaps operations) - Resolves: bz#2165280 ([kvm-unit-tests] debug-wp-migration fails) - Resolves: bz#1860292 (RFE: add extent_size_hint information to qemu-img info) - Resolves: bz#2155173 ([vhost-user] unable to start vhost net: 71: falling back on userspace) - Resolves: bz#2162569 ([transitional device][virtio-rng-pci-transitional]Stable Guest ABI failed between RHEL 8.6 to RHEL 9.2)
This commit is contained in:
parent
9b81b4ad6b
commit
a6628605f7
140
kvm-Revert-vhost-user-Introduce-nested-event-loop-in-vho.patch
Normal file
140
kvm-Revert-vhost-user-Introduce-nested-event-loop-in-vho.patch
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
From 0c19fb7c4a22a30830152b224b2e66963f829a7a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Kurz <groug@kaod.org>
|
||||||
|
Date: Thu, 19 Jan 2023 18:24:24 +0100
|
||||||
|
Subject: [PATCH 19/20] Revert "vhost-user: Introduce nested event loop in
|
||||||
|
vhost_user_read()"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
RH-Author: Laurent Vivier <lvivier@redhat.com>
|
||||||
|
RH-MergeRequest: 146: Fix vhost-user with dpdk
|
||||||
|
RH-Bugzilla: 2155173
|
||||||
|
RH-Acked-by: Cindy Lu <lulu@redhat.com>
|
||||||
|
RH-Acked-by: Greg Kurz (RH) <gkurz@redhat.com>
|
||||||
|
RH-Acked-by: Eugenio Pérez <eperezma@redhat.com>
|
||||||
|
RH-Commit: [2/2] 9b67041f92f29f70b7ccb41d8087801e4e4e38af (lvivier/qemu-kvm-centos)
|
||||||
|
|
||||||
|
This reverts commit a7f523c7d114d445c5d83aecdba3efc038e5a692.
|
||||||
|
|
||||||
|
The nested event loop is broken by design. It's only user was removed.
|
||||||
|
Drop the code as well so that nobody ever tries to use it again.
|
||||||
|
|
||||||
|
I had to fix a couple of trivial conflicts around return values because
|
||||||
|
of 025faa872bcf ("vhost-user: stick to -errno error return convention").
|
||||||
|
|
||||||
|
Signed-off-by: Greg Kurz <groug@kaod.org>
|
||||||
|
Message-Id: <20230119172424.478268-3-groug@kaod.org>
|
||||||
|
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||||
|
(cherry picked from commit 4382138f642f69fdbc79ebf4e93d84be8061191f)
|
||||||
|
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
||||||
|
---
|
||||||
|
hw/virtio/vhost-user.c | 65 ++++--------------------------------------
|
||||||
|
1 file changed, 5 insertions(+), 60 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
|
||||||
|
index 0ac00eb901..7cb49c50f9 100644
|
||||||
|
--- a/hw/virtio/vhost-user.c
|
||||||
|
+++ b/hw/virtio/vhost-user.c
|
||||||
|
@@ -305,19 +305,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-struct vhost_user_read_cb_data {
|
||||||
|
- struct vhost_dev *dev;
|
||||||
|
- VhostUserMsg *msg;
|
||||||
|
- GMainLoop *loop;
|
||||||
|
- int ret;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
|
||||||
|
- gpointer opaque)
|
||||||
|
+static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
{
|
||||||
|
- struct vhost_user_read_cb_data *data = opaque;
|
||||||
|
- struct vhost_dev *dev = data->dev;
|
||||||
|
- VhostUserMsg *msg = data->msg;
|
||||||
|
struct vhost_user *u = dev->opaque;
|
||||||
|
CharBackend *chr = u->user->chr;
|
||||||
|
uint8_t *p = (uint8_t *) msg;
|
||||||
|
@@ -325,8 +314,7 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
|
||||||
|
|
||||||
|
r = vhost_user_read_header(dev, msg);
|
||||||
|
if (r < 0) {
|
||||||
|
- data->ret = r;
|
||||||
|
- goto end;
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate message size is sane */
|
||||||
|
@@ -334,8 +322,7 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
|
||||||
|
error_report("Failed to read msg header."
|
||||||
|
" Size %d exceeds the maximum %zu.", msg->hdr.size,
|
||||||
|
VHOST_USER_PAYLOAD_SIZE);
|
||||||
|
- data->ret = -EPROTO;
|
||||||
|
- goto end;
|
||||||
|
+ return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->hdr.size) {
|
||||||
|
@@ -346,53 +333,11 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition,
|
||||||
|
int saved_errno = errno;
|
||||||
|
error_report("Failed to read msg payload."
|
||||||
|
" Read %d instead of %d.", r, msg->hdr.size);
|
||||||
|
- data->ret = r < 0 ? -saved_errno : -EIO;
|
||||||
|
- goto end;
|
||||||
|
+ return r < 0 ? -saved_errno : -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-end:
|
||||||
|
- g_main_loop_quit(data->loop);
|
||||||
|
- return G_SOURCE_REMOVE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
-{
|
||||||
|
- struct vhost_user *u = dev->opaque;
|
||||||
|
- CharBackend *chr = u->user->chr;
|
||||||
|
- GMainContext *prev_ctxt = chr->chr->gcontext;
|
||||||
|
- GMainContext *ctxt = g_main_context_new();
|
||||||
|
- GMainLoop *loop = g_main_loop_new(ctxt, FALSE);
|
||||||
|
- struct vhost_user_read_cb_data data = {
|
||||||
|
- .dev = dev,
|
||||||
|
- .loop = loop,
|
||||||
|
- .msg = msg,
|
||||||
|
- .ret = 0
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * We want to be able to monitor the slave channel fd while waiting
|
||||||
|
- * for chr I/O. This requires an event loop, but we can't nest the
|
||||||
|
- * one to which chr is currently attached : its fd handlers might not
|
||||||
|
- * be prepared for re-entrancy. So we create a new one and switch chr
|
||||||
|
- * to use it.
|
||||||
|
- */
|
||||||
|
- qemu_chr_be_update_read_handlers(chr->chr, ctxt);
|
||||||
|
- qemu_chr_fe_add_watch(chr, G_IO_IN | G_IO_HUP, vhost_user_read_cb, &data);
|
||||||
|
-
|
||||||
|
- g_main_loop_run(loop);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Restore the previous event loop context. This also destroys/recreates
|
||||||
|
- * event sources : this guarantees that all pending events in the original
|
||||||
|
- * context that have been processed by the nested loop are purged.
|
||||||
|
- */
|
||||||
|
- qemu_chr_be_update_read_handlers(chr->chr, prev_ctxt);
|
||||||
|
-
|
||||||
|
- g_main_loop_unref(loop);
|
||||||
|
- g_main_context_unref(ctxt);
|
||||||
|
-
|
||||||
|
- return data.ret;
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_message_reply(struct vhost_dev *dev,
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
143
kvm-Revert-vhost-user-Monitor-slave-channel-in-vhost_use.patch
Normal file
143
kvm-Revert-vhost-user-Monitor-slave-channel-in-vhost_use.patch
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
From 9fb47ad317ad8cdda9960190d499ad6c3a9817f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Kurz <groug@kaod.org>
|
||||||
|
Date: Thu, 19 Jan 2023 18:24:23 +0100
|
||||||
|
Subject: [PATCH 18/20] Revert "vhost-user: Monitor slave channel in
|
||||||
|
vhost_user_read()"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
RH-Author: Laurent Vivier <lvivier@redhat.com>
|
||||||
|
RH-MergeRequest: 146: Fix vhost-user with dpdk
|
||||||
|
RH-Bugzilla: 2155173
|
||||||
|
RH-Acked-by: Cindy Lu <lulu@redhat.com>
|
||||||
|
RH-Acked-by: Greg Kurz (RH) <gkurz@redhat.com>
|
||||||
|
RH-Acked-by: Eugenio Pérez <eperezma@redhat.com>
|
||||||
|
RH-Commit: [1/2] c583a7f121ca9c93c9a2ad17bf0ccf5c1241dc99 (lvivier/qemu-kvm-centos)
|
||||||
|
|
||||||
|
This reverts commit db8a3772e300c1a656331a92da0785d81667dc81.
|
||||||
|
|
||||||
|
Motivation : this is breaking vhost-user with DPDK as reported in [0].
|
||||||
|
|
||||||
|
Received unexpected msg type. Expected 22 received 40
|
||||||
|
Fail to update device iotlb
|
||||||
|
Received unexpected msg type. Expected 40 received 22
|
||||||
|
Received unexpected msg type. Expected 22 received 11
|
||||||
|
Fail to update device iotlb
|
||||||
|
Received unexpected msg type. Expected 11 received 22
|
||||||
|
vhost VQ 1 ring restore failed: -71: Protocol error (71)
|
||||||
|
Received unexpected msg type. Expected 22 received 11
|
||||||
|
Fail to update device iotlb
|
||||||
|
Received unexpected msg type. Expected 11 received 22
|
||||||
|
vhost VQ 0 ring restore failed: -71: Protocol error (71)
|
||||||
|
unable to start vhost net: 71: falling back on userspace virtio
|
||||||
|
|
||||||
|
The failing sequence that leads to the first error is :
|
||||||
|
- QEMU sends a VHOST_USER_GET_STATUS (40) request to DPDK on the master
|
||||||
|
socket
|
||||||
|
- QEMU starts a nested event loop in order to wait for the
|
||||||
|
VHOST_USER_GET_STATUS response and to be able to process messages from
|
||||||
|
the slave channel
|
||||||
|
- DPDK sends a couple of legitimate IOTLB miss messages on the slave
|
||||||
|
channel
|
||||||
|
- QEMU processes each IOTLB request and sends VHOST_USER_IOTLB_MSG (22)
|
||||||
|
updates on the master socket
|
||||||
|
- QEMU assumes to receive a response for the latest VHOST_USER_IOTLB_MSG
|
||||||
|
but it gets the response for the VHOST_USER_GET_STATUS instead
|
||||||
|
|
||||||
|
The subsequent errors have the same root cause : the nested event loop
|
||||||
|
breaks the order by design. It lures QEMU to expect responses to the
|
||||||
|
latest message sent on the master socket to arrive first.
|
||||||
|
|
||||||
|
Since this was only needed for DAX enablement which is still not merged
|
||||||
|
upstream, just drop the code for now. A working solution will have to
|
||||||
|
be merged later on. Likely protect the master socket with a mutex
|
||||||
|
and service the slave channel with a separate thread, as discussed with
|
||||||
|
Maxime in the mail thread below.
|
||||||
|
|
||||||
|
[0] https://lore.kernel.org/qemu-devel/43145ede-89dc-280e-b953-6a2b436de395@redhat.com/
|
||||||
|
|
||||||
|
Reported-by: Yanghang Liu <yanghliu@redhat.com>
|
||||||
|
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2155173
|
||||||
|
Signed-off-by: Greg Kurz <groug@kaod.org>
|
||||||
|
Message-Id: <20230119172424.478268-2-groug@kaod.org>
|
||||||
|
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
Acked-by: Maxime Coquelin <maxime.coquelin@redhat.com>
|
||||||
|
(cherry picked from commit f340a59d5a852d75ae34555723694c7e8eafbd0c)
|
||||||
|
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
|
||||||
|
---
|
||||||
|
hw/virtio/vhost-user.c | 35 +++--------------------------------
|
||||||
|
1 file changed, 3 insertions(+), 32 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
|
||||||
|
index 8f635844af..0ac00eb901 100644
|
||||||
|
--- a/hw/virtio/vhost-user.c
|
||||||
|
+++ b/hw/virtio/vhost-user.c
|
||||||
|
@@ -356,35 +356,6 @@ end:
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static gboolean slave_read(QIOChannel *ioc, GIOCondition condition,
|
||||||
|
- gpointer opaque);
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * This updates the read handler to use a new event loop context.
|
||||||
|
- * Event sources are removed from the previous context : this ensures
|
||||||
|
- * that events detected in the previous context are purged. They will
|
||||||
|
- * be re-detected and processed in the new context.
|
||||||
|
- */
|
||||||
|
-static void slave_update_read_handler(struct vhost_dev *dev,
|
||||||
|
- GMainContext *ctxt)
|
||||||
|
-{
|
||||||
|
- struct vhost_user *u = dev->opaque;
|
||||||
|
-
|
||||||
|
- if (!u->slave_ioc) {
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (u->slave_src) {
|
||||||
|
- g_source_destroy(u->slave_src);
|
||||||
|
- g_source_unref(u->slave_src);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- u->slave_src = qio_channel_add_watch_source(u->slave_ioc,
|
||||||
|
- G_IO_IN | G_IO_HUP,
|
||||||
|
- slave_read, dev, NULL,
|
||||||
|
- ctxt);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
{
|
||||||
|
struct vhost_user *u = dev->opaque;
|
||||||
|
@@ -406,7 +377,6 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
* be prepared for re-entrancy. So we create a new one and switch chr
|
||||||
|
* to use it.
|
||||||
|
*/
|
||||||
|
- slave_update_read_handler(dev, ctxt);
|
||||||
|
qemu_chr_be_update_read_handlers(chr->chr, ctxt);
|
||||||
|
qemu_chr_fe_add_watch(chr, G_IO_IN | G_IO_HUP, vhost_user_read_cb, &data);
|
||||||
|
|
||||||
|
@@ -418,7 +388,6 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
|
||||||
|
* context that have been processed by the nested loop are purged.
|
||||||
|
*/
|
||||||
|
qemu_chr_be_update_read_handlers(chr->chr, prev_ctxt);
|
||||||
|
- slave_update_read_handler(dev, NULL);
|
||||||
|
|
||||||
|
g_main_loop_unref(loop);
|
||||||
|
g_main_context_unref(ctxt);
|
||||||
|
@@ -1802,7 +1771,9 @@ static int vhost_setup_slave_channel(struct vhost_dev *dev)
|
||||||
|
return -ECONNREFUSED;
|
||||||
|
}
|
||||||
|
u->slave_ioc = ioc;
|
||||||
|
- slave_update_read_handler(dev, NULL);
|
||||||
|
+ u->slave_src = qio_channel_add_watch_source(u->slave_ioc,
|
||||||
|
+ G_IO_IN | G_IO_HUP,
|
||||||
|
+ slave_read, dev, NULL, NULL);
|
||||||
|
|
||||||
|
if (reply_supported) {
|
||||||
|
msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
From ab68e13b7628f2348d41a4518a92508542af712f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Eric Auger <eric.auger@redhat.com>
|
||||||
|
Date: Fri, 3 Feb 2023 18:15:10 +0100
|
||||||
|
Subject: [PATCH 05/20] accel/tcg: Test CPUJumpCache in tb_jmp_cache_clear_page
|
||||||
|
|
||||||
|
RH-Author: Eric Auger <eric.auger@redhat.com>
|
||||||
|
RH-MergeRequest: 144: accel/tcg: Test CPUJumpCache in tb_jmp_cache_clear_page
|
||||||
|
RH-Bugzilla: 2165280
|
||||||
|
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
|
||||||
|
RH-Acked-by: Gavin Shan <gshan@redhat.com>
|
||||||
|
RH-Acked-by: Shaoqin Huang <None>
|
||||||
|
RH-Commit: [1/1] 5b0863c34ba06c01c4e343d1ecd72402779c7de3 (eauger1/centos-qemu-kvm)
|
||||||
|
|
||||||
|
Bugzilla: https://bugzilla.redhat.com/2165280
|
||||||
|
Upstream: yes
|
||||||
|
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=50530041
|
||||||
|
Test: 'kvm unit test ./run_tests.sh -g debug' does not SIGSEV anymore
|
||||||
|
|
||||||
|
After commit 4e4fa6c12d ("accel/tcg: Complete cpu initialization
|
||||||
|
before registration"), it looks the CPUJumpCache pointer can be NULL.
|
||||||
|
This causes a SIGSEV when running debug-wp-migration kvm unit test.
|
||||||
|
|
||||||
|
At the first place it should be clarified why this TCG code is called
|
||||||
|
with KVM acceleration. This may hide another bug.
|
||||||
|
|
||||||
|
Fixes: 4e4fa6c12d ("accel/tcg: Complete cpu initialization before registration")
|
||||||
|
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||||
|
Message-Id: <20230203171510.2867451-1-eric.auger@redhat.com>
|
||||||
|
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
|
||||||
|
(cherry picked from commit 99ab4d500af638ba3ebb20e8aa89d72201b70860)
|
||||||
|
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||||
|
---
|
||||||
|
accel/tcg/cputlb.c | 7 ++++++-
|
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
|
||||||
|
index 6f1c00682b..4244b0e4e3 100644
|
||||||
|
--- a/accel/tcg/cputlb.c
|
||||||
|
+++ b/accel/tcg/cputlb.c
|
||||||
|
@@ -100,9 +100,14 @@ static void tlb_window_reset(CPUTLBDesc *desc, int64_t ns,
|
||||||
|
|
||||||
|
static void tb_jmp_cache_clear_page(CPUState *cpu, target_ulong page_addr)
|
||||||
|
{
|
||||||
|
- int i, i0 = tb_jmp_cache_hash_page(page_addr);
|
||||||
|
CPUJumpCache *jc = cpu->tb_jmp_cache;
|
||||||
|
+ int i, i0;
|
||||||
|
|
||||||
|
+ if (unlikely(!jc)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ i0 = tb_jmp_cache_hash_page(page_addr);
|
||||||
|
for (i = 0; i < TB_JMP_PAGE_SIZE; i++) {
|
||||||
|
qatomic_set(&jc->array[i0 + i].tb, NULL);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
132
kvm-block-Improve-empty-format-specific-info-dump.patch
Normal file
132
kvm-block-Improve-empty-format-specific-info-dump.patch
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
From 074c89b05dae971c7118cb769fd34e22135c8f4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:53 +0200
|
||||||
|
Subject: [PATCH 06/20] block: Improve empty format-specific info dump
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [1/12] be551e83f426e620e673302198b51368bfd324ce (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
When a block driver supports obtaining format-specific information, but
|
||||||
|
that object only contains optional fields, it is possible that none of
|
||||||
|
them are present, so that dump_qobject() (called by
|
||||||
|
bdrv_image_info_specific_dump()) will not print anything.
|
||||||
|
|
||||||
|
The callers of bdrv_image_info_specific_dump() put a header above this
|
||||||
|
information ("Format specific information:\n"), which will look strange
|
||||||
|
when there is nothing below. Modify bdrv_image_info_specific_dump() to
|
||||||
|
print this header instead of its callers, and only if there is indeed
|
||||||
|
something to be printed.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-2-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 3716470b24f0f63090d59bcf28ad8fe6fb7835bd)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/qapi.c | 41 +++++++++++++++++++++++++++++++++++++----
|
||||||
|
include/block/qapi.h | 3 ++-
|
||||||
|
qemu-io-cmds.c | 4 ++--
|
||||||
|
3 files changed, 41 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index cf557e3aea..51202b470a 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -777,7 +777,35 @@ static void dump_qdict(int indentation, QDict *dict)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
|
||||||
|
+/*
|
||||||
|
+ * Return whether dumping the given QObject with dump_qobject() would
|
||||||
|
+ * yield an empty dump, i.e. not print anything.
|
||||||
|
+ */
|
||||||
|
+static bool qobject_is_empty_dump(const QObject *obj)
|
||||||
|
+{
|
||||||
|
+ switch (qobject_type(obj)) {
|
||||||
|
+ case QTYPE_QNUM:
|
||||||
|
+ case QTYPE_QSTRING:
|
||||||
|
+ case QTYPE_QBOOL:
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ case QTYPE_QDICT:
|
||||||
|
+ return qdict_size(qobject_to(QDict, obj)) == 0;
|
||||||
|
+
|
||||||
|
+ case QTYPE_QLIST:
|
||||||
|
+ return qlist_empty(qobject_to(QList, obj));
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ abort();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Dumps the given ImageInfoSpecific object in a human-readable form,
|
||||||
|
+ * prepending an optional prefix if the dump is not empty.
|
||||||
|
+ */
|
||||||
|
+void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
+ const char *prefix)
|
||||||
|
{
|
||||||
|
QObject *obj, *data;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
@@ -785,7 +813,12 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
|
||||||
|
visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
|
||||||
|
visit_complete(v, &obj);
|
||||||
|
data = qdict_get(qobject_to(QDict, obj), "data");
|
||||||
|
- dump_qobject(1, data);
|
||||||
|
+ if (!qobject_is_empty_dump(data)) {
|
||||||
|
+ if (prefix) {
|
||||||
|
+ qemu_printf("%s", prefix);
|
||||||
|
+ }
|
||||||
|
+ dump_qobject(1, data);
|
||||||
|
+ }
|
||||||
|
qobject_unref(obj);
|
||||||
|
visit_free(v);
|
||||||
|
}
|
||||||
|
@@ -866,7 +899,7 @@ void bdrv_image_info_dump(ImageInfo *info)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->has_format_specific) {
|
||||||
|
- qemu_printf("Format specific information:\n");
|
||||||
|
- bdrv_image_info_specific_dump(info->format_specific);
|
||||||
|
+ bdrv_image_info_specific_dump(info->format_specific,
|
||||||
|
+ "Format specific information:\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index 22c7807c89..c09859ea78 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -40,6 +40,7 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
|
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
-void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec);
|
||||||
|
+void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
+ const char *prefix);
|
||||||
|
void bdrv_image_info_dump(ImageInfo *info);
|
||||||
|
#endif
|
||||||
|
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
||||||
|
index 952dc940f1..f4a374528e 100644
|
||||||
|
--- a/qemu-io-cmds.c
|
||||||
|
+++ b/qemu-io-cmds.c
|
||||||
|
@@ -1825,8 +1825,8 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
if (spec_info) {
|
||||||
|
- printf("Format specific information:\n");
|
||||||
|
- bdrv_image_info_specific_dump(spec_info);
|
||||||
|
+ bdrv_image_info_specific_dump(spec_info,
|
||||||
|
+ "Format specific information:\n");
|
||||||
|
qapi_free_ImageInfoSpecific(spec_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
246
kvm-block-Split-BlockNodeInfo-off-of-ImageInfo.patch
Normal file
246
kvm-block-Split-BlockNodeInfo-off-of-ImageInfo.patch
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
From 54e290df4bc1c9e83be7357caed6a2b1ba4f21f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:56 +0200
|
||||||
|
Subject: [PATCH 09/20] block: Split BlockNodeInfo off of ImageInfo
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [4/12] fc8d69d549bb9a929db218b91697ee3ae95c1ff6 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
ImageInfo sometimes contains flat information, and sometimes it does
|
||||||
|
not. Split off a BlockNodeInfo struct, which only contains information
|
||||||
|
about a single node and has no link to the backing image.
|
||||||
|
|
||||||
|
We do this so we can extend BlockNodeInfo to a BlockGraphInfo struct,
|
||||||
|
which has links to all child nodes, not just the backing node. It would
|
||||||
|
be strange to base BlockGraphInfo on ImageInfo, because then this
|
||||||
|
extended struct would have two links to the backing node (one in
|
||||||
|
BlockGraphInfo as one of all the child links, and one in ImageInfo).
|
||||||
|
|
||||||
|
Furthermore, it is quite common to ignore the backing-image field
|
||||||
|
altogether: bdrv_query_image_info() does not set it, and
|
||||||
|
bdrv_image_info_dump() does not evaluate it. That signals that we
|
||||||
|
should have different structs for describing a single node and one that
|
||||||
|
has a link to the backing image.
|
||||||
|
|
||||||
|
Still, bdrv_query_image_info() and bdrv_image_info_dump() are not
|
||||||
|
changed too much in this patch. Follow-up patches will handle them.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-5-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit a2085f8909377b6df738f6c3f7ee6db4d16da8f7)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/qapi.c | 86 ++++++++++++++++++++++++++++++++------------
|
||||||
|
include/block/qapi.h | 3 ++
|
||||||
|
qapi/block-core.json | 24 +++++++++----
|
||||||
|
3 files changed, 85 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index 51202b470a..e5022b4481 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -241,30 +241,18 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * bdrv_query_image_info:
|
||||||
|
- * @bs: block device to examine
|
||||||
|
- * @p_info: location to store image information
|
||||||
|
- * @errp: location to store error information
|
||||||
|
- *
|
||||||
|
- * Store "flat" image information in @p_info.
|
||||||
|
- *
|
||||||
|
- * "Flat" means it does *not* query backing image information,
|
||||||
|
- * i.e. (*pinfo)->has_backing_image will be set to false and
|
||||||
|
- * (*pinfo)->backing_image to NULL even when the image does in fact have
|
||||||
|
- * a backing image.
|
||||||
|
- *
|
||||||
|
- * @p_info will be set only on success. On error, store error in @errp.
|
||||||
|
+ * Helper function for other query info functions. Store information about @bs
|
||||||
|
+ * in @info, setting @errp on error.
|
||||||
|
*/
|
||||||
|
-void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
- ImageInfo **p_info,
|
||||||
|
- Error **errp)
|
||||||
|
+static void bdrv_do_query_node_info(BlockDriverState *bs,
|
||||||
|
+ BlockNodeInfo *info,
|
||||||
|
+ Error **errp)
|
||||||
|
{
|
||||||
|
int64_t size;
|
||||||
|
const char *backing_filename;
|
||||||
|
BlockDriverInfo bdi;
|
||||||
|
int ret;
|
||||||
|
Error *err = NULL;
|
||||||
|
- ImageInfo *info;
|
||||||
|
|
||||||
|
aio_context_acquire(bdrv_get_aio_context(bs));
|
||||||
|
|
||||||
|
@@ -277,7 +265,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
|
||||||
|
bdrv_refresh_filename(bs);
|
||||||
|
|
||||||
|
- info = g_new0(ImageInfo, 1);
|
||||||
|
info->filename = g_strdup(bs->filename);
|
||||||
|
info->format = g_strdup(bdrv_get_format_name(bs));
|
||||||
|
info->virtual_size = size;
|
||||||
|
@@ -298,7 +285,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
info->format_specific = bdrv_get_specific_info(bs, &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
- qapi_free_ImageInfo(info);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
info->has_format_specific = info->format_specific != NULL;
|
||||||
|
@@ -339,16 +325,72 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error_propagate(errp, err);
|
||||||
|
- qapi_free_ImageInfo(info);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- *p_info = info;
|
||||||
|
-
|
||||||
|
out:
|
||||||
|
aio_context_release(bdrv_get_aio_context(bs));
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * bdrv_query_block_node_info:
|
||||||
|
+ * @bs: block node to examine
|
||||||
|
+ * @p_info: location to store node information
|
||||||
|
+ * @errp: location to store error information
|
||||||
|
+ *
|
||||||
|
+ * Store image information about @bs in @p_info.
|
||||||
|
+ *
|
||||||
|
+ * @p_info will be set only on success. On error, store error in @errp.
|
||||||
|
+ */
|
||||||
|
+void bdrv_query_block_node_info(BlockDriverState *bs,
|
||||||
|
+ BlockNodeInfo **p_info,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ BlockNodeInfo *info;
|
||||||
|
+ ERRP_GUARD();
|
||||||
|
+
|
||||||
|
+ info = g_new0(BlockNodeInfo, 1);
|
||||||
|
+ bdrv_do_query_node_info(bs, info, errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ qapi_free_BlockNodeInfo(info);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *p_info = info;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * bdrv_query_image_info:
|
||||||
|
+ * @bs: block node to examine
|
||||||
|
+ * @p_info: location to store image information
|
||||||
|
+ * @errp: location to store error information
|
||||||
|
+ *
|
||||||
|
+ * Store "flat" image information in @p_info.
|
||||||
|
+ *
|
||||||
|
+ * "Flat" means it does *not* query backing image information,
|
||||||
|
+ * i.e. (*pinfo)->has_backing_image will be set to false and
|
||||||
|
+ * (*pinfo)->backing_image to NULL even when the image does in fact have
|
||||||
|
+ * a backing image.
|
||||||
|
+ *
|
||||||
|
+ * @p_info will be set only on success. On error, store error in @errp.
|
||||||
|
+ */
|
||||||
|
+void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
+ ImageInfo **p_info,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ ImageInfo *info;
|
||||||
|
+ ERRP_GUARD();
|
||||||
|
+
|
||||||
|
+ info = g_new0(ImageInfo, 1);
|
||||||
|
+ bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ qapi_free_ImageInfo(info);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *p_info = info;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* @p_info will be set only on success. */
|
||||||
|
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
|
||||||
|
Error **errp)
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index c09859ea78..c7de4e3fa9 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -35,6 +35,9 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||||
|
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
|
||||||
|
SnapshotInfoList **p_list,
|
||||||
|
Error **errp);
|
||||||
|
+void bdrv_query_block_node_info(BlockDriverState *bs,
|
||||||
|
+ BlockNodeInfo **p_info,
|
||||||
|
+ Error **errp);
|
||||||
|
void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
ImageInfo **p_info,
|
||||||
|
Error **errp);
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 4b9365167f..7720da0498 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -251,7 +251,7 @@
|
||||||
|
} }
|
||||||
|
|
||||||
|
##
|
||||||
|
-# @ImageInfo:
|
||||||
|
+# @BlockNodeInfo:
|
||||||
|
#
|
||||||
|
# Information about a QEMU image file
|
||||||
|
#
|
||||||
|
@@ -279,22 +279,34 @@
|
||||||
|
#
|
||||||
|
# @snapshots: list of VM snapshots
|
||||||
|
#
|
||||||
|
-# @backing-image: info of the backing image (since 1.6)
|
||||||
|
-#
|
||||||
|
# @format-specific: structure supplying additional format-specific
|
||||||
|
# information (since 1.7)
|
||||||
|
#
|
||||||
|
-# Since: 1.3
|
||||||
|
+# Since: 8.0
|
||||||
|
##
|
||||||
|
-{ 'struct': 'ImageInfo',
|
||||||
|
+{ 'struct': 'BlockNodeInfo',
|
||||||
|
'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',
|
||||||
|
'*actual-size': 'int', 'virtual-size': 'int',
|
||||||
|
'*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
|
||||||
|
'*backing-filename': 'str', '*full-backing-filename': 'str',
|
||||||
|
'*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
|
||||||
|
- '*backing-image': 'ImageInfo',
|
||||||
|
'*format-specific': 'ImageInfoSpecific' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @ImageInfo:
|
||||||
|
+#
|
||||||
|
+# Information about a QEMU image file, and potentially its backing image
|
||||||
|
+#
|
||||||
|
+# @backing-image: info of the backing image
|
||||||
|
+#
|
||||||
|
+# Since: 1.3
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'ImageInfo',
|
||||||
|
+ 'base': 'BlockNodeInfo',
|
||||||
|
+ 'data': {
|
||||||
|
+ '*backing-image': 'ImageInfo'
|
||||||
|
+ } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ImageCheck:
|
||||||
|
#
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
145
kvm-block-file-Add-file-specific-image-info.patch
Normal file
145
kvm-block-file-Add-file-specific-image-info.patch
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
From 4af86458d6bea2a6e15fd57d4d4bbe88e35f7e72 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:54 +0200
|
||||||
|
Subject: [PATCH 07/20] block/file: Add file-specific image info
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [2/12] d8cc351d6c16c41b2000e41dc555f13093a9edce (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
Add some (optional) information that the file driver can provide for
|
||||||
|
image files, namely the extent size hint.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-3-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 7f36a50ab4e7d39369cac67be4ba9d6ee4081dc0)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/file-posix.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
qapi/block-core.json | 26 ++++++++++++++++++++++++--
|
||||||
|
2 files changed, 54 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/file-posix.c b/block/file-posix.c
|
||||||
|
index b9647c5ffc..df3da79aed 100644
|
||||||
|
--- a/block/file-posix.c
|
||||||
|
+++ b/block/file-posix.c
|
||||||
|
@@ -3095,6 +3095,34 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static ImageInfoSpecific *raw_get_specific_info(BlockDriverState *bs,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ ImageInfoSpecificFile *file_info = g_new0(ImageInfoSpecificFile, 1);
|
||||||
|
+ ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
|
||||||
|
+
|
||||||
|
+ *spec_info = (ImageInfoSpecific){
|
||||||
|
+ .type = IMAGE_INFO_SPECIFIC_KIND_FILE,
|
||||||
|
+ .u.file.data = file_info,
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+#ifdef FS_IOC_FSGETXATTR
|
||||||
|
+ {
|
||||||
|
+ BDRVRawState *s = bs->opaque;
|
||||||
|
+ struct fsxattr attr;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = ioctl(s->fd, FS_IOC_FSGETXATTR, &attr);
|
||||||
|
+ if (!ret && attr.fsx_extsize != 0) {
|
||||||
|
+ file_info->has_extent_size_hint = true;
|
||||||
|
+ file_info->extent_size_hint = attr.fsx_extsize;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return spec_info;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static BlockStatsSpecificFile get_blockstats_specific_file(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
@@ -3328,6 +3356,7 @@ BlockDriver bdrv_file = {
|
||||||
|
.bdrv_co_truncate = raw_co_truncate,
|
||||||
|
.bdrv_getlength = raw_getlength,
|
||||||
|
.bdrv_get_info = raw_get_info,
|
||||||
|
+ .bdrv_get_specific_info = raw_get_specific_info,
|
||||||
|
.bdrv_get_allocated_file_size
|
||||||
|
= raw_get_allocated_file_size,
|
||||||
|
.bdrv_get_specific_stats = raw_get_specific_stats,
|
||||||
|
@@ -3700,6 +3729,7 @@ static BlockDriver bdrv_host_device = {
|
||||||
|
.bdrv_co_truncate = raw_co_truncate,
|
||||||
|
.bdrv_getlength = raw_getlength,
|
||||||
|
.bdrv_get_info = raw_get_info,
|
||||||
|
+ .bdrv_get_specific_info = raw_get_specific_info,
|
||||||
|
.bdrv_get_allocated_file_size
|
||||||
|
= raw_get_allocated_file_size,
|
||||||
|
.bdrv_get_specific_stats = hdev_get_specific_stats,
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 95ac4fa634..f5d822cbd6 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -139,16 +139,29 @@
|
||||||
|
'*encryption-format': 'RbdImageEncryptionFormat'
|
||||||
|
} }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @ImageInfoSpecificFile:
|
||||||
|
+#
|
||||||
|
+# @extent-size-hint: Extent size hint (if available)
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'ImageInfoSpecificFile',
|
||||||
|
+ 'data': {
|
||||||
|
+ '*extent-size-hint': 'size'
|
||||||
|
+ } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificKind:
|
||||||
|
#
|
||||||
|
# @luks: Since 2.7
|
||||||
|
# @rbd: Since 6.1
|
||||||
|
+# @file: Since 8.0
|
||||||
|
#
|
||||||
|
# Since: 1.7
|
||||||
|
##
|
||||||
|
{ 'enum': 'ImageInfoSpecificKind',
|
||||||
|
- 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd' ] }
|
||||||
|
+ 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd', 'file' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificQCow2Wrapper:
|
||||||
|
@@ -185,6 +198,14 @@
|
||||||
|
{ 'struct': 'ImageInfoSpecificRbdWrapper',
|
||||||
|
'data': { 'data': 'ImageInfoSpecificRbd' } }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @ImageInfoSpecificFileWrapper:
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'ImageInfoSpecificFileWrapper',
|
||||||
|
+ 'data': { 'data': 'ImageInfoSpecificFile' } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecific:
|
||||||
|
#
|
||||||
|
@@ -199,7 +220,8 @@
|
||||||
|
'qcow2': 'ImageInfoSpecificQCow2Wrapper',
|
||||||
|
'vmdk': 'ImageInfoSpecificVmdkWrapper',
|
||||||
|
'luks': 'ImageInfoSpecificLUKSWrapper',
|
||||||
|
- 'rbd': 'ImageInfoSpecificRbdWrapper'
|
||||||
|
+ 'rbd': 'ImageInfoSpecificRbdWrapper',
|
||||||
|
+ 'file': 'ImageInfoSpecificFileWrapper'
|
||||||
|
} }
|
||||||
|
|
||||||
|
##
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
206
kvm-block-qapi-Add-indentation-to-bdrv_node_info_dump.patch
Normal file
206
kvm-block-qapi-Add-indentation-to-bdrv_node_info_dump.patch
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
From c8c282c2e1d74cfc5de6527f7e20dfc3e76b67ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:27:00 +0200
|
||||||
|
Subject: [PATCH 13/20] block/qapi: Add indentation to bdrv_node_info_dump()
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [8/12] d3a697e81ab9828457198075e5815a592363c725 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
In order to let qemu-img info present a block graph, add a parameter to
|
||||||
|
bdrv_node_info_dump() and bdrv_image_info_specific_dump() so that the
|
||||||
|
information of nodes below the root level can be given an indentation.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-9-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 76c9e9750d1bd580e8ed4465f6be3a986434e7c3)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/monitor/block-hmp-cmds.c | 2 +-
|
||||||
|
block/qapi.c | 47 +++++++++++++++++++---------------
|
||||||
|
include/block/qapi.h | 5 ++--
|
||||||
|
qemu-img.c | 2 +-
|
||||||
|
qemu-io-cmds.c | 3 ++-
|
||||||
|
5 files changed, 34 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||||
|
index aa37faa601..72824d4e2e 100644
|
||||||
|
--- a/block/monitor/block-hmp-cmds.c
|
||||||
|
+++ b/block/monitor/block-hmp-cmds.c
|
||||||
|
@@ -734,7 +734,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
||||||
|
monitor_printf(mon, "\nImages:\n");
|
||||||
|
image_info = inserted->image;
|
||||||
|
while (1) {
|
||||||
|
- bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
|
||||||
|
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0);
|
||||||
|
if (image_info->has_backing_image) {
|
||||||
|
image_info = image_info->backing_image;
|
||||||
|
} else {
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index f208c21ccf..3e35603f0c 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -915,7 +915,8 @@ static bool qobject_is_empty_dump(const QObject *obj)
|
||||||
|
* prepending an optional prefix if the dump is not empty.
|
||||||
|
*/
|
||||||
|
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
- const char *prefix)
|
||||||
|
+ const char *prefix,
|
||||||
|
+ int indentation)
|
||||||
|
{
|
||||||
|
QObject *obj, *data;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
@@ -925,48 +926,51 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
data = qdict_get(qobject_to(QDict, obj), "data");
|
||||||
|
if (!qobject_is_empty_dump(data)) {
|
||||||
|
if (prefix) {
|
||||||
|
- qemu_printf("%s", prefix);
|
||||||
|
+ qemu_printf("%*s%s", indentation * 4, "", prefix);
|
||||||
|
}
|
||||||
|
- dump_qobject(1, data);
|
||||||
|
+ dump_qobject(indentation + 1, data);
|
||||||
|
}
|
||||||
|
qobject_unref(obj);
|
||||||
|
visit_free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void bdrv_node_info_dump(BlockNodeInfo *info)
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation)
|
||||||
|
{
|
||||||
|
char *size_buf, *dsize_buf;
|
||||||
|
+ g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
|
||||||
|
+
|
||||||
|
if (!info->has_actual_size) {
|
||||||
|
dsize_buf = g_strdup("unavailable");
|
||||||
|
} else {
|
||||||
|
dsize_buf = size_to_str(info->actual_size);
|
||||||
|
}
|
||||||
|
size_buf = size_to_str(info->virtual_size);
|
||||||
|
- qemu_printf("image: %s\n"
|
||||||
|
- "file format: %s\n"
|
||||||
|
- "virtual size: %s (%" PRId64 " bytes)\n"
|
||||||
|
- "disk size: %s\n",
|
||||||
|
- info->filename, info->format, size_buf,
|
||||||
|
- info->virtual_size,
|
||||||
|
- dsize_buf);
|
||||||
|
+ qemu_printf("%simage: %s\n"
|
||||||
|
+ "%sfile format: %s\n"
|
||||||
|
+ "%svirtual size: %s (%" PRId64 " bytes)\n"
|
||||||
|
+ "%sdisk size: %s\n",
|
||||||
|
+ ind_s, info->filename,
|
||||||
|
+ ind_s, info->format,
|
||||||
|
+ ind_s, size_buf, info->virtual_size,
|
||||||
|
+ ind_s, dsize_buf);
|
||||||
|
g_free(size_buf);
|
||||||
|
g_free(dsize_buf);
|
||||||
|
|
||||||
|
if (info->has_encrypted && info->encrypted) {
|
||||||
|
- qemu_printf("encrypted: yes\n");
|
||||||
|
+ qemu_printf("%sencrypted: yes\n", ind_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->has_cluster_size) {
|
||||||
|
- qemu_printf("cluster_size: %" PRId64 "\n",
|
||||||
|
- info->cluster_size);
|
||||||
|
+ qemu_printf("%scluster_size: %" PRId64 "\n",
|
||||||
|
+ ind_s, info->cluster_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->has_dirty_flag && info->dirty_flag) {
|
||||||
|
- qemu_printf("cleanly shut down: no\n");
|
||||||
|
+ qemu_printf("%scleanly shut down: no\n", ind_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->has_backing_filename) {
|
||||||
|
- qemu_printf("backing file: %s", info->backing_filename);
|
||||||
|
+ qemu_printf("%sbacking file: %s", ind_s, info->backing_filename);
|
||||||
|
if (!info->has_full_backing_filename) {
|
||||||
|
qemu_printf(" (cannot determine actual path)");
|
||||||
|
} else if (strcmp(info->backing_filename,
|
||||||
|
@@ -975,15 +979,16 @@ void bdrv_node_info_dump(BlockNodeInfo *info)
|
||||||
|
}
|
||||||
|
qemu_printf("\n");
|
||||||
|
if (info->has_backing_filename_format) {
|
||||||
|
- qemu_printf("backing file format: %s\n",
|
||||||
|
- info->backing_filename_format);
|
||||||
|
+ qemu_printf("%sbacking file format: %s\n",
|
||||||
|
+ ind_s, info->backing_filename_format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->has_snapshots) {
|
||||||
|
SnapshotInfoList *elem;
|
||||||
|
|
||||||
|
- qemu_printf("Snapshot list:\n");
|
||||||
|
+ qemu_printf("%sSnapshot list:\n", ind_s);
|
||||||
|
+ qemu_printf("%s", ind_s);
|
||||||
|
bdrv_snapshot_dump(NULL);
|
||||||
|
qemu_printf("\n");
|
||||||
|
|
||||||
|
@@ -1003,6 +1008,7 @@ void bdrv_node_info_dump(BlockNodeInfo *info)
|
||||||
|
|
||||||
|
pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
|
||||||
|
pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
|
||||||
|
+ qemu_printf("%s", ind_s);
|
||||||
|
bdrv_snapshot_dump(&sn);
|
||||||
|
qemu_printf("\n");
|
||||||
|
}
|
||||||
|
@@ -1010,6 +1016,7 @@ void bdrv_node_info_dump(BlockNodeInfo *info)
|
||||||
|
|
||||||
|
if (info->has_format_specific) {
|
||||||
|
bdrv_image_info_specific_dump(info->format_specific,
|
||||||
|
- "Format specific information:\n");
|
||||||
|
+ "Format specific information:\n",
|
||||||
|
+ indentation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index 196436020e..38855f2ae9 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -49,6 +49,7 @@ void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||||
|
|
||||||
|
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
- const char *prefix);
|
||||||
|
-void bdrv_node_info_dump(BlockNodeInfo *info);
|
||||||
|
+ const char *prefix,
|
||||||
|
+ int indentation);
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation);
|
||||||
|
#endif
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index 3b2ca3bbcb..30b4ea58bb 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -2859,7 +2859,7 @@ static void dump_human_image_info_list(BlockNodeInfoList *list)
|
||||||
|
}
|
||||||
|
delim = true;
|
||||||
|
|
||||||
|
- bdrv_node_info_dump(elem->value);
|
||||||
|
+ bdrv_node_info_dump(elem->value, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
|
||||||
|
index f4a374528e..fdcb89211b 100644
|
||||||
|
--- a/qemu-io-cmds.c
|
||||||
|
+++ b/qemu-io-cmds.c
|
||||||
|
@@ -1826,7 +1826,8 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
|
||||||
|
}
|
||||||
|
if (spec_info) {
|
||||||
|
bdrv_image_info_specific_dump(spec_info,
|
||||||
|
- "Format specific information:\n");
|
||||||
|
+ "Format specific information:\n",
|
||||||
|
+ 0);
|
||||||
|
qapi_free_ImageInfoSpecific(spec_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
155
kvm-block-qapi-Introduce-BlockGraphInfo.patch
Normal file
155
kvm-block-qapi-Introduce-BlockGraphInfo.patch
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
From 0044e3848b02ef6edba5961d1f4b6297d137d207 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:59 +0200
|
||||||
|
Subject: [PATCH 12/20] block/qapi: Introduce BlockGraphInfo
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [7/12] de47bac372cd552b812c774a2f35f95923af74ff (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
Introduce a new QAPI type BlockGraphInfo and an associated
|
||||||
|
bdrv_query_block_graph_info() function that recursively gathers
|
||||||
|
BlockNodeInfo objects through a block graph.
|
||||||
|
|
||||||
|
A follow-up patch is going to make "qemu-img info" use this to print
|
||||||
|
information about all nodes that are (usually implicitly) opened for a
|
||||||
|
given image file.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-8-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 6cab33997b91eb86e82a6a2ae58a24f835249d4a)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/qapi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
include/block/qapi.h | 3 +++
|
||||||
|
qapi/block-core.json | 35 ++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 86 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index 5d0a8d2ce3..f208c21ccf 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -411,6 +411,54 @@ fail:
|
||||||
|
qapi_free_ImageInfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * bdrv_query_block_graph_info:
|
||||||
|
+ * @bs: root node to start from
|
||||||
|
+ * @p_info: location to store image information
|
||||||
|
+ * @errp: location to store error information
|
||||||
|
+ *
|
||||||
|
+ * Store image information about the graph starting from @bs in @p_info.
|
||||||
|
+ *
|
||||||
|
+ * @p_info will be set only on success. On error, store error in @errp.
|
||||||
|
+ */
|
||||||
|
+void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||||
|
+ BlockGraphInfo **p_info,
|
||||||
|
+ Error **errp)
|
||||||
|
+{
|
||||||
|
+ BlockGraphInfo *info;
|
||||||
|
+ BlockChildInfoList **children_list_tail;
|
||||||
|
+ BdrvChild *c;
|
||||||
|
+ ERRP_GUARD();
|
||||||
|
+
|
||||||
|
+ info = g_new0(BlockGraphInfo, 1);
|
||||||
|
+ bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ children_list_tail = &info->children;
|
||||||
|
+
|
||||||
|
+ QLIST_FOREACH(c, &bs->children, next) {
|
||||||
|
+ BlockChildInfo *c_info;
|
||||||
|
+
|
||||||
|
+ c_info = g_new0(BlockChildInfo, 1);
|
||||||
|
+ QAPI_LIST_APPEND(children_list_tail, c_info);
|
||||||
|
+
|
||||||
|
+ c_info->name = g_strdup(c->name);
|
||||||
|
+ bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *p_info = info;
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+fail:
|
||||||
|
+ assert(*errp != NULL);
|
||||||
|
+ qapi_free_BlockGraphInfo(info);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* @p_info will be set only on success. */
|
||||||
|
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
|
||||||
|
Error **errp)
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index 2174bf8fa2..196436020e 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -43,6 +43,9 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
bool flat,
|
||||||
|
bool skip_implicit_filters,
|
||||||
|
Error **errp);
|
||||||
|
+void bdrv_query_block_graph_info(BlockDriverState *bs,
|
||||||
|
+ BlockGraphInfo **p_info,
|
||||||
|
+ Error **errp);
|
||||||
|
|
||||||
|
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 4cf2deeb6c..d703e0fb16 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -307,6 +307,41 @@
|
||||||
|
'*backing-image': 'ImageInfo'
|
||||||
|
} }
|
||||||
|
|
||||||
|
+##
|
||||||
|
+# @BlockChildInfo:
|
||||||
|
+#
|
||||||
|
+# Information about all nodes in the block graph starting at some node,
|
||||||
|
+# annotated with information about that node in relation to its parent.
|
||||||
|
+#
|
||||||
|
+# @name: Child name of the root node in the BlockGraphInfo struct, in its role
|
||||||
|
+# as the child of some undescribed parent node
|
||||||
|
+#
|
||||||
|
+# @info: Block graph information starting at this node
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockChildInfo',
|
||||||
|
+ 'data': {
|
||||||
|
+ 'name': 'str',
|
||||||
|
+ 'info': 'BlockGraphInfo'
|
||||||
|
+ } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
+# @BlockGraphInfo:
|
||||||
|
+#
|
||||||
|
+# Information about all nodes in a block (sub)graph in the form of BlockNodeInfo
|
||||||
|
+# data.
|
||||||
|
+# The base BlockNodeInfo struct contains the information for the (sub)graph's
|
||||||
|
+# root node.
|
||||||
|
+#
|
||||||
|
+# @children: Array of links to this node's child nodes' information
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'BlockGraphInfo',
|
||||||
|
+ 'base': 'BlockNodeInfo',
|
||||||
|
+ 'data': { 'children': ['BlockChildInfo'] } }
|
||||||
|
+
|
||||||
|
##
|
||||||
|
# @ImageCheck:
|
||||||
|
#
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
197
kvm-block-qapi-Let-bdrv_query_image_info-recurse.patch
Normal file
197
kvm-block-qapi-Let-bdrv_query_image_info-recurse.patch
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
From ae2c3df00d673d436fe4d8ec9103a3b76d7e6233 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:58 +0200
|
||||||
|
Subject: [PATCH 11/20] block/qapi: Let bdrv_query_image_info() recurse
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [6/12] 451a83fd682cd6dd6026c22974d18c2f12ee06e3 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
There is no real reason why bdrv_query_image_info() should generally not
|
||||||
|
recurse. The ImageInfo struct has a pointer to the backing image, so it
|
||||||
|
should generally be filled, unless the caller explicitly opts out.
|
||||||
|
|
||||||
|
This moves the recursing code from bdrv_block_device_info() into
|
||||||
|
bdrv_query_image_info().
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-7-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 5d8813593f3f673fc96eed199beb35690cc46f58)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
block/qapi.c: Conflicts with
|
||||||
|
54fde4ff0621c22b15cbaaa3c74301cc0dbd1c9e ("qapi block: Elide
|
||||||
|
redundant has_FOO in generated C"), which dropped
|
||||||
|
`has_backing_image`. Without that commit (and 44ea9d9be before it),
|
||||||
|
we still need to set `has_backing_image` in
|
||||||
|
`bdrv_query_image_info()`.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/qapi.c | 94 +++++++++++++++++++++++++++-----------------
|
||||||
|
include/block/qapi.h | 2 +
|
||||||
|
2 files changed, 59 insertions(+), 37 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index ad88bf9b38..5d0a8d2ce3 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -47,8 +47,10 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
ImageInfo **p_image_info;
|
||||||
|
+ ImageInfo *backing_info;
|
||||||
|
BlockDriverState *bs0, *backing;
|
||||||
|
BlockDeviceInfo *info;
|
||||||
|
+ ERRP_GUARD();
|
||||||
|
|
||||||
|
if (!bs->drv) {
|
||||||
|
error_setg(errp, "Block device %s is ejected", bs->node_name);
|
||||||
|
@@ -149,38 +151,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
|
||||||
|
bs0 = bs;
|
||||||
|
p_image_info = &info->image;
|
||||||
|
info->backing_file_depth = 0;
|
||||||
|
- while (1) {
|
||||||
|
- Error *local_err = NULL;
|
||||||
|
- bdrv_query_image_info(bs0, p_image_info, &local_err);
|
||||||
|
- if (local_err) {
|
||||||
|
- error_propagate(errp, local_err);
|
||||||
|
- qapi_free_BlockDeviceInfo(info);
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* stop gathering data for flat output */
|
||||||
|
- if (flat) {
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (bs0->drv && bdrv_filter_or_cow_child(bs0)) {
|
||||||
|
- /*
|
||||||
|
- * Put any filtered child here (for backwards compatibility to when
|
||||||
|
- * we put bs0->backing here, which might be any filtered child).
|
||||||
|
- */
|
||||||
|
- info->backing_file_depth++;
|
||||||
|
- bs0 = bdrv_filter_or_cow_bs(bs0);
|
||||||
|
- (*p_image_info)->has_backing_image = true;
|
||||||
|
- p_image_info = &((*p_image_info)->backing_image);
|
||||||
|
- } else {
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ /*
|
||||||
|
+ * Skip automatically inserted nodes that the user isn't aware of for
|
||||||
|
+ * query-block (blk != NULL), but not for query-named-block-nodes
|
||||||
|
+ */
|
||||||
|
+ bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ qapi_free_BlockDeviceInfo(info);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* Skip automatically inserted nodes that the user isn't aware of for
|
||||||
|
- * query-block (blk != NULL), but not for query-named-block-nodes */
|
||||||
|
- if (blk) {
|
||||||
|
- bs0 = bdrv_skip_implicit_filters(bs0);
|
||||||
|
- }
|
||||||
|
+ backing_info = info->image->backing_image;
|
||||||
|
+ while (backing_info) {
|
||||||
|
+ info->backing_file_depth++;
|
||||||
|
+ backing_info = backing_info->backing_image;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
@@ -363,19 +348,28 @@ void bdrv_query_block_node_info(BlockDriverState *bs,
|
||||||
|
* bdrv_query_image_info:
|
||||||
|
* @bs: block node to examine
|
||||||
|
* @p_info: location to store image information
|
||||||
|
+ * @flat: skip backing node information
|
||||||
|
+ * @skip_implicit_filters: skip implicit filters in the backing chain
|
||||||
|
* @errp: location to store error information
|
||||||
|
*
|
||||||
|
- * Store "flat" image information in @p_info.
|
||||||
|
+ * Store image information in @p_info, potentially recursively covering the
|
||||||
|
+ * backing chain.
|
||||||
|
*
|
||||||
|
- * "Flat" means it does *not* query backing image information,
|
||||||
|
- * i.e. (*pinfo)->has_backing_image will be set to false and
|
||||||
|
- * (*pinfo)->backing_image to NULL even when the image does in fact have
|
||||||
|
- * a backing image.
|
||||||
|
+ * If @flat is true, do not query backing image information, i.e.
|
||||||
|
+ * (*p_info)->has_backing_image will be set to false and
|
||||||
|
+ * (*p_info)->backing_image to NULL even when the image does in fact have a
|
||||||
|
+ * backing image.
|
||||||
|
+ *
|
||||||
|
+ * If @skip_implicit_filters is true, implicit filter nodes in the backing chain
|
||||||
|
+ * will be skipped when querying backing image information.
|
||||||
|
+ * (@skip_implicit_filters is ignored when @flat is true.)
|
||||||
|
*
|
||||||
|
* @p_info will be set only on success. On error, store error in @errp.
|
||||||
|
*/
|
||||||
|
void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
ImageInfo **p_info,
|
||||||
|
+ bool flat,
|
||||||
|
+ bool skip_implicit_filters,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
ImageInfo *info;
|
||||||
|
@@ -384,11 +378,37 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
info = g_new0(ImageInfo, 1);
|
||||||
|
bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
|
||||||
|
if (*errp) {
|
||||||
|
- qapi_free_ImageInfo(info);
|
||||||
|
- return;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!flat) {
|
||||||
|
+ BlockDriverState *backing;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Use any filtered child here (for backwards compatibility to when
|
||||||
|
+ * we always took bs->backing, which might be any filtered child).
|
||||||
|
+ */
|
||||||
|
+ backing = bdrv_filter_or_cow_bs(bs);
|
||||||
|
+ if (skip_implicit_filters) {
|
||||||
|
+ backing = bdrv_skip_implicit_filters(backing);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (backing) {
|
||||||
|
+ bdrv_query_image_info(backing, &info->backing_image, false,
|
||||||
|
+ skip_implicit_filters, errp);
|
||||||
|
+ if (*errp) {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ info->has_backing_image = true;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
*p_info = info;
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+fail:
|
||||||
|
+ assert(*errp);
|
||||||
|
+ qapi_free_ImageInfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @p_info will be set only on success. */
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index 22198dcd0c..2174bf8fa2 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -40,6 +40,8 @@ void bdrv_query_block_node_info(BlockDriverState *bs,
|
||||||
|
Error **errp);
|
||||||
|
void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
ImageInfo **p_info,
|
||||||
|
+ bool flat,
|
||||||
|
+ bool skip_implicit_filters,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
|
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
140
kvm-block-vmdk-Change-extent-info-type.patch
Normal file
140
kvm-block-vmdk-Change-extent-info-type.patch
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
From d8caed018afb0f60f449e971398d2a8d6c2992e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:55 +0200
|
||||||
|
Subject: [PATCH 08/20] block/vmdk: Change extent info type
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [3/12] efe50a2797c679ce6bb5faa423047461a34e6792 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
VMDK's implementation of .bdrv_get_specific_info() returns information
|
||||||
|
about its extent files, ostensibly in the form of ImageInfo objects.
|
||||||
|
However, it does not get this information through
|
||||||
|
bdrv_query_image_info(), but fills only a select few fields with custom
|
||||||
|
information that does not always match the fields' purposes.
|
||||||
|
|
||||||
|
For example, @format, which is supposed to be a block driver name, is
|
||||||
|
filled with the extent type, e.g. SPARSE or FLAT.
|
||||||
|
|
||||||
|
In ImageInfo, @compressed shows whether the data that can be seen in the
|
||||||
|
image is stored in compressed form or not. For example, a compressed
|
||||||
|
qcow2 image will store compressed data in its data file, but when
|
||||||
|
accessing the qcow2 node, you will see normal data. This is not how
|
||||||
|
VMDK uses the @compressed field for its extent files: Instead, it
|
||||||
|
signifies whether accessing the extent file will yield compressed data
|
||||||
|
(which the VMDK driver then (de-)compresses).
|
||||||
|
|
||||||
|
Create a new structure to represent the extent information. This allows
|
||||||
|
us to clarify the fields' meanings, and it clearly shows that these are
|
||||||
|
not complete ImageInfo objects. (That is, if a user wants an extent
|
||||||
|
file's ImageInfo object, they will need to query it separately, and will
|
||||||
|
not get it from ImageInfoSpecificVmdk.extents.)
|
||||||
|
|
||||||
|
Note that this removes the last use of ['ImageInfo'] (i.e. an array of
|
||||||
|
ImageInfo objects), so the QAPI generator will no longer generate
|
||||||
|
ImageInfoList by default. However, we use it in qemu-img.c, so we need
|
||||||
|
to create a dummy object to force the generate to create that type,
|
||||||
|
similarly to DummyForceArrays in machine.json (introduced in commit
|
||||||
|
9f08c8ec73878122ad4b061ed334f0437afaaa32 ("qapi: Lazy creation of array
|
||||||
|
types")).
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-4-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 456e75171a85c19a5bfa202eefcbdc4ef1692f05)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/vmdk.c | 8 ++++----
|
||||||
|
qapi/block-core.json | 38 +++++++++++++++++++++++++++++++++++++-
|
||||||
|
2 files changed, 41 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/vmdk.c b/block/vmdk.c
|
||||||
|
index 26376352b9..4435b9880b 100644
|
||||||
|
--- a/block/vmdk.c
|
||||||
|
+++ b/block/vmdk.c
|
||||||
|
@@ -2901,12 +2901,12 @@ static int vmdk_has_zero_init(BlockDriverState *bs)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent)
|
||||||
|
+static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
|
||||||
|
{
|
||||||
|
- ImageInfo *info = g_new0(ImageInfo, 1);
|
||||||
|
+ VmdkExtentInfo *info = g_new0(VmdkExtentInfo, 1);
|
||||||
|
|
||||||
|
bdrv_refresh_filename(extent->file->bs);
|
||||||
|
- *info = (ImageInfo){
|
||||||
|
+ *info = (VmdkExtentInfo){
|
||||||
|
.filename = g_strdup(extent->file->bs->filename),
|
||||||
|
.format = g_strdup(extent->type),
|
||||||
|
.virtual_size = extent->sectors * BDRV_SECTOR_SIZE,
|
||||||
|
@@ -2985,7 +2985,7 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs,
|
||||||
|
int i;
|
||||||
|
BDRVVmdkState *s = bs->opaque;
|
||||||
|
ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1);
|
||||||
|
- ImageInfoList **tail;
|
||||||
|
+ VmdkExtentInfoList **tail;
|
||||||
|
|
||||||
|
*spec_info = (ImageInfoSpecific){
|
||||||
|
.type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index f5d822cbd6..4b9365167f 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -124,7 +124,33 @@
|
||||||
|
'create-type': 'str',
|
||||||
|
'cid': 'int',
|
||||||
|
'parent-cid': 'int',
|
||||||
|
- 'extents': ['ImageInfo']
|
||||||
|
+ 'extents': ['VmdkExtentInfo']
|
||||||
|
+ } }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
+# @VmdkExtentInfo:
|
||||||
|
+#
|
||||||
|
+# Information about a VMDK extent file
|
||||||
|
+#
|
||||||
|
+# @filename: Name of the extent file
|
||||||
|
+#
|
||||||
|
+# @format: Extent type (e.g. FLAT or SPARSE)
|
||||||
|
+#
|
||||||
|
+# @virtual-size: Number of bytes covered by this extent
|
||||||
|
+#
|
||||||
|
+# @cluster-size: Cluster size in bytes (for non-flat extents)
|
||||||
|
+#
|
||||||
|
+# @compressed: Whether this extent contains compressed data
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'VmdkExtentInfo',
|
||||||
|
+ 'data': {
|
||||||
|
+ 'filename': 'str',
|
||||||
|
+ 'format': 'str',
|
||||||
|
+ 'virtual-size': 'int',
|
||||||
|
+ '*cluster-size': 'int',
|
||||||
|
+ '*compressed': 'bool'
|
||||||
|
} }
|
||||||
|
|
||||||
|
##
|
||||||
|
@@ -5754,3 +5780,13 @@
|
||||||
|
'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
|
||||||
|
'returns': 'SnapshotInfo',
|
||||||
|
'allow-preconfig': true }
|
||||||
|
+
|
||||||
|
+##
|
||||||
|
+# @DummyBlockCoreForceArrays:
|
||||||
|
+#
|
||||||
|
+# Not used by QMP; hack to let us use ImageInfoList internally
|
||||||
|
+#
|
||||||
|
+# Since: 8.0
|
||||||
|
+##
|
||||||
|
+{ 'struct': 'DummyBlockCoreForceArrays',
|
||||||
|
+ 'data': { 'unused-image-info': ['ImageInfo'] } }
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
99
kvm-iotests-106-214-308-Read-only-one-size-line.patch
Normal file
99
kvm-iotests-106-214-308-Read-only-one-size-line.patch
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
From 6727e92a97f8ee9f367a41111bef3f5cad4a479a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:27:02 +0200
|
||||||
|
Subject: [PATCH 15/20] iotests/106, 214, 308: Read only one size line
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [10/12] 1554e0a92b92ed101a251478ccae43f45f6e071e (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
These tests read size information (sometimes disk size, sometimes
|
||||||
|
virtual size) from qemu-img info's output. Once qemu-img starts
|
||||||
|
printing info about child nodes, we are going to see multiple instances
|
||||||
|
of that per image, but these tests are only interested in the first one,
|
||||||
|
so use "head -n 1" to get it.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-11-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 74163adda3101b127943f7cbbf8fcccd2d472426)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
tests/qemu-iotests/106 | 4 ++--
|
||||||
|
tests/qemu-iotests/214 | 6 ++++--
|
||||||
|
tests/qemu-iotests/308 | 4 ++--
|
||||||
|
3 files changed, 8 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
|
||||||
|
index 9d6adb542d..ae0fc46691 100755
|
||||||
|
--- a/tests/qemu-iotests/106
|
||||||
|
+++ b/tests/qemu-iotests/106
|
||||||
|
@@ -66,7 +66,7 @@ for create_mode in off falloc full; do
|
||||||
|
expected_size=$((expected_size + $GROWTH_SIZE))
|
||||||
|
fi
|
||||||
|
|
||||||
|
- actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
|
||||||
|
+ actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size' | head -n 1)
|
||||||
|
actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
|
||||||
|
|
||||||
|
# The actual size may exceed the expected size, depending on the file
|
||||||
|
@@ -105,7 +105,7 @@ for growth_mode in falloc full; do
|
||||||
|
_make_test_img -o "extent_size_hint=0" 2G
|
||||||
|
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K
|
||||||
|
|
||||||
|
- actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
|
||||||
|
+ actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size' | head -n 1)
|
||||||
|
actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
|
||||||
|
|
||||||
|
if [ $actual_size -lt $GROWTH_SIZE ]; then
|
||||||
|
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
|
||||||
|
index c66e246ba2..55ffcd7f44 100755
|
||||||
|
--- a/tests/qemu-iotests/214
|
||||||
|
+++ b/tests/qemu-iotests/214
|
||||||
|
@@ -102,7 +102,8 @@ let data_size="8 * $cluster_size"
|
||||||
|
$QEMU_IO -c "write -P 0xaa 0 $data_size" "$TEST_IMG" \
|
||||||
|
2>&1 | _filter_qemu_io | _filter_testdir
|
||||||
|
sizeA=$($QEMU_IMG info --output=json "$TEST_IMG" |
|
||||||
|
- sed -n '/"actual-size":/ s/[^0-9]//gp')
|
||||||
|
+ sed -n '/"actual-size":/ s/[^0-9]//gp' |
|
||||||
|
+ head -n 1)
|
||||||
|
|
||||||
|
_make_test_img 2M -o cluster_size=$cluster_size
|
||||||
|
echo "Write compressed data:"
|
||||||
|
@@ -124,7 +125,8 @@ $QEMU_IO -c "write -P 0xcc $offset $data_size" "json:{\
|
||||||
|
_filter_qemu_io | _filter_testdir
|
||||||
|
|
||||||
|
sizeB=$($QEMU_IMG info --output=json "$TEST_IMG" |
|
||||||
|
- sed -n '/"actual-size":/ s/[^0-9]//gp')
|
||||||
|
+ sed -n '/"actual-size":/ s/[^0-9]//gp' |
|
||||||
|
+ head -n 1)
|
||||||
|
|
||||||
|
if [ $sizeA -lt $sizeB ]
|
||||||
|
then
|
||||||
|
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
|
||||||
|
index bde4aac2fa..09275e9a10 100755
|
||||||
|
--- a/tests/qemu-iotests/308
|
||||||
|
+++ b/tests/qemu-iotests/308
|
||||||
|
@@ -217,12 +217,12 @@ echo
|
||||||
|
echo '=== Remove export ==='
|
||||||
|
|
||||||
|
# Double-check that $EXT_MP appears as a non-empty file (the raw image)
|
||||||
|
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
|
||||||
|
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
|
||||||
|
|
||||||
|
fuse_export_del 'export-mp'
|
||||||
|
|
||||||
|
# See that the file appears empty again
|
||||||
|
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
|
||||||
|
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '=== Writable export ==='
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
171
kvm-iotests-Filter-child-node-information.patch
Normal file
171
kvm-iotests-Filter-child-node-information.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
From 3102e62f80757729c97e58e2b3d62a6a9de952a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:27:01 +0200
|
||||||
|
Subject: [PATCH 14/20] iotests: Filter child node information
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [9/12] 0b0a42d54397791f7f149e53c9175b7863707e70 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
Before we let qemu-img info print child node information, have
|
||||||
|
common.filter, common.rc, and iotests.py filter it from the test output
|
||||||
|
so we get as few reference output changes as possible.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-10-hreitz@redhat.com>
|
||||||
|
Tested-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit bcc6777ad6facede73c0cf8b1700045bf4365f7d)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
tests/qemu-iotests/common.filter | 22 ++++++++++++++--------
|
||||||
|
tests/qemu-iotests/common.rc | 22 ++++++++++++++--------
|
||||||
|
tests/qemu-iotests/iotests.py | 18 +++++++++++++++---
|
||||||
|
3 files changed, 43 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
|
||||||
|
index 6a13757177..6ddda2ee64 100644
|
||||||
|
--- a/tests/qemu-iotests/common.filter
|
||||||
|
+++ b/tests/qemu-iotests/common.filter
|
||||||
|
@@ -224,6 +224,7 @@ _filter_img_info()
|
||||||
|
|
||||||
|
discard=0
|
||||||
|
regex_json_spec_start='^ *"format-specific": \{'
|
||||||
|
+ regex_json_child_start='^ *"children": \['
|
||||||
|
gsed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
|
||||||
|
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
|
||||||
|
-e "s#$TEST_DIR#TEST_DIR#g" \
|
||||||
|
@@ -252,20 +253,25 @@ _filter_img_info()
|
||||||
|
-e 's/\(compression type: \)\(zlib\|zstd\)/\1COMPRESSION_TYPE/' \
|
||||||
|
-e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" | \
|
||||||
|
while IFS='' read -r line; do
|
||||||
|
- if [[ $format_specific == 1 ]]; then
|
||||||
|
- discard=0
|
||||||
|
- elif [[ $line == "Format specific information:" ]]; then
|
||||||
|
- discard=1
|
||||||
|
- elif [[ $line =~ $regex_json_spec_start ]]; then
|
||||||
|
- discard=2
|
||||||
|
- regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
|
||||||
|
+ if [[ $discard == 0 ]]; then
|
||||||
|
+ if [[ $format_specific == 0 && $line == "Format specific information:" ]]; then
|
||||||
|
+ discard=1
|
||||||
|
+ elif [[ $line =~ "Child node '/" ]]; then
|
||||||
|
+ discard=1
|
||||||
|
+ elif [[ $line =~ $regex_json_spec_start ]]; then
|
||||||
|
+ discard=2
|
||||||
|
+ regex_json_end="^${line%%[^ ]*}\\},? *$"
|
||||||
|
+ elif [[ $line =~ $regex_json_child_start ]]; then
|
||||||
|
+ discard=2
|
||||||
|
+ regex_json_end="^${line%%[^ ]*}\\],? *$"
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
if [[ $discard == 0 ]]; then
|
||||||
|
echo "$line"
|
||||||
|
elif [[ $discard == 1 && ! $line ]]; then
|
||||||
|
echo
|
||||||
|
discard=0
|
||||||
|
- elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
|
||||||
|
+ elif [[ $discard == 2 && $line =~ $regex_json_end ]]; then
|
||||||
|
discard=0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
|
||||||
|
index db757025cb..f4476b62f7 100644
|
||||||
|
--- a/tests/qemu-iotests/common.rc
|
||||||
|
+++ b/tests/qemu-iotests/common.rc
|
||||||
|
@@ -711,6 +711,7 @@ _img_info()
|
||||||
|
|
||||||
|
discard=0
|
||||||
|
regex_json_spec_start='^ *"format-specific": \{'
|
||||||
|
+ regex_json_child_start='^ *"children": \['
|
||||||
|
$QEMU_IMG info $QEMU_IMG_EXTRA_ARGS "$@" "$TEST_IMG" 2>&1 | \
|
||||||
|
sed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
|
||||||
|
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
|
||||||
|
@@ -721,20 +722,25 @@ _img_info()
|
||||||
|
-e "/^disk size:/ D" \
|
||||||
|
-e "/actual-size/ D" | \
|
||||||
|
while IFS='' read -r line; do
|
||||||
|
- if [[ $format_specific == 1 ]]; then
|
||||||
|
- discard=0
|
||||||
|
- elif [[ $line == "Format specific information:" ]]; then
|
||||||
|
- discard=1
|
||||||
|
- elif [[ $line =~ $regex_json_spec_start ]]; then
|
||||||
|
- discard=2
|
||||||
|
- regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
|
||||||
|
+ if [[ $discard == 0 ]]; then
|
||||||
|
+ if [[ $format_specific == 0 && $line == "Format specific information:" ]]; then
|
||||||
|
+ discard=1
|
||||||
|
+ elif [[ $line =~ "Child node '/" ]]; then
|
||||||
|
+ discard=1
|
||||||
|
+ elif [[ $format_specific == 0 && $line =~ $regex_json_spec_start ]]; then
|
||||||
|
+ discard=2
|
||||||
|
+ regex_json_end="^${line%%[^ ]*}\\},? *$"
|
||||||
|
+ elif [[ $line =~ $regex_json_child_start ]]; then
|
||||||
|
+ discard=2
|
||||||
|
+ regex_json_end="^${line%%[^ ]*}\\],? *$"
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
if [[ $discard == 0 ]]; then
|
||||||
|
echo "$line"
|
||||||
|
elif [[ $discard == 1 && ! $line ]]; then
|
||||||
|
echo
|
||||||
|
discard=0
|
||||||
|
- elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
|
||||||
|
+ elif [[ $discard == 2 && $line =~ $regex_json_end ]]; then
|
||||||
|
discard=0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
|
||||||
|
index da7d6637e1..94aeb3f3b2 100644
|
||||||
|
--- a/tests/qemu-iotests/iotests.py
|
||||||
|
+++ b/tests/qemu-iotests/iotests.py
|
||||||
|
@@ -329,7 +329,7 @@ def qemu_img_log(*args: str, check: bool = True
|
||||||
|
|
||||||
|
def img_info_log(filename: str, filter_path: Optional[str] = None,
|
||||||
|
use_image_opts: bool = False, extra_args: Sequence[str] = (),
|
||||||
|
- check: bool = True,
|
||||||
|
+ check: bool = True, drop_child_info: bool = True,
|
||||||
|
) -> None:
|
||||||
|
args = ['info']
|
||||||
|
if use_image_opts:
|
||||||
|
@@ -342,7 +342,7 @@ def img_info_log(filename: str, filter_path: Optional[str] = None,
|
||||||
|
output = qemu_img(*args, check=check).stdout
|
||||||
|
if not filter_path:
|
||||||
|
filter_path = filename
|
||||||
|
- log(filter_img_info(output, filter_path))
|
||||||
|
+ log(filter_img_info(output, filter_path, drop_child_info))
|
||||||
|
|
||||||
|
def qemu_io_wrap_args(args: Sequence[str]) -> List[str]:
|
||||||
|
if '-f' in args or '--image-opts' in args:
|
||||||
|
@@ -642,11 +642,23 @@ def _filter(_key, value):
|
||||||
|
def filter_generated_node_ids(msg):
|
||||||
|
return re.sub("#block[0-9]+", "NODE_NAME", msg)
|
||||||
|
|
||||||
|
-def filter_img_info(output, filename):
|
||||||
|
+def filter_img_info(output: str, filename: str,
|
||||||
|
+ drop_child_info: bool = True) -> str:
|
||||||
|
lines = []
|
||||||
|
+ drop_indented = False
|
||||||
|
for line in output.split('\n'):
|
||||||
|
if 'disk size' in line or 'actual-size' in line:
|
||||||
|
continue
|
||||||
|
+
|
||||||
|
+ # Drop child node info
|
||||||
|
+ if drop_indented:
|
||||||
|
+ if line.startswith(' '):
|
||||||
|
+ continue
|
||||||
|
+ drop_indented = False
|
||||||
|
+ if drop_child_info and "Child node '/" in line:
|
||||||
|
+ drop_indented = True
|
||||||
|
+ continue
|
||||||
|
+
|
||||||
|
line = line.replace(filename, 'TEST_IMG')
|
||||||
|
line = filter_testfiles(line)
|
||||||
|
line = line.replace(imgfmt, 'IMGFMT')
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,67 @@
|
|||||||
|
From 46ead2c391924b68741d6da28f28f909b80f5914 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 20:14:51 +0100
|
||||||
|
Subject: [PATCH 01/20] qcow2: Fix theoretical corruption in store_bitmap()
|
||||||
|
error path
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-MergeRequest: 143: qemu-img: Fix exit code for errors closing the image
|
||||||
|
RH-Bugzilla: 2150180
|
||||||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||||
|
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [1/4] a6a497947179431567d330d0501247a3749fb9fd (kmwolf/centos-qemu-kvm)
|
||||||
|
|
||||||
|
In order to write the bitmap table to the image file, it is converted to
|
||||||
|
big endian. If the write fails, it is passed to clear_bitmap_table() to
|
||||||
|
free all of the clusters it had allocated before. However, if we don't
|
||||||
|
convert it back to native endianness first, we'll free things at a wrong
|
||||||
|
offset.
|
||||||
|
|
||||||
|
In practical terms, the offsets will be so high that we won't actually
|
||||||
|
free any allocated clusters, but just run into an error, but in theory
|
||||||
|
this can cause image corruption.
|
||||||
|
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Message-Id: <20230112191454.169353-2-kwolf@redhat.com>
|
||||||
|
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit b03dd9613bcf8fe948581b2b3585510cb525c382)
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
---
|
||||||
|
block/qcow2-bitmap.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
|
||||||
|
index bcad567c0c..3dff99ba06 100644
|
||||||
|
--- a/block/qcow2-bitmap.c
|
||||||
|
+++ b/block/qcow2-bitmap.c
|
||||||
|
@@ -115,7 +115,7 @@ static int update_header_sync(BlockDriverState *bs)
|
||||||
|
return bdrv_flush(bs->file->bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline void bitmap_table_to_be(uint64_t *bitmap_table, size_t size)
|
||||||
|
+static inline void bitmap_table_bswap_be(uint64_t *bitmap_table, size_t size)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
@@ -1401,9 +1401,10 @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
- bitmap_table_to_be(tb, tb_size);
|
||||||
|
+ bitmap_table_bswap_be(tb, tb_size);
|
||||||
|
ret = bdrv_pwrite(bs->file, tb_offset, tb_size * sizeof(tb[0]), tb, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
+ bitmap_table_bswap_be(tb, tb_size);
|
||||||
|
error_setg_errno(errp, -ret, "Failed to write bitmap '%s' to file",
|
||||||
|
bm_name);
|
||||||
|
goto fail;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
197
kvm-qemu-img-Change-info-key-names-for-protocol-nodes.patch
Normal file
197
kvm-qemu-img-Change-info-key-names-for-protocol-nodes.patch
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
From b1970c733dc46b2a8f648997a7e1c5d12900ff54 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:27:04 +0200
|
||||||
|
Subject: [PATCH 17/20] qemu-img: Change info key names for protocol nodes
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [12/12] 67c260aaa05466410503fecee6210bf9d47e8c7c (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
Currently, when querying a qcow2 image, qemu-img info reports something
|
||||||
|
like this:
|
||||||
|
|
||||||
|
image: test.qcow2
|
||||||
|
file format: qcow2
|
||||||
|
virtual size: 64 MiB (67108864 bytes)
|
||||||
|
disk size: 196 KiB
|
||||||
|
cluster_size: 65536
|
||||||
|
Format specific information:
|
||||||
|
compat: 1.1
|
||||||
|
compression type: zlib
|
||||||
|
lazy refcounts: false
|
||||||
|
refcount bits: 16
|
||||||
|
corrupt: false
|
||||||
|
extended l2: false
|
||||||
|
Child node '/file':
|
||||||
|
image: test.qcow2
|
||||||
|
file format: file
|
||||||
|
virtual size: 192 KiB (197120 bytes)
|
||||||
|
disk size: 196 KiB
|
||||||
|
Format specific information:
|
||||||
|
extent size hint: 1048576
|
||||||
|
|
||||||
|
Notably, the way the keys are named is specific for image files: The
|
||||||
|
filename is shown under "image", the BDS driver under "file format", and
|
||||||
|
the BDS length under "virtual size". This does not make much sense for
|
||||||
|
nodes that are not actually supposed to be guest images, like the /file
|
||||||
|
child node shown above.
|
||||||
|
|
||||||
|
Give bdrv_node_info_dump() a @protocol parameter that gives a hint that
|
||||||
|
the respective node is probably just used for data storage and does not
|
||||||
|
necessarily present the data for a VM guest disk. This renames the keys
|
||||||
|
so that with this patch, the output becomes:
|
||||||
|
|
||||||
|
image: test.qcow2
|
||||||
|
[...]
|
||||||
|
Child node '/file':
|
||||||
|
filename: test.qcow2
|
||||||
|
protocol type: file
|
||||||
|
file length: 192 KiB (197120 bytes)
|
||||||
|
disk size: 196 KiB
|
||||||
|
Format specific information:
|
||||||
|
extent size hint: 1048576
|
||||||
|
|
||||||
|
(Perhaps we should also rename "Format specific information", but I
|
||||||
|
could not come up with anything better that will not become problematic
|
||||||
|
if we guess wrong with the protocol "heuristic".)
|
||||||
|
|
||||||
|
This change affects iotest 302, which has protocol node information in
|
||||||
|
its reference output.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-13-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit d570177b50c389f379f93183155a27d44856ab46)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/monitor/block-hmp-cmds.c | 2 +-
|
||||||
|
block/qapi.c | 39 ++++++++++++++++++++++++++++------
|
||||||
|
include/block/qapi.h | 2 +-
|
||||||
|
qemu-img.c | 3 ++-
|
||||||
|
tests/qemu-iotests/302.out | 6 +++---
|
||||||
|
5 files changed, 39 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||||
|
index 72824d4e2e..4d83339a5d 100644
|
||||||
|
--- a/block/monitor/block-hmp-cmds.c
|
||||||
|
+++ b/block/monitor/block-hmp-cmds.c
|
||||||
|
@@ -734,7 +734,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
||||||
|
monitor_printf(mon, "\nImages:\n");
|
||||||
|
image_info = inserted->image;
|
||||||
|
while (1) {
|
||||||
|
- bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0);
|
||||||
|
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0, false);
|
||||||
|
if (image_info->has_backing_image) {
|
||||||
|
image_info = image_info->backing_image;
|
||||||
|
} else {
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index 3e35603f0c..56f398c500 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -934,24 +934,49 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
visit_free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation)
|
||||||
|
+/**
|
||||||
|
+ * Print the given @info object in human-readable form. Every field is indented
|
||||||
|
+ * using the given @indentation (four spaces per indentation level).
|
||||||
|
+ *
|
||||||
|
+ * When using this to print a whole block graph, @protocol can be set to true to
|
||||||
|
+ * signify that the given information is associated with a protocol node, i.e.
|
||||||
|
+ * just data storage for an image, such that the data it presents is not really
|
||||||
|
+ * a full VM disk. If so, several fields change name: For example, "virtual
|
||||||
|
+ * size" is printed as "file length".
|
||||||
|
+ * (Consider a qcow2 image, which is represented by a qcow2 node and a file
|
||||||
|
+ * node. Printing a "virtual size" for the file node does not make sense,
|
||||||
|
+ * because without the qcow2 node, it is not really a guest disk, so it does not
|
||||||
|
+ * have a "virtual size". Therefore, we call it "file length" instead.)
|
||||||
|
+ *
|
||||||
|
+ * @protocol is ignored when @indentation is 0, because we take that to mean
|
||||||
|
+ * that the associated node is the root node in the queried block graph, and
|
||||||
|
+ * thus is always to be interpreted as a standalone guest disk.
|
||||||
|
+ */
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
|
||||||
|
{
|
||||||
|
char *size_buf, *dsize_buf;
|
||||||
|
g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
|
||||||
|
|
||||||
|
+ if (indentation == 0) {
|
||||||
|
+ /* Top level, consider this a normal image */
|
||||||
|
+ protocol = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!info->has_actual_size) {
|
||||||
|
dsize_buf = g_strdup("unavailable");
|
||||||
|
} else {
|
||||||
|
dsize_buf = size_to_str(info->actual_size);
|
||||||
|
}
|
||||||
|
size_buf = size_to_str(info->virtual_size);
|
||||||
|
- qemu_printf("%simage: %s\n"
|
||||||
|
- "%sfile format: %s\n"
|
||||||
|
- "%svirtual size: %s (%" PRId64 " bytes)\n"
|
||||||
|
+ qemu_printf("%s%s: %s\n"
|
||||||
|
+ "%s%s: %s\n"
|
||||||
|
+ "%s%s: %s (%" PRId64 " bytes)\n"
|
||||||
|
"%sdisk size: %s\n",
|
||||||
|
- ind_s, info->filename,
|
||||||
|
- ind_s, info->format,
|
||||||
|
- ind_s, size_buf, info->virtual_size,
|
||||||
|
+ ind_s, protocol ? "filename" : "image", info->filename,
|
||||||
|
+ ind_s, protocol ? "protocol type" : "file format",
|
||||||
|
+ info->format,
|
||||||
|
+ ind_s, protocol ? "file length" : "virtual size",
|
||||||
|
+ size_buf, info->virtual_size,
|
||||||
|
ind_s, dsize_buf);
|
||||||
|
g_free(size_buf);
|
||||||
|
g_free(dsize_buf);
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index 38855f2ae9..26113da21a 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -51,5 +51,5 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
const char *prefix,
|
||||||
|
int indentation);
|
||||||
|
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation);
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol);
|
||||||
|
#endif
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index e281011245..2943625c67 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -2853,7 +2853,8 @@ static void dump_human_image_info(BlockGraphInfo *info, int indentation,
|
||||||
|
{
|
||||||
|
BlockChildInfoList *children_list;
|
||||||
|
|
||||||
|
- bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation);
|
||||||
|
+ bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation,
|
||||||
|
+ info->children == NULL);
|
||||||
|
|
||||||
|
for (children_list = info->children; children_list;
|
||||||
|
children_list = children_list->next)
|
||||||
|
diff --git a/tests/qemu-iotests/302.out b/tests/qemu-iotests/302.out
|
||||||
|
index edfa1c4f05..7b5014cdd8 100644
|
||||||
|
--- a/tests/qemu-iotests/302.out
|
||||||
|
+++ b/tests/qemu-iotests/302.out
|
||||||
|
@@ -5,9 +5,9 @@ file format: raw
|
||||||
|
virtual size: 448 KiB (458752 bytes)
|
||||||
|
disk size: unavailable
|
||||||
|
Child node '/file':
|
||||||
|
- image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
|
||||||
|
- file format: nbd
|
||||||
|
- virtual size: 448 KiB (458752 bytes)
|
||||||
|
+ filename: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
|
||||||
|
+ protocol type: nbd
|
||||||
|
+ file length: 448 KiB (458752 bytes)
|
||||||
|
disk size: unavailable
|
||||||
|
|
||||||
|
=== Converted image info ===
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
261
kvm-qemu-img-Let-info-print-block-graph.patch
Normal file
261
kvm-qemu-img-Let-info-print-block-graph.patch
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
From ea73e9de42b446ce1049805c23f7706e4f87ed1f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:27:03 +0200
|
||||||
|
Subject: [PATCH 16/20] qemu-img: Let info print block graph
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [11/12] 2c1b8a03c918484449e876acf4c6663766848ad8 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
For every node in the backing chain, collect its BlockGraphInfo struct
|
||||||
|
using bdrv_query_block_graph_info(). Print all nodes' information,
|
||||||
|
indenting child nodes and labelling them with a path constructed from
|
||||||
|
the child names leading to the node from the root (e.g. /file/file).
|
||||||
|
|
||||||
|
Note that we open each image with BDRV_O_NO_BACKING, so its backing
|
||||||
|
child is omitted from this graph, and thus presented in the previous
|
||||||
|
manner: By simply concatenating all images' information, separated with
|
||||||
|
blank lines.
|
||||||
|
|
||||||
|
This affects two iotests:
|
||||||
|
- 065: Here we try to get the format node's format specific information.
|
||||||
|
The pre-patch code does so by taking all lines from "Format specific
|
||||||
|
information:" until an empty line. This format specific information
|
||||||
|
is no longer followed by an empty line, though, but by child node
|
||||||
|
information, so limit the range by "Child node '/file':".
|
||||||
|
- 302: Calls qemu_img() for qemu-img info directly, which does not
|
||||||
|
filter the output, so the child node information ends up in the
|
||||||
|
output.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-12-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit c04d0ab026201d21873a63f768cb69c4554dfec1)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
qapi/block-core.json | 4 +--
|
||||||
|
qemu-img.c | 69 ++++++++++++++++++++++++++------------
|
||||||
|
tests/qemu-iotests/065 | 2 +-
|
||||||
|
tests/qemu-iotests/302.out | 5 +++
|
||||||
|
4 files changed, 56 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index d703e0fb16..7f331eb8ea 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -5831,9 +5831,9 @@
|
||||||
|
##
|
||||||
|
# @DummyBlockCoreForceArrays:
|
||||||
|
#
|
||||||
|
-# Not used by QMP; hack to let us use BlockNodeInfoList internally
|
||||||
|
+# Not used by QMP; hack to let us use BlockGraphInfoList internally
|
||||||
|
#
|
||||||
|
# Since: 8.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'DummyBlockCoreForceArrays',
|
||||||
|
- 'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }
|
||||||
|
+ 'data': { 'unused-block-graph-info': ['BlockGraphInfo'] } }
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index 30b4ea58bb..e281011245 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -2816,13 +2816,13 @@ static void dump_snapshots(BlockDriverState *bs)
|
||||||
|
g_free(sn_tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_json_block_node_info_list(BlockNodeInfoList *list)
|
||||||
|
+static void dump_json_block_graph_info_list(BlockGraphInfoList *list)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
QObject *obj;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
|
||||||
|
- visit_type_BlockNodeInfoList(v, NULL, &list, &error_abort);
|
||||||
|
+ visit_type_BlockGraphInfoList(v, NULL, &list, &error_abort);
|
||||||
|
visit_complete(v, &obj);
|
||||||
|
str = qobject_to_json_pretty(obj, true);
|
||||||
|
assert(str != NULL);
|
||||||
|
@@ -2832,13 +2832,13 @@ static void dump_json_block_node_info_list(BlockNodeInfoList *list)
|
||||||
|
g_string_free(str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_json_block_node_info(BlockNodeInfo *info)
|
||||||
|
+static void dump_json_block_graph_info(BlockGraphInfo *info)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
QObject *obj;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
|
||||||
|
- visit_type_BlockNodeInfo(v, NULL, &info, &error_abort);
|
||||||
|
+ visit_type_BlockGraphInfo(v, NULL, &info, &error_abort);
|
||||||
|
visit_complete(v, &obj);
|
||||||
|
str = qobject_to_json_pretty(obj, true);
|
||||||
|
assert(str != NULL);
|
||||||
|
@@ -2848,9 +2848,29 @@ static void dump_json_block_node_info(BlockNodeInfo *info)
|
||||||
|
g_string_free(str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_human_image_info_list(BlockNodeInfoList *list)
|
||||||
|
+static void dump_human_image_info(BlockGraphInfo *info, int indentation,
|
||||||
|
+ const char *path)
|
||||||
|
{
|
||||||
|
- BlockNodeInfoList *elem;
|
||||||
|
+ BlockChildInfoList *children_list;
|
||||||
|
+
|
||||||
|
+ bdrv_node_info_dump(qapi_BlockGraphInfo_base(info), indentation);
|
||||||
|
+
|
||||||
|
+ for (children_list = info->children; children_list;
|
||||||
|
+ children_list = children_list->next)
|
||||||
|
+ {
|
||||||
|
+ BlockChildInfo *child = children_list->value;
|
||||||
|
+ g_autofree char *child_path = NULL;
|
||||||
|
+
|
||||||
|
+ printf("%*sChild node '%s%s':\n",
|
||||||
|
+ indentation * 4, "", path, child->name);
|
||||||
|
+ child_path = g_strdup_printf("%s%s/", path, child->name);
|
||||||
|
+ dump_human_image_info(child->info, indentation + 1, child_path);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void dump_human_image_info_list(BlockGraphInfoList *list)
|
||||||
|
+{
|
||||||
|
+ BlockGraphInfoList *elem;
|
||||||
|
bool delim = false;
|
||||||
|
|
||||||
|
for (elem = list; elem; elem = elem->next) {
|
||||||
|
@@ -2859,7 +2879,7 @@ static void dump_human_image_info_list(BlockNodeInfoList *list)
|
||||||
|
}
|
||||||
|
delim = true;
|
||||||
|
|
||||||
|
- bdrv_node_info_dump(elem->value, 0);
|
||||||
|
+ dump_human_image_info(elem->value, 0, "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2869,7 +2889,7 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Open an image file chain and return an BlockNodeInfoList
|
||||||
|
+ * Open an image file chain and return an BlockGraphInfoList
|
||||||
|
*
|
||||||
|
* @filename: topmost image filename
|
||||||
|
* @fmt: topmost image format (may be NULL to autodetect)
|
||||||
|
@@ -2880,13 +2900,13 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
|
||||||
|
* opening an image file. If there was an error a message will have been
|
||||||
|
* printed to stderr.
|
||||||
|
*/
|
||||||
|
-static BlockNodeInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
- const char *filename,
|
||||||
|
- const char *fmt,
|
||||||
|
- bool chain, bool force_share)
|
||||||
|
+static BlockGraphInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
+ const char *filename,
|
||||||
|
+ const char *fmt,
|
||||||
|
+ bool chain, bool force_share)
|
||||||
|
{
|
||||||
|
- BlockNodeInfoList *head = NULL;
|
||||||
|
- BlockNodeInfoList **tail = &head;
|
||||||
|
+ BlockGraphInfoList *head = NULL;
|
||||||
|
+ BlockGraphInfoList **tail = &head;
|
||||||
|
GHashTable *filenames;
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
@@ -2895,7 +2915,7 @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
while (filename) {
|
||||||
|
BlockBackend *blk;
|
||||||
|
BlockDriverState *bs;
|
||||||
|
- BlockNodeInfo *info;
|
||||||
|
+ BlockGraphInfo *info;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
|
||||||
|
error_report("Backing file '%s' creates an infinite loop.",
|
||||||
|
@@ -2912,7 +2932,14 @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
}
|
||||||
|
bs = blk_bs(blk);
|
||||||
|
|
||||||
|
- bdrv_query_block_node_info(bs, &info, &err);
|
||||||
|
+ /*
|
||||||
|
+ * Note that the returned BlockGraphInfo object will not have
|
||||||
|
+ * information about this image's backing node, because we have opened
|
||||||
|
+ * it with BDRV_O_NO_BACKING. Printing this object will therefore not
|
||||||
|
+ * duplicate the backing chain information that we obtain by walking
|
||||||
|
+ * the chain manually here.
|
||||||
|
+ */
|
||||||
|
+ bdrv_query_block_graph_info(bs, &info, &err);
|
||||||
|
if (err) {
|
||||||
|
error_report_err(err);
|
||||||
|
blk_unref(blk);
|
||||||
|
@@ -2945,7 +2972,7 @@ static BlockNodeInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
return head;
|
||||||
|
|
||||||
|
err:
|
||||||
|
- qapi_free_BlockNodeInfoList(head);
|
||||||
|
+ qapi_free_BlockGraphInfoList(head);
|
||||||
|
g_hash_table_destroy(filenames);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -2956,7 +2983,7 @@ static int img_info(int argc, char **argv)
|
||||||
|
OutputFormat output_format = OFORMAT_HUMAN;
|
||||||
|
bool chain = false;
|
||||||
|
const char *filename, *fmt, *output;
|
||||||
|
- BlockNodeInfoList *list;
|
||||||
|
+ BlockGraphInfoList *list;
|
||||||
|
bool image_opts = false;
|
||||||
|
bool force_share = false;
|
||||||
|
|
||||||
|
@@ -3035,14 +3062,14 @@ static int img_info(int argc, char **argv)
|
||||||
|
break;
|
||||||
|
case OFORMAT_JSON:
|
||||||
|
if (chain) {
|
||||||
|
- dump_json_block_node_info_list(list);
|
||||||
|
+ dump_json_block_graph_info_list(list);
|
||||||
|
} else {
|
||||||
|
- dump_json_block_node_info(list->value);
|
||||||
|
+ dump_json_block_graph_info(list->value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- qapi_free_BlockNodeInfoList(list);
|
||||||
|
+ qapi_free_BlockGraphInfoList(list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065
|
||||||
|
index b724c89c7c..b76701c71e 100755
|
||||||
|
--- a/tests/qemu-iotests/065
|
||||||
|
+++ b/tests/qemu-iotests/065
|
||||||
|
@@ -56,7 +56,7 @@ class TestQemuImgInfo(TestImageInfoSpecific):
|
||||||
|
def test_human(self):
|
||||||
|
data = qemu_img('info', '--output=human', test_img).stdout.split('\n')
|
||||||
|
data = data[(data.index('Format specific information:') + 1)
|
||||||
|
- :data.index('')]
|
||||||
|
+ :data.index("Child node '/file':")]
|
||||||
|
for field in data:
|
||||||
|
self.assertTrue(re.match('^ {4}[^ ]', field) is not None)
|
||||||
|
data = [line.strip() for line in data]
|
||||||
|
diff --git a/tests/qemu-iotests/302.out b/tests/qemu-iotests/302.out
|
||||||
|
index 3e7c281b91..edfa1c4f05 100644
|
||||||
|
--- a/tests/qemu-iotests/302.out
|
||||||
|
+++ b/tests/qemu-iotests/302.out
|
||||||
|
@@ -4,6 +4,11 @@ image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
|
||||||
|
file format: raw
|
||||||
|
virtual size: 448 KiB (458752 bytes)
|
||||||
|
disk size: unavailable
|
||||||
|
+Child node '/file':
|
||||||
|
+ image: nbd+unix:///exp?socket=SOCK_DIR/PID-nbd-sock
|
||||||
|
+ file format: nbd
|
||||||
|
+ virtual size: 448 KiB (458752 bytes)
|
||||||
|
+ disk size: unavailable
|
||||||
|
|
||||||
|
=== Converted image info ===
|
||||||
|
image: TEST_IMG
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
241
kvm-qemu-img-Use-BlockNodeInfo.patch
Normal file
241
kvm-qemu-img-Use-BlockNodeInfo.patch
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
From dca4cbe680baff837ca8ac8bd39b77b46af3f64b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Date: Mon, 20 Jun 2022 18:26:57 +0200
|
||||||
|
Subject: [PATCH 10/20] qemu-img: Use BlockNodeInfo
|
||||||
|
|
||||||
|
RH-Author: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-MergeRequest: 145: Show protocol-level information in qemu-img info
|
||||||
|
RH-Bugzilla: 1860292
|
||||||
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [5/12] b599af3ec05951a0ba11d9eae2ee19148d6bf624 (hreitz/qemu-kvm-c-9-s)
|
||||||
|
|
||||||
|
qemu-img info never uses ImageInfo's backing-image field, because it
|
||||||
|
opens the backing chain one by one with BDRV_O_NO_BACKING, and prints
|
||||||
|
all backing chain nodes' information consecutively. Use BlockNodeInfo
|
||||||
|
to make it clear that we only print information about a single node, and
|
||||||
|
that we are not using the backing-image field.
|
||||||
|
|
||||||
|
Notably, bdrv_image_info_dump() does not evaluate the backing-image
|
||||||
|
field, so we can easily make it take a BlockNodeInfo pointer (and
|
||||||
|
consequentially rename it to bdrv_node_info_dump()). It makes more
|
||||||
|
sense this way, because again, the interface now makes it syntactically
|
||||||
|
clear that backing-image is ignored by this function.
|
||||||
|
|
||||||
|
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
|
||||||
|
Message-Id: <20220620162704.80987-6-hreitz@redhat.com>
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit b1f4cd1589a16fec02f264a09bd3560e4ccce3c2)
|
||||||
|
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
---
|
||||||
|
block/monitor/block-hmp-cmds.c | 2 +-
|
||||||
|
block/qapi.c | 2 +-
|
||||||
|
include/block/qapi.h | 2 +-
|
||||||
|
qapi/block-core.json | 4 +--
|
||||||
|
qemu-img.c | 48 +++++++++++++++++-----------------
|
||||||
|
5 files changed, 29 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||||
|
index b6135e9bfe..aa37faa601 100644
|
||||||
|
--- a/block/monitor/block-hmp-cmds.c
|
||||||
|
+++ b/block/monitor/block-hmp-cmds.c
|
||||||
|
@@ -734,7 +734,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
||||||
|
monitor_printf(mon, "\nImages:\n");
|
||||||
|
image_info = inserted->image;
|
||||||
|
while (1) {
|
||||||
|
- bdrv_image_info_dump(image_info);
|
||||||
|
+ bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
|
||||||
|
if (image_info->has_backing_image) {
|
||||||
|
image_info = image_info->backing_image;
|
||||||
|
} else {
|
||||||
|
diff --git a/block/qapi.c b/block/qapi.c
|
||||||
|
index e5022b4481..ad88bf9b38 100644
|
||||||
|
--- a/block/qapi.c
|
||||||
|
+++ b/block/qapi.c
|
||||||
|
@@ -865,7 +865,7 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
visit_free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void bdrv_image_info_dump(ImageInfo *info)
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info)
|
||||||
|
{
|
||||||
|
char *size_buf, *dsize_buf;
|
||||||
|
if (!info->has_actual_size) {
|
||||||
|
diff --git a/include/block/qapi.h b/include/block/qapi.h
|
||||||
|
index c7de4e3fa9..22198dcd0c 100644
|
||||||
|
--- a/include/block/qapi.h
|
||||||
|
+++ b/include/block/qapi.h
|
||||||
|
@@ -45,5 +45,5 @@ void bdrv_query_image_info(BlockDriverState *bs,
|
||||||
|
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
|
||||||
|
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
|
||||||
|
const char *prefix);
|
||||||
|
-void bdrv_image_info_dump(ImageInfo *info);
|
||||||
|
+void bdrv_node_info_dump(BlockNodeInfo *info);
|
||||||
|
#endif
|
||||||
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||||
|
index 7720da0498..4cf2deeb6c 100644
|
||||||
|
--- a/qapi/block-core.json
|
||||||
|
+++ b/qapi/block-core.json
|
||||||
|
@@ -5796,9 +5796,9 @@
|
||||||
|
##
|
||||||
|
# @DummyBlockCoreForceArrays:
|
||||||
|
#
|
||||||
|
-# Not used by QMP; hack to let us use ImageInfoList internally
|
||||||
|
+# Not used by QMP; hack to let us use BlockNodeInfoList internally
|
||||||
|
#
|
||||||
|
# Since: 8.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'DummyBlockCoreForceArrays',
|
||||||
|
- 'data': { 'unused-image-info': ['ImageInfo'] } }
|
||||||
|
+ 'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index 2f85bb7ede..3b2ca3bbcb 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -2816,13 +2816,13 @@ static void dump_snapshots(BlockDriverState *bs)
|
||||||
|
g_free(sn_tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_json_image_info_list(ImageInfoList *list)
|
||||||
|
+static void dump_json_block_node_info_list(BlockNodeInfoList *list)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
QObject *obj;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
|
||||||
|
- visit_type_ImageInfoList(v, NULL, &list, &error_abort);
|
||||||
|
+ visit_type_BlockNodeInfoList(v, NULL, &list, &error_abort);
|
||||||
|
visit_complete(v, &obj);
|
||||||
|
str = qobject_to_json_pretty(obj, true);
|
||||||
|
assert(str != NULL);
|
||||||
|
@@ -2832,13 +2832,13 @@ static void dump_json_image_info_list(ImageInfoList *list)
|
||||||
|
g_string_free(str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_json_image_info(ImageInfo *info)
|
||||||
|
+static void dump_json_block_node_info(BlockNodeInfo *info)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
QObject *obj;
|
||||||
|
Visitor *v = qobject_output_visitor_new(&obj);
|
||||||
|
|
||||||
|
- visit_type_ImageInfo(v, NULL, &info, &error_abort);
|
||||||
|
+ visit_type_BlockNodeInfo(v, NULL, &info, &error_abort);
|
||||||
|
visit_complete(v, &obj);
|
||||||
|
str = qobject_to_json_pretty(obj, true);
|
||||||
|
assert(str != NULL);
|
||||||
|
@@ -2848,9 +2848,9 @@ static void dump_json_image_info(ImageInfo *info)
|
||||||
|
g_string_free(str, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dump_human_image_info_list(ImageInfoList *list)
|
||||||
|
+static void dump_human_image_info_list(BlockNodeInfoList *list)
|
||||||
|
{
|
||||||
|
- ImageInfoList *elem;
|
||||||
|
+ BlockNodeInfoList *elem;
|
||||||
|
bool delim = false;
|
||||||
|
|
||||||
|
for (elem = list; elem; elem = elem->next) {
|
||||||
|
@@ -2859,7 +2859,7 @@ static void dump_human_image_info_list(ImageInfoList *list)
|
||||||
|
}
|
||||||
|
delim = true;
|
||||||
|
|
||||||
|
- bdrv_image_info_dump(elem->value);
|
||||||
|
+ bdrv_node_info_dump(elem->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2869,24 +2869,24 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- * Open an image file chain and return an ImageInfoList
|
||||||
|
+ * Open an image file chain and return an BlockNodeInfoList
|
||||||
|
*
|
||||||
|
* @filename: topmost image filename
|
||||||
|
* @fmt: topmost image format (may be NULL to autodetect)
|
||||||
|
* @chain: true - enumerate entire backing file chain
|
||||||
|
* false - only topmost image file
|
||||||
|
*
|
||||||
|
- * Returns a list of ImageInfo objects or NULL if there was an error opening an
|
||||||
|
- * image file. If there was an error a message will have been printed to
|
||||||
|
- * stderr.
|
||||||
|
+ * Returns a list of BlockNodeInfo objects or NULL if there was an error
|
||||||
|
+ * opening an image file. If there was an error a message will have been
|
||||||
|
+ * printed to stderr.
|
||||||
|
*/
|
||||||
|
-static ImageInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
- const char *filename,
|
||||||
|
- const char *fmt,
|
||||||
|
- bool chain, bool force_share)
|
||||||
|
+static BlockNodeInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
+ const char *filename,
|
||||||
|
+ const char *fmt,
|
||||||
|
+ bool chain, bool force_share)
|
||||||
|
{
|
||||||
|
- ImageInfoList *head = NULL;
|
||||||
|
- ImageInfoList **tail = &head;
|
||||||
|
+ BlockNodeInfoList *head = NULL;
|
||||||
|
+ BlockNodeInfoList **tail = &head;
|
||||||
|
GHashTable *filenames;
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
|
@@ -2895,7 +2895,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
while (filename) {
|
||||||
|
BlockBackend *blk;
|
||||||
|
BlockDriverState *bs;
|
||||||
|
- ImageInfo *info;
|
||||||
|
+ BlockNodeInfo *info;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
|
||||||
|
error_report("Backing file '%s' creates an infinite loop.",
|
||||||
|
@@ -2912,7 +2912,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
}
|
||||||
|
bs = blk_bs(blk);
|
||||||
|
|
||||||
|
- bdrv_query_image_info(bs, &info, &err);
|
||||||
|
+ bdrv_query_block_node_info(bs, &info, &err);
|
||||||
|
if (err) {
|
||||||
|
error_report_err(err);
|
||||||
|
blk_unref(blk);
|
||||||
|
@@ -2945,7 +2945,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
|
||||||
|
return head;
|
||||||
|
|
||||||
|
err:
|
||||||
|
- qapi_free_ImageInfoList(head);
|
||||||
|
+ qapi_free_BlockNodeInfoList(head);
|
||||||
|
g_hash_table_destroy(filenames);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -2956,7 +2956,7 @@ static int img_info(int argc, char **argv)
|
||||||
|
OutputFormat output_format = OFORMAT_HUMAN;
|
||||||
|
bool chain = false;
|
||||||
|
const char *filename, *fmt, *output;
|
||||||
|
- ImageInfoList *list;
|
||||||
|
+ BlockNodeInfoList *list;
|
||||||
|
bool image_opts = false;
|
||||||
|
bool force_share = false;
|
||||||
|
|
||||||
|
@@ -3035,14 +3035,14 @@ static int img_info(int argc, char **argv)
|
||||||
|
break;
|
||||||
|
case OFORMAT_JSON:
|
||||||
|
if (chain) {
|
||||||
|
- dump_json_image_info_list(list);
|
||||||
|
+ dump_json_block_node_info_list(list);
|
||||||
|
} else {
|
||||||
|
- dump_json_image_info(list->value);
|
||||||
|
+ dump_json_block_node_info(list->value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- qapi_free_ImageInfoList(list);
|
||||||
|
+ qapi_free_BlockNodeInfoList(list);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,70 @@
|
|||||||
|
From d0d3d694b3a8d200442484ae0c9d263e0439cd04 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 20:14:53 +0100
|
||||||
|
Subject: [PATCH 03/20] qemu-img bitmap: Report errors while closing the image
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-MergeRequest: 143: qemu-img: Fix exit code for errors closing the image
|
||||||
|
RH-Bugzilla: 2150180
|
||||||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||||
|
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [3/4] 4a704fec2e3bcb47b2be1529e27fd1833d58c517 (kmwolf/centos-qemu-kvm)
|
||||||
|
|
||||||
|
blk_unref() can't report any errors that happen while closing the image.
|
||||||
|
For example, if qcow2 hits an -ENOSPC error while writing out dirty
|
||||||
|
bitmaps when it's closed, it prints error messages to stderr, but
|
||||||
|
'qemu-img bitmap' won't see any error return value and will therefore
|
||||||
|
look successful with exit code 0.
|
||||||
|
|
||||||
|
In order to fix this, manually inactivate the image first before calling
|
||||||
|
blk_unref(). This already performs the operations that would be most
|
||||||
|
likely to fail while closing the image, but it can still return errors.
|
||||||
|
|
||||||
|
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1330
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Message-Id: <20230112191454.169353-4-kwolf@redhat.com>
|
||||||
|
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit c5e477110dcb8ef4642dce399777c3dee68fa96c)
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
---
|
||||||
|
qemu-img.c | 11 +++++++++++
|
||||||
|
1 file changed, 11 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index 3cbdda9f76..2f85bb7ede 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -4646,6 +4646,7 @@ static int img_bitmap(int argc, char **argv)
|
||||||
|
QSIMPLEQ_HEAD(, ImgBitmapAction) actions;
|
||||||
|
ImgBitmapAction *act, *act_next;
|
||||||
|
const char *op;
|
||||||
|
+ int inactivate_ret;
|
||||||
|
|
||||||
|
QSIMPLEQ_INIT(&actions);
|
||||||
|
|
||||||
|
@@ -4830,6 +4831,16 @@ static int img_bitmap(int argc, char **argv)
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
+ /*
|
||||||
|
+ * Manually inactivate the images first because this way we can know whether
|
||||||
|
+ * an error occurred. blk_unref() doesn't tell us about failures.
|
||||||
|
+ */
|
||||||
|
+ inactivate_ret = bdrv_inactivate_all();
|
||||||
|
+ if (inactivate_ret < 0) {
|
||||||
|
+ error_report("Error while closing the image: %s", strerror(-inactivate_ret));
|
||||||
|
+ ret = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
blk_unref(src);
|
||||||
|
blk_unref(blk);
|
||||||
|
qemu_opts_del(opts);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,67 @@
|
|||||||
|
From 2f5369f0effaa23be746f9b5d9f6a0bfc346fb7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 20:14:52 +0100
|
||||||
|
Subject: [PATCH 02/20] qemu-img commit: Report errors while closing the image
|
||||||
|
|
||||||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-MergeRequest: 143: qemu-img: Fix exit code for errors closing the image
|
||||||
|
RH-Bugzilla: 2150180
|
||||||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||||
|
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [2/4] faedd43355463b1210a3f21ecd430f478bd06f5a (kmwolf/centos-qemu-kvm)
|
||||||
|
|
||||||
|
blk_unref() can't report any errors that happen while closing the image.
|
||||||
|
For example, if qcow2 hits an -ENOSPC error while writing out dirty
|
||||||
|
bitmaps when it's closed, it prints error messages to stderr, but
|
||||||
|
'qemu-img commit' won't see any error return value and will therefore
|
||||||
|
look successful with exit code 0.
|
||||||
|
|
||||||
|
In order to fix this, manually inactivate the image first before calling
|
||||||
|
blk_unref(). This already performs the operations that would be most
|
||||||
|
likely to fail while closing the image, but it can still return errors.
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Message-Id: <20230112191454.169353-3-kwolf@redhat.com>
|
||||||
|
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 44efba2d713aca076c411594d0c1a2b99155eeb3)
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
---
|
||||||
|
qemu-img.c | 13 +++++++++++++
|
||||||
|
1 file changed, 13 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/qemu-img.c b/qemu-img.c
|
||||||
|
index a9b3a8103c..3cbdda9f76 100644
|
||||||
|
--- a/qemu-img.c
|
||||||
|
+++ b/qemu-img.c
|
||||||
|
@@ -449,6 +449,11 @@ static BlockBackend *img_open(bool image_opts,
|
||||||
|
blk = img_open_file(filename, NULL, fmt, flags, writethrough, quiet,
|
||||||
|
force_share);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (blk) {
|
||||||
|
+ blk_set_force_allow_inactivate(blk);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1119,6 +1124,14 @@ unref_backing:
|
||||||
|
done:
|
||||||
|
qemu_progress_end();
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Manually inactivate the image first because this way we can know whether
|
||||||
|
+ * an error occurred. blk_unref() doesn't tell us about failures.
|
||||||
|
+ */
|
||||||
|
+ ret = bdrv_inactivate_all();
|
||||||
|
+ if (ret < 0 && !local_err) {
|
||||||
|
+ error_setg_errno(&local_err, -ret, "Error while closing the image");
|
||||||
|
+ }
|
||||||
|
blk_unref(blk);
|
||||||
|
|
||||||
|
if (local_err) {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
166
kvm-qemu-iotests-Test-qemu-img-bitmap-commit-exit-code-o.patch
Normal file
166
kvm-qemu-iotests-Test-qemu-img-bitmap-commit-exit-code-o.patch
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
From 06030aa79fcb2d90d6a670e75d959aa0c3204b5c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Date: Thu, 12 Jan 2023 20:14:54 +0100
|
||||||
|
Subject: [PATCH 04/20] qemu-iotests: Test qemu-img bitmap/commit exit code on
|
||||||
|
error
|
||||||
|
|
||||||
|
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
RH-MergeRequest: 143: qemu-img: Fix exit code for errors closing the image
|
||||||
|
RH-Bugzilla: 2150180
|
||||||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||||
|
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
||||||
|
RH-Commit: [4/4] b96bb671bcfb7ae18015fda14db70f42a83a6ea7 (kmwolf/centos-qemu-kvm)
|
||||||
|
|
||||||
|
This tests that when an error happens while writing back bitmaps to the
|
||||||
|
image file in qcow2_inactivate(), 'qemu-img bitmap/commit' actually
|
||||||
|
return an error value in their exit code instead of making the operation
|
||||||
|
look successful to scripts.
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Message-Id: <20230112191454.169353-5-kwolf@redhat.com>
|
||||||
|
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
(cherry picked from commit 07a4e1f8e5418f36424cd57d5d061b090a238c65)
|
||||||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
---
|
||||||
|
.../qemu-iotests/tests/qemu-img-close-errors | 96 +++++++++++++++++++
|
||||||
|
.../tests/qemu-img-close-errors.out | 23 +++++
|
||||||
|
2 files changed, 119 insertions(+)
|
||||||
|
create mode 100755 tests/qemu-iotests/tests/qemu-img-close-errors
|
||||||
|
create mode 100644 tests/qemu-iotests/tests/qemu-img-close-errors.out
|
||||||
|
|
||||||
|
diff --git a/tests/qemu-iotests/tests/qemu-img-close-errors b/tests/qemu-iotests/tests/qemu-img-close-errors
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000000..50bfb6cfa2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemu-iotests/tests/qemu-img-close-errors
|
||||||
|
@@ -0,0 +1,96 @@
|
||||||
|
+#!/usr/bin/env bash
|
||||||
|
+# group: rw auto quick
|
||||||
|
+#
|
||||||
|
+# Check that errors while closing the image, in particular writing back dirty
|
||||||
|
+# bitmaps, is correctly reported with a failing qemu-img exit code.
|
||||||
|
+#
|
||||||
|
+# Copyright (C) 2023 Red Hat, Inc.
|
||||||
|
+#
|
||||||
|
+# This program is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of the GNU General Public License as published by
|
||||||
|
+# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
+# (at your option) any later version.
|
||||||
|
+#
|
||||||
|
+# This program is distributed in the hope that it will be useful,
|
||||||
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+# GNU General Public License for more details.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+# creator
|
||||||
|
+owner=kwolf@redhat.com
|
||||||
|
+
|
||||||
|
+seq="$(basename $0)"
|
||||||
|
+echo "QA output created by $seq"
|
||||||
|
+
|
||||||
|
+status=1 # failure is the default!
|
||||||
|
+
|
||||||
|
+_cleanup()
|
||||||
|
+{
|
||||||
|
+ _cleanup_test_img
|
||||||
|
+}
|
||||||
|
+trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||||
|
+
|
||||||
|
+# get standard environment, filters and checks
|
||||||
|
+cd ..
|
||||||
|
+. ./common.rc
|
||||||
|
+. ./common.filter
|
||||||
|
+
|
||||||
|
+_supported_fmt qcow2
|
||||||
|
+_supported_proto file
|
||||||
|
+_supported_os Linux
|
||||||
|
+
|
||||||
|
+size=1G
|
||||||
|
+
|
||||||
|
+# The error we are going to use is ENOSPC. Depending on how many bitmaps we
|
||||||
|
+# create in the backing file (and therefore increase the used up space), we get
|
||||||
|
+# failures in different places. With a low number, only merging the bitmap
|
||||||
|
+# fails, whereas with a higher number, already 'qemu-img commit' fails.
|
||||||
|
+for max_bitmap in 6 7; do
|
||||||
|
+ echo
|
||||||
|
+ echo "=== Test with $max_bitmap bitmaps ==="
|
||||||
|
+
|
||||||
|
+ TEST_IMG="$TEST_IMG.base" _make_test_img -q $size
|
||||||
|
+ for i in $(seq 1 $max_bitmap); do
|
||||||
|
+ $QEMU_IMG bitmap --add "$TEST_IMG.base" "stale-bitmap-$i"
|
||||||
|
+ done
|
||||||
|
+
|
||||||
|
+ # Simulate a block device of 128 MB by resizing the image file accordingly
|
||||||
|
+ # and then enforcing the size with the raw driver
|
||||||
|
+ $QEMU_IO -f raw -c "truncate 128M" "$TEST_IMG.base"
|
||||||
|
+ BASE_JSON='json:{
|
||||||
|
+ "driver": "qcow2",
|
||||||
|
+ "file": {
|
||||||
|
+ "driver": "raw",
|
||||||
|
+ "size": 134217728,
|
||||||
|
+ "file": {
|
||||||
|
+ "driver": "file",
|
||||||
|
+ "filename":"'"$TEST_IMG.base"'"
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }'
|
||||||
|
+
|
||||||
|
+ _make_test_img -q -b "$BASE_JSON" -F $IMGFMT
|
||||||
|
+ $QEMU_IMG bitmap --add "$TEST_IMG" "good-bitmap"
|
||||||
|
+
|
||||||
|
+ $QEMU_IO -c 'write 0 126m' "$TEST_IMG" | _filter_qemu_io
|
||||||
|
+
|
||||||
|
+ $QEMU_IMG commit -d "$TEST_IMG" 2>&1 | _filter_generated_node_ids
|
||||||
|
+ echo "qemu-img commit exit code: ${PIPESTATUS[0]}"
|
||||||
|
+
|
||||||
|
+ $QEMU_IMG bitmap --add "$BASE_JSON" "good-bitmap"
|
||||||
|
+ echo "qemu-img bitmap --add exit code: $?"
|
||||||
|
+
|
||||||
|
+ $QEMU_IMG bitmap --merge "good-bitmap" -b "$TEST_IMG" "$BASE_JSON" \
|
||||||
|
+ "good-bitmap" 2>&1 | _filter_generated_node_ids
|
||||||
|
+ echo "qemu-img bitmap --merge exit code: ${PIPESTATUS[0]}"
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+# success, all done
|
||||||
|
+echo "*** done"
|
||||||
|
+rm -f $seq.full
|
||||||
|
+status=0
|
||||||
|
+
|
||||||
|
diff --git a/tests/qemu-iotests/tests/qemu-img-close-errors.out b/tests/qemu-iotests/tests/qemu-img-close-errors.out
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..1bfe88f176
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/qemu-iotests/tests/qemu-img-close-errors.out
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+QA output created by qemu-img-close-errors
|
||||||
|
+
|
||||||
|
+=== Test with 6 bitmaps ===
|
||||||
|
+wrote 132120576/132120576 bytes at offset 0
|
||||||
|
+126 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
|
+Image committed.
|
||||||
|
+qemu-img commit exit code: 0
|
||||||
|
+qemu-img bitmap --add exit code: 0
|
||||||
|
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'good-bitmap' to file: No space left on device
|
||||||
|
+qemu-img: Error while closing the image: Invalid argument
|
||||||
|
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'good-bitmap' to file: No space left on device
|
||||||
|
+qemu-img bitmap --merge exit code: 1
|
||||||
|
+
|
||||||
|
+=== Test with 7 bitmaps ===
|
||||||
|
+wrote 132120576/132120576 bytes at offset 0
|
||||||
|
+126 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
|
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'stale-bitmap-7' to file: No space left on device
|
||||||
|
+qemu-img: Lost persistent bitmaps during inactivation of node 'NODE_NAME': Failed to write bitmap 'stale-bitmap-7' to file: No space left on device
|
||||||
|
+qemu-img: Error while closing the image: Invalid argument
|
||||||
|
+qemu-img commit exit code: 1
|
||||||
|
+qemu-img bitmap --add exit code: 0
|
||||||
|
+qemu-img bitmap --merge exit code: 0
|
||||||
|
+*** done
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From 5413b8825db6eecc6f245854a6bce58e4dee3294 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||||
|
Date: Tue, 7 Feb 2023 17:57:39 +0000
|
||||||
|
Subject: [PATCH 20/20] virtio-rng-pci: fix transitional migration compat for
|
||||||
|
vectors
|
||||||
|
|
||||||
|
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||||
|
RH-MergeRequest: 147: virtio-rng-pci: fix transitional migration compat for vectors
|
||||||
|
RH-Bugzilla: 2162569
|
||||||
|
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
||||||
|
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
||||||
|
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
RH-Commit: [1/1] 6e2bd111cd56808fccf2c0464a40f7784fd893a2 (dagrh/c-9-s-qemu-kvm)
|
||||||
|
|
||||||
|
In upstream bad9c5a5166/downstream 46e08bafe9ed I fixed the virito-rng-pci
|
||||||
|
migration compatibility, but it was discovered that we also need to fix
|
||||||
|
the other aliases of the device for the transitional cases.
|
||||||
|
|
||||||
|
I've sent upstream:
|
||||||
|
https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg01926.html
|
||||||
|
but downstream we need to change the downstream machine type anyway,
|
||||||
|
so it's not quite identical.
|
||||||
|
|
||||||
|
Fixes: 9ea02e8f1 ('virtio-rng-pci: Allow setting nvectors, so we can use MSI-X')
|
||||||
|
|
||||||
|
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||||
|
---
|
||||||
|
hw/core/machine.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/core/machine.c b/hw/core/machine.c
|
||||||
|
index 7adbac6f87..3ee638394b 100644
|
||||||
|
--- a/hw/core/machine.c
|
||||||
|
+++ b/hw/core/machine.c
|
||||||
|
@@ -58,6 +58,9 @@ GlobalProperty hw_compat_rhel_9_1[] = {
|
||||||
|
{ "virtio-device", "queue_reset", "false" },
|
||||||
|
/* hw_compat_rhel_9_1 bz 2155749 */
|
||||||
|
{ "virtio-rng-pci", "vectors", "0" },
|
||||||
|
+ /* hw_compat_rhel_9_1 bz 2162569 */
|
||||||
|
+ { "virtio-rng-pci-transitional", "vectors", "0" },
|
||||||
|
+ { "virtio-rng-pci-non-transitional", "vectors", "0" },
|
||||||
|
};
|
||||||
|
const size_t hw_compat_rhel_9_1_len = G_N_ELEMENTS(hw_compat_rhel_9_1);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -148,7 +148,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
|
|||||||
Summary: QEMU is a machine emulator and virtualizer
|
Summary: QEMU is a machine emulator and virtualizer
|
||||||
Name: qemu-kvm
|
Name: qemu-kvm
|
||||||
Version: 7.2.0
|
Version: 7.2.0
|
||||||
Release: 7%{?rcrel}%{?dist}%{?cc_suffix}
|
Release: 8%{?rcrel}%{?dist}%{?cc_suffix}
|
||||||
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
||||||
# Epoch 15 used for RHEL 8
|
# Epoch 15 used for RHEL 8
|
||||||
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
||||||
@ -316,6 +316,46 @@ Patch83: kvm-vdpa-add-shadow_data-to-vhost_vdpa.patch
|
|||||||
Patch84: kvm-vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch
|
Patch84: kvm-vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch
|
||||||
# For bz#2104412 - vDPA ASID support in Qemu
|
# For bz#2104412 - vDPA ASID support in Qemu
|
||||||
Patch85: kvm-vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch
|
Patch85: kvm-vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch
|
||||||
|
# For bz#2150180 - qemu-img finishes successfully while having errors in commit or bitmaps operations
|
||||||
|
Patch86: kvm-qcow2-Fix-theoretical-corruption-in-store_bitmap-err.patch
|
||||||
|
# For bz#2150180 - qemu-img finishes successfully while having errors in commit or bitmaps operations
|
||||||
|
Patch87: kvm-qemu-img-commit-Report-errors-while-closing-the-imag.patch
|
||||||
|
# For bz#2150180 - qemu-img finishes successfully while having errors in commit or bitmaps operations
|
||||||
|
Patch88: kvm-qemu-img-bitmap-Report-errors-while-closing-the-imag.patch
|
||||||
|
# For bz#2150180 - qemu-img finishes successfully while having errors in commit or bitmaps operations
|
||||||
|
Patch89: kvm-qemu-iotests-Test-qemu-img-bitmap-commit-exit-code-o.patch
|
||||||
|
# For bz#2165280 - [kvm-unit-tests] debug-wp-migration fails
|
||||||
|
Patch90: kvm-accel-tcg-Test-CPUJumpCache-in-tb_jmp_cache_clear_pa.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch91: kvm-block-Improve-empty-format-specific-info-dump.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch92: kvm-block-file-Add-file-specific-image-info.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch93: kvm-block-vmdk-Change-extent-info-type.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch94: kvm-block-Split-BlockNodeInfo-off-of-ImageInfo.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch95: kvm-qemu-img-Use-BlockNodeInfo.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch96: kvm-block-qapi-Let-bdrv_query_image_info-recurse.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch97: kvm-block-qapi-Introduce-BlockGraphInfo.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch98: kvm-block-qapi-Add-indentation-to-bdrv_node_info_dump.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch99: kvm-iotests-Filter-child-node-information.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch100: kvm-iotests-106-214-308-Read-only-one-size-line.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch101: kvm-qemu-img-Let-info-print-block-graph.patch
|
||||||
|
# For bz#1860292 - RFE: add extent_size_hint information to qemu-img info
|
||||||
|
Patch102: kvm-qemu-img-Change-info-key-names-for-protocol-nodes.patch
|
||||||
|
# For bz#2155173 - [vhost-user] unable to start vhost net: 71: falling back on userspace
|
||||||
|
Patch103: kvm-Revert-vhost-user-Monitor-slave-channel-in-vhost_use.patch
|
||||||
|
# For bz#2155173 - [vhost-user] unable to start vhost net: 71: falling back on userspace
|
||||||
|
Patch104: kvm-Revert-vhost-user-Introduce-nested-event-loop-in-vho.patch
|
||||||
|
# For bz#2162569 - [transitional device][virtio-rng-pci-transitional]Stable Guest ABI failed between RHEL 8.6 to RHEL 9.2
|
||||||
|
Patch105: kvm-virtio-rng-pci-fix-transitional-migration-compat-for.patch
|
||||||
|
|
||||||
%if %{have_clang}
|
%if %{have_clang}
|
||||||
BuildRequires: clang
|
BuildRequires: clang
|
||||||
@ -1346,6 +1386,38 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Feb 09 2023 Miroslav Rezanina <mrezanin@redhat.com> - 7.2.0-8
|
||||||
|
- kvm-qcow2-Fix-theoretical-corruption-in-store_bitmap-err.patch [bz#2150180]
|
||||||
|
- kvm-qemu-img-commit-Report-errors-while-closing-the-imag.patch [bz#2150180]
|
||||||
|
- kvm-qemu-img-bitmap-Report-errors-while-closing-the-imag.patch [bz#2150180]
|
||||||
|
- kvm-qemu-iotests-Test-qemu-img-bitmap-commit-exit-code-o.patch [bz#2150180]
|
||||||
|
- kvm-accel-tcg-Test-CPUJumpCache-in-tb_jmp_cache_clear_pa.patch [bz#2165280]
|
||||||
|
- kvm-block-Improve-empty-format-specific-info-dump.patch [bz#1860292]
|
||||||
|
- kvm-block-file-Add-file-specific-image-info.patch [bz#1860292]
|
||||||
|
- kvm-block-vmdk-Change-extent-info-type.patch [bz#1860292]
|
||||||
|
- kvm-block-Split-BlockNodeInfo-off-of-ImageInfo.patch [bz#1860292]
|
||||||
|
- kvm-qemu-img-Use-BlockNodeInfo.patch [bz#1860292]
|
||||||
|
- kvm-block-qapi-Let-bdrv_query_image_info-recurse.patch [bz#1860292]
|
||||||
|
- kvm-block-qapi-Introduce-BlockGraphInfo.patch [bz#1860292]
|
||||||
|
- kvm-block-qapi-Add-indentation-to-bdrv_node_info_dump.patch [bz#1860292]
|
||||||
|
- kvm-iotests-Filter-child-node-information.patch [bz#1860292]
|
||||||
|
- kvm-iotests-106-214-308-Read-only-one-size-line.patch [bz#1860292]
|
||||||
|
- kvm-qemu-img-Let-info-print-block-graph.patch [bz#1860292]
|
||||||
|
- kvm-qemu-img-Change-info-key-names-for-protocol-nodes.patch [bz#1860292]
|
||||||
|
- kvm-Revert-vhost-user-Monitor-slave-channel-in-vhost_use.patch [bz#2155173]
|
||||||
|
- kvm-Revert-vhost-user-Introduce-nested-event-loop-in-vho.patch [bz#2155173]
|
||||||
|
- kvm-virtio-rng-pci-fix-transitional-migration-compat-for.patch [bz#2162569]
|
||||||
|
- Resolves: bz#2150180
|
||||||
|
(qemu-img finishes successfully while having errors in commit or bitmaps operations)
|
||||||
|
- Resolves: bz#2165280
|
||||||
|
([kvm-unit-tests] debug-wp-migration fails)
|
||||||
|
- Resolves: bz#1860292
|
||||||
|
(RFE: add extent_size_hint information to qemu-img info)
|
||||||
|
- Resolves: bz#2155173
|
||||||
|
([vhost-user] unable to start vhost net: 71: falling back on userspace)
|
||||||
|
- Resolves: bz#2162569
|
||||||
|
([transitional device][virtio-rng-pci-transitional]Stable Guest ABI failed between RHEL 8.6 to RHEL 9.2)
|
||||||
|
|
||||||
* Mon Feb 06 2023 Miroslav Rezanina <mrezanin@redhat.com> - 7.2.0-7
|
* Mon Feb 06 2023 Miroslav Rezanina <mrezanin@redhat.com> - 7.2.0-7
|
||||||
- kvm-vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch [bz#2104412]
|
- kvm-vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch [bz#2104412]
|
||||||
- kvm-vhost-set-SVQ-device-call-handler-at-SVQ-start.patch [bz#2104412]
|
- kvm-vhost-set-SVQ-device-call-handler-at-SVQ-start.patch [bz#2104412]
|
||||||
|
Loading…
Reference in New Issue
Block a user