* 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:
Miroslav Rezanina 2023-02-09 09:45:40 -05:00
parent 9b81b4ad6b
commit a6628605f7
21 changed files with 3021 additions and 1 deletions

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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]