* 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
|
||||
Name: qemu-kvm
|
||||
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 15 used for RHEL 8
|
||||
# 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
|
||||
# For bz#2104412 - vDPA ASID support in Qemu
|
||||
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}
|
||||
BuildRequires: clang
|
||||
@ -1346,6 +1386,38 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
|
||||
%endif
|
||||
|
||||
%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
|
||||
- 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]
|
||||
|
Loading…
Reference in New Issue
Block a user