* [PATCH v2 00/39] Make HMP optional (and later standalone)
@ 2026-06-25 21:19 Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 01/39] vl: fix -monitor none prefix matching Marc-André Lureau
` (39 more replies)
0 siblings, 40 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster, Eric Farman,
Philippe Mathieu-Daudé
Hi,
This series makes HMP compile-time optional via --disable-hmp. The
resulting binary speaks only QMP - reducing the attack surface, binary
size and enforcing a separation between machine-readable interface and
interactive debugging console.
QMP offers almost all the functionality HMP could provide, so a separate
standalone "HMP-like" console could be implemented on top of it. The
rough list of missing commands (+complexity estimation) after this
series:
Debugging / introspection:
- info registers (medium) - plus $reg expression handling
- x/xp read memory (medium)
- gpa2hpa/gpa2hva/gva2gpa address translation (medium)
- info lapic (high) - deep x86 APIC state, lots of registers
- info mem (high) - virtual memory mappings, different per arch
- info tlb (high) - virt-to-phys mappings, also per arch
- info mtree (high) - memory region tree, multiple view modes
- info skeys (medium) - s390x storage keys
- info cmma (medium) - s390x CMMA values
- info qdm (easy) - could probably be folded into QOM introspection
- info qtree (medium) - same, maybe QOM introspection is enough
- info snapshots (medium)
- info usbhost (medium)
- info via (medium) -- VIA south bridge state
Simple actions / settings:
- gdbserver (trivial)
- boot_set (easy)
- mce (easy) - x86 MCE injection
- sum (easy) - memory checksum
- sync-profile (easy) - enable/disable/reset
- info sync-profile (medium)
- one-insn-per-tb (easy) - could be a QOM property on the accelerator
- pcie_aer_inject_error (easy)
- migration_mode (medium?)
- i/o ioport read/write (easy)
- hostfwd-add/hostfwd-remove (medium) - slirp port forwarding
- log/logfile (medium)
- trace-file (medium)
Also, to let clients do disassembly on their side, it'd be useful to
have something like "query-disassemble-info" that gives the client what
architecture and endianness is used etc.
In the meantime, being able to build without HMP is valuable and helps
identifying the missing pieces. The series does so by steps:
- preparatory cleanups and bug fixes
- add commands without QMP equivalent and needed for tests
- convert most iotests and qtests from HMP to QMP
- guard HMP-only code paths
- make HMP source files conditional in the build system
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Changes in v2:
- add "target/i386: return an error for invalid CPU in hmp_mce()",
suggested by Philippe
- drop all the patches converting iotests to QMP - instead skip
when HMP is disabled. The series was getting significantly bigger with
those, we can address the remaining conversion later.
- clean up the series to be fully bisectable
- rebased, add r-b trailers
- Link to v1: https://lore.kernel.org/qemu-devel/20260521-qemu-no-hmp-v1-0-d104f809e145@redhat.com
To: qemu-devel@nongnu.org
Cc: Philippe Mathieu-Daudé <philmd@mailo.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
---
Marc-André Lureau (39):
vl: fix -monitor none prefix matching
hmp: remove 'vcpu' argument from trace-event help
hmp: fix snapshot_blkdev argument type
target/i386: decouple cpu_x86_inject_mce() from Monitor
target/i386: return an error for invalid CPU in hmp_mce()
system: move gpa2hva() to system memory unit
s390x: prevent crash if given invalid CPU#
system: decouple qmp_inject_nmi() from Monitor
hmp: correct the nmi documentation
monitor: move HMP-only fields from Monitor to MonitorHMP
tests/functional: use query-version QMP command instead of HMP
net/qapi: add x-query-usernet command
python, tests: switch usernet queries from HMP to QMP
tests/qtest/pnv: drop unnecessary -serial mon:stdio
tests/qtest/qmp-test: don't depend on human-monitor-command
tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast
tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
tests/qtest/device-introspect-test: fix test without HMP
tests/qemu-iotests/205: fix race in assertExportNotFound
net: add x-query-network QMP command
tests/qtest/netdev-socket: replace HMP with x-query-network QMP
qemu-io: propagate errors through Error API instead of printf
RFC: qtest: add qemu-io command to the qtest protocol
RFC: qtest/ide-test: convert to use qtest qemu-io command
block: add x-qemu-io QMP command
tests/qemu-iotests: add qmp_qemu_io()
tests/qemu-iotests: convert pause/resume_drive() to QMP
build-sys: add 'hmp' option
monitor: reject readline monitor when HMP is disabled
tests: skip HMP-dependent tests when HMP is disabled
util: guard monitor_vprintf callers with CONFIG_HMP
qapi: make HMP-specific schema entries conditional on CONFIG_HMP
system: guard HMP initialization paths with CONFIG_HMP
Guard HMP command implementations with CONFIG_HMP
target: guard MonitorDef tables with CONFIG_HMP
hw: guard BusClass::print_dev with CONFIG_HMP
build-sys: make HMP source files conditional on have_hmp
monitor: guard HMP internal helpers with CONFIG_HMP
monitor: guard HMP monitor API with CONFIG_HMP
meson.build | 6 +-
qapi/block.json | 34 ++
qapi/control.json | 4 +-
qapi/machine.json | 5 +-
qapi/misc.json | 3 +-
qapi/net.json | 166 +++++++++
include/hw/core/qdev.h | 2 +
include/hw/core/sysemu-cpu-ops.h | 2 +
include/monitor/monitor.h | 11 +-
include/net/net.h | 3 +-
include/qemu-io.h | 4 +-
include/system/memory.h | 2 +
monitor/monitor-internal.h | 4 +-
net/hub.h | 4 +-
target/i386/cpu.h | 4 +-
tests/qtest/libqtest.h | 11 +
accel/accel-system.c | 2 +
accel/tcg/monitor.c | 2 +
block/monitor/block-hmp-cmds.c | 60 +--
block/monitor/qmp-cmds.c | 79 ++++
chardev/char.c | 7 +
gdbstub/system.c | 8 +
hw/char/virtio-serial-bus.c | 6 +
hw/core/sysbus.c | 6 +
hw/i386/kvm/xen-stubs.c | 2 +
hw/i386/kvm/xen_evtchn.c | 3 +-
hw/i386/sgx.c | 2 +
hw/misc/auxbus.c | 16 +-
hw/misc/mos6522-stub.c | 2 +
hw/misc/mos6522.c | 2 +
hw/pci/pci-stub.c | 2 +
hw/pci/pci.c | 2 +
hw/s390x/s390-skeys.c | 2 +
hw/s390x/s390-stattrib.c | 4 +
hw/s390x/s390-virtio-ccw.c | 5 +
hw/uefi/ovmf-log.c | 2 +
hw/usb/bus.c | 6 +
hw/usb/host-libusb.c | 6 +
hw/xen/xen-bus.c | 4 +
migration/dirtyrate.c | 2 +
monitor/hmp-cmds.c | 53 +--
monitor/hmp.c | 7 +-
monitor/monitor.c | 47 ++-
monitor/qmp-cmds.c | 2 +
net/hub.c | 29 +-
net/net-hmp-cmds.c | 59 ++-
net/net.c | 70 +++-
net/slirp.c | 41 +-
qemu-io-cmds.c | 414 +++++++++++----------
qemu-io.c | 17 +-
replay/replay-debugging.c | 8 +
replay/stubs-system.c | 6 +
stubs/monitor-core.c | 2 +
stubs/monitor-internal.c | 2 +
system/cpus.c | 7 +-
system/dirtylimit.c | 6 +
system/physmem.c | 31 ++
system/qdev-monitor.c | 4 +
system/qtest.c | 14 +
system/vl.c | 6 +-
target/i386/cpu-apic.c | 2 +
target/i386/cpu.c | 4 +
target/i386/helper.c | 49 +--
target/i386/kvm/kvm.c | 4 +-
target/i386/monitor.c | 13 +-
target/i386/sev.c | 2 +
target/m68k/cpu.c | 4 +
target/m68k/monitor.c | 2 +
target/ppc/monitor.c | 2 +
target/riscv/monitor.c | 3 +
target/sh4/monitor.c | 2 +
target/sparc/cpu.c | 5 +-
target/sparc/monitor.c | 2 +
target/xtensa/monitor.c | 2 +
tests/qtest/cdrom-test.c | 29 +-
tests/qtest/device-introspect-test.c | 111 ++++--
tests/qtest/drive_del-test.c | 25 ++
tests/qtest/ide-test.c | 4 +-
tests/qtest/libqtest.c | 14 +
tests/qtest/netdev-socket.c | 143 ++++---
tests/qtest/numa-test.c | 63 +++-
tests/qtest/pnv-host-i2c-test.c | 2 +-
tests/qtest/pnv-xive2-test.c | 2 +-
tests/qtest/qmp-test.c | 9 +-
tests/unit/test-util-sockets.c | 4 +-
tools/qemu-vnc/stubs.c | 2 +
util/error-report.c | 8 +-
util/qemu-print.c | 6 +
audio/meson.build | 4 +-
backends/meson.build | 5 +-
block/monitor/meson.build | 5 +-
chardev/meson.build | 5 +-
disas/meson.build | 4 +-
dump/meson.build | 5 +-
hmp-commands-info.hx | 6 +-
hmp-commands.hx | 14 +-
hw/core/meson.build | 5 +-
hw/i386/meson.build | 4 +-
hw/net/meson.build | 4 +-
hw/pci/meson.build | 4 +-
hw/virtio/meson.build | 4 +-
meson_options.txt | 2 +
migration/meson.build | 4 +-
monitor/meson.build | 9 +-
net/meson.build | 4 +-
python/qemu/utils/__init__.py | 5 +-
qemu-options.hx | 6 +-
qom/meson.build | 4 +-
scripts/meson-buildoptions.sh | 3 +
stats/meson.build | 5 +-
stubs/meson.build | 12 +-
system/meson.build | 9 +-
tests/functional/generic/test_version.py | 10 +-
tests/functional/qemu_test/utils.py | 8 +-
tests/qemu-iotests/004.out | 20 +-
tests/qemu-iotests/021.out | 60 +--
tests/qemu-iotests/026.out | 228 ++++++------
tests/qemu-iotests/028 | 1 +
tests/qemu-iotests/045 | 3 +-
tests/qemu-iotests/051 | 1 +
tests/qemu-iotests/056 | 3 +-
tests/qemu-iotests/060 | 1 +
tests/qemu-iotests/060.out | 44 ++-
tests/qemu-iotests/068 | 1 +
tests/qemu-iotests/071 | 1 +
tests/qemu-iotests/071.out | 10 +-
tests/qemu-iotests/072.out | 2 +-
tests/qemu-iotests/080.out | 4 +-
tests/qemu-iotests/081 | 1 +
tests/qemu-iotests/081.out | 2 +-
tests/qemu-iotests/083.out | 36 +-
tests/qemu-iotests/089.out | 4 +-
tests/qemu-iotests/091 | 1 +
tests/qemu-iotests/093 | 3 +-
tests/qemu-iotests/102 | 1 +
tests/qemu-iotests/114.out | 2 +-
tests/qemu-iotests/117 | 1 +
tests/qemu-iotests/119 | 1 +
tests/qemu-iotests/120 | 1 +
tests/qemu-iotests/124 | 3 +-
tests/qemu-iotests/130 | 1 +
tests/qemu-iotests/132 | 3 +-
tests/qemu-iotests/134.out | 2 +-
tests/qemu-iotests/136 | 3 +-
tests/qemu-iotests/137.out | 2 +-
tests/qemu-iotests/142 | 1 +
tests/qemu-iotests/145 | 1 +
tests/qemu-iotests/146 | 1 +
tests/qemu-iotests/148 | 3 +-
tests/qemu-iotests/151 | 3 +-
tests/qemu-iotests/152 | 3 +-
tests/qemu-iotests/153 | 1 +
tests/qemu-iotests/153.out | 12 +-
tests/qemu-iotests/156 | 1 +
tests/qemu-iotests/157 | 1 +
tests/qemu-iotests/161 | 1 +
tests/qemu-iotests/165 | 3 +-
tests/qemu-iotests/171 | 2 +-
tests/qemu-iotests/171.out | 68 ++--
tests/qemu-iotests/172 | 1 +
tests/qemu-iotests/181 | 1 +
tests/qemu-iotests/185 | 1 +
tests/qemu-iotests/186 | 1 +
tests/qemu-iotests/192 | 1 +
tests/qemu-iotests/201 | 1 +
tests/qemu-iotests/205 | 6 +-
tests/qemu-iotests/214.out | 2 +-
tests/qemu-iotests/216 | 3 +-
tests/qemu-iotests/220.out | 2 +-
tests/qemu-iotests/225 | 1 +
tests/qemu-iotests/225.out | 4 +-
tests/qemu-iotests/232 | 1 +
tests/qemu-iotests/236 | 3 +-
tests/qemu-iotests/244.out | 12 +-
tests/qemu-iotests/245 | 3 +-
tests/qemu-iotests/246 | 3 +-
tests/qemu-iotests/249 | 1 +
tests/qemu-iotests/249.out | 6 +-
tests/qemu-iotests/254 | 3 +-
tests/qemu-iotests/255 | 3 +-
tests/qemu-iotests/257 | 3 +-
tests/qemu-iotests/260 | 3 +-
tests/qemu-iotests/264 | 3 +-
tests/qemu-iotests/267 | 1 +
tests/qemu-iotests/271.out | 14 +-
tests/qemu-iotests/274 | 3 +-
tests/qemu-iotests/280 | 1 +
tests/qemu-iotests/281 | 3 +-
tests/qemu-iotests/283 | 1 +
tests/qemu-iotests/286 | 1 +
tests/qemu-iotests/289.out | 2 +-
tests/qemu-iotests/298 | 3 +-
tests/qemu-iotests/300 | 3 +-
tests/qemu-iotests/304 | 3 +-
tests/qemu-iotests/305.out | 2 +-
tests/qemu-iotests/307.out | 2 +-
tests/qemu-iotests/310 | 3 +-
tests/qemu-iotests/common.rc | 8 +
tests/qemu-iotests/iotests.py | 32 +-
tests/qemu-iotests/tests/backup-discard-source | 7 +-
tests/qemu-iotests/tests/copy-before-write | 69 ++--
tests/qemu-iotests/tests/file-io-error.out | 2 +-
tests/qemu-iotests/tests/image-fleecing | 3 +-
tests/qemu-iotests/tests/image-fleecing.out | 12 +-
tests/qemu-iotests/tests/inactive-node-nbd.out | 8 +-
tests/qemu-iotests/tests/iothreads-create | 3 +-
tests/qemu-iotests/tests/luks-detached-header | 3 +-
.../tests/migrate-bitmaps-postcopy-test | 3 +-
tests/qemu-iotests/tests/migrate-bitmaps-test | 3 +-
tests/qemu-iotests/tests/mirror-change-copy-mode | 3 +-
tests/qemu-iotests/tests/mirror-ready-cancel-error | 3 +-
tests/qemu-iotests/tests/qcow2-internal-snapshots | 1 +
tests/qemu-iotests/tests/qsd-migrate | 3 +-
tests/qemu-iotests/tests/reopen-file | 3 +-
tests/qemu-iotests/tests/write-zeroes-unmap | 1 +
tests/qtest/meson.build | 8 +-
tests/vm/basevm.py | 13 +-
trace/meson.build | 5 +-
ui/meson.build | 4 +-
219 files changed, 1917 insertions(+), 927 deletions(-)
---
base-commit: 1b4d5bb3e233c9fc84663be28635d122c9a2b81e
change-id: 20260521-qemu-no-hmp-ead3f0bf79c0
Best regards,
--
Marc-André Lureau <marcandre.lureau@redhat.com>
^ permalink raw reply [flat|nested] 79+ messages in thread
* [PATCH v2 01/39] vl: fix -monitor none prefix matching
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:30 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
` (38 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Use g_strcmp0() for exact match instead of strncmp() which would
incorrectly treat any string starting with "none" as disabling
the monitor.
Fixes: 70e098af88f ("monitor: allow to disable the default monitor")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
system/vl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/system/vl.c b/system/vl.c
index 1c0da7df293..dd7fe828118 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -3221,7 +3221,7 @@ void qemu_init(int argc, char **argv)
}
case QEMU_OPTION_monitor:
default_monitor = 0;
- if (strncmp(optarg, "none", 4)) {
+ if (g_strcmp0(optarg, "none")) {
monitor_parse(optarg, "readline", false);
}
break;
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 01/39] vl: fix -monitor none prefix matching Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:31 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type Marc-André Lureau
` (37 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
Fixes: 89aafcf2a793 ("trace: remove code that depends on setting vcpu")
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hmp-commands-info.hx | 6 +++---
hmp-commands.hx | 7 +++----
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 82134eb6c21..2695ff04ffc 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -587,10 +587,10 @@ ERST
{
.name = "trace-events",
- .args_type = "name:s?,vcpu:i?",
- .params = "[name] [vcpu]",
+ .args_type = "name:s?",
+ .params = "[name]",
.help = "show available trace-events & their state "
- "(name: event name pattern; vcpu: vCPU to query, default is any)",
+ "(name: event name pattern)",
.cmd = hmp_info_trace_events,
.command_completion = info_trace_events_completion,
},
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 7ae2468a3d9..2b658bbbf28 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -299,10 +299,9 @@ ERST
{
.name = "trace-event",
- .args_type = "name:s,option:b,vcpu:i?",
- .params = "name on|off [vcpu]",
- .help = "changes status of a specific trace event "
- "(vcpu: vCPU to set, default is all)",
+ .args_type = "name:s,option:b",
+ .params = "name on|off",
+ .help = "changes status of a specific trace event",
.cmd = hmp_trace_event,
.command_completion = trace_event_completion,
},
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 01/39] vl: fix -monitor none prefix matching Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:35 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
` (36 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
The `snapshot-file` argument for `snapshot_blkdev` is mandatory. Correct
the `args_type` definition to reflect this.
Fixes: 6106e2492fe ("qapi: Convert blockdev_snapshot_sync")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hmp-commands.hx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2b658bbbf28..1e286b7c89d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1168,7 +1168,7 @@ ERST
{
.name = "snapshot_blkdev",
- .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
+ .args_type = "reuse:-n,device:B,snapshot-file:s,format:s?",
.params = "[-n] device [new-image-file] [format]",
.help = "initiates a live snapshot\n\t\t\t"
"of device. If a new image file is specified, the\n\t\t\t"
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (2 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:40 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
` (35 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
Replace monitor_printf() error reporting with the standard **errp
pattern. Drop the Monitor *mon parameter and return bool to indicate
success, improving the function usage from non-HMP contexts. Update the
KVM MCE injection path and hmp_mce() accordingly.
Notes:
- we may want to print the error in KVM path too
- multiple error prints are now accumulated with error hints
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
target/i386/cpu.h | 4 ++--
target/i386/helper.c | 49 ++++++++++++++++++++++++++++---------------------
target/i386/kvm/kvm.c | 4 ++--
target/i386/monitor.c | 6 ++++--
4 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 67e2ecf3251..a8b211cf6c9 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2842,9 +2842,9 @@ void do_cpu_init(X86CPU *cpu);
#define MCE_INJECT_BROADCAST 1
#define MCE_INJECT_UNCOND_AO 2
-void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
+bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
uint64_t status, uint64_t mcg_status, uint64_t addr,
- uint64_t misc, int flags);
+ uint64_t misc, int flags, Error **errp);
uint32_t cpu_cc_compute_all(CPUX86State *env1);
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 68362141621..10d4ac03072 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qapi/qapi-events-run-state.h"
#include "cpu.h"
#include "exec/cputlb.h"
@@ -27,7 +28,6 @@
#ifndef CONFIG_USER_ONLY
#include "system/hw_accel.h"
#include "system/memory.h"
-#include "monitor/monitor.h"
#include "kvm/kvm_i386.h"
#endif
#include "qemu/log.h"
@@ -381,7 +381,7 @@ out:
}
typedef struct MCEInjectionParams {
- Monitor *mon;
+ GString *err;
int bank;
uint64_t status;
uint64_t mcg_status;
@@ -428,9 +428,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
* reporting is disabled
*/
if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
- monitor_printf(params->mon,
- "CPU %d: Uncorrected error reporting disabled\n",
- cs->cpu_index);
+ g_string_append_printf(params->err,
+ "CPU %d: Uncorrected error reporting disabled\n",
+ cs->cpu_index);
return;
}
@@ -439,10 +439,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
* reporting is disabled for the bank
*/
if (banks[0] != ~(uint64_t)0) {
- monitor_printf(params->mon,
- "CPU %d: Uncorrected error reporting disabled for"
- " bank %d\n",
- cs->cpu_index, params->bank);
+ g_string_append_printf(params->err,
+ "CPU %d: Uncorrected error reporting disabled for bank %d\n",
+ cs->cpu_index, params->bank);
return;
}
@@ -459,7 +458,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
if (need_reset) {
emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
recursive);
- monitor_printf(params->mon, "%s", msg);
+ g_string_append_printf(params->err, "%s\n", msg);
qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
return;
@@ -488,14 +487,16 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
}
-void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
+bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
uint64_t status, uint64_t mcg_status, uint64_t addr,
- uint64_t misc, int flags)
+ uint64_t misc, int flags, Error **errp)
{
+ ERRP_GUARD();
CPUState *cs = CPU(cpu);
CPUX86State *cenv = &cpu->env;
+ g_autoptr(GString) err = g_string_new(NULL);
MCEInjectionParams params = {
- .mon = mon,
+ .err = err,
.bank = bank,
.status = status,
.mcg_status = mcg_status,
@@ -506,21 +507,21 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
unsigned bank_num = cenv->mcg_cap & 0xff;
if (!cenv->mcg_cap) {
- monitor_printf(mon, "MCE injection not supported\n");
- return;
+ error_setg(errp, "MCE injection not supported");
+ return false;
}
if (bank >= bank_num) {
- monitor_printf(mon, "Invalid MCE bank number\n");
- return;
+ error_setg(errp, "Invalid MCE bank number");
+ return false;
}
if (!(status & MCI_STATUS_VAL)) {
- monitor_printf(mon, "Invalid MCE status code\n");
- return;
+ error_setg(errp, "Invalid MCE status code");
+ return false;
}
if ((flags & MCE_INJECT_BROADCAST)
&& !cpu_x86_support_mca_broadcast(cenv)) {
- monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
- return;
+ error_setg(errp, "Guest CPU does not support MCA broadcast");
+ return false;
}
run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
@@ -539,6 +540,12 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
}
}
+ if (params.err->len) {
+ error_setg(errp, "Failed to inject MCE");
+ error_append_hint(errp, "%s", params.err->str);
+ return false;
+ }
+ return true;
}
static inline target_ulong get_memio_eip(CPUX86State *env)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 9e352882c8c..d01519ef2f3 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -747,8 +747,8 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
flags = 0;
}
- cpu_x86_inject_mce(NULL, cpu, 9, status, mcg_status, paddr,
- (MCM_ADDR_PHYS << 6) | 0xc, flags);
+ cpu_x86_inject_mce(cpu, 9, status, mcg_status, paddr,
+ (MCM_ADDR_PHYS << 6) | 0xc, flags, NULL);
}
static void emit_hypervisor_memory_failure(MemoryFailureAction action, bool ar)
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index a536712c755..785a13dd710 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -580,6 +580,7 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
uint64_t addr = qdict_get_int(qdict, "addr");
uint64_t misc = qdict_get_int(qdict, "misc");
int flags = MCE_INJECT_UNCOND_AO;
+ Error *err = NULL;
if (qdict_get_try_bool(qdict, "broadcast", false)) {
flags |= MCE_INJECT_BROADCAST;
@@ -587,7 +588,8 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
cs = qemu_get_cpu(cpu_index);
if (cs != NULL) {
cpu = X86_CPU(cs);
- cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
- flags);
+ cpu_x86_inject_mce(cpu, bank, status, mcg_status, addr, misc,
+ flags, &err);
+ hmp_handle_error(mon, err);
}
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce()
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (3 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:42 ` Daniel P. Berrangé
2026-08-10 20:16 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 06/39] system: move gpa2hva() to system memory unit Marc-André Lureau
` (34 subsequent siblings)
39 siblings, 2 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
Rather than silently doing nothing.
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
target/i386/monitor.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 785a13dd710..9ed772e6d7f 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -586,10 +586,12 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
flags |= MCE_INJECT_BROADCAST;
}
cs = qemu_get_cpu(cpu_index);
- if (cs != NULL) {
+ if (cs) {
cpu = X86_CPU(cs);
cpu_x86_inject_mce(cpu, bank, status, mcg_status, addr, misc,
flags, &err);
- hmp_handle_error(mon, err);
+ } else {
+ error_setg(&err, "Invalid CPU %d", cpu_index);
}
+ hmp_handle_error(mon, err);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 06/39] system: move gpa2hva() to system memory unit
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (4 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:44 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 07/39] s390x: prevent crash if given invalid CPU# Marc-André Lureau
` (33 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
The function is now used by SEV code path. Move it to physmem.c rather
than hmp-cmds.c.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/monitor/monitor.h | 2 --
include/system/memory.h | 2 ++
monitor/hmp-cmds.c | 31 -------------------------------
system/physmem.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 55649a86641..17182e626a7 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -42,8 +42,6 @@ int monitor_get_cpu_index(Monitor *mon);
int monitor_puts_locked(Monitor *mon, const char *str);
void monitor_flush_locked(Monitor *mon);
-void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp);
-
void monitor_read_command(MonitorHMP *mon, int show_prompt);
int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func,
void *opaque);
diff --git a/include/system/memory.h b/include/system/memory.h
index 47a0e06fbf8..237b2b6aaee 100644
--- a/include/system/memory.h
+++ b/include/system/memory.h
@@ -2832,4 +2832,6 @@ bool ram_block_discard_is_required(void);
void ram_block_add_cpr_blocker(RAMBlock *rb, Error **errp);
void ram_block_del_cpr_blocker(RAMBlock *rb);
+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp);
+
#endif
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 443b8c785dc..521ab8a641c 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -709,37 +709,6 @@ void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
memory_dump(mon, count, format, size, addr, true);
}
-void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
-{
- Int128 gpa_region_size;
- MemoryRegionSection mrs = memory_region_find(get_system_memory(),
- addr, size);
-
- if (!mrs.mr) {
- error_setg(errp,
- "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
- return NULL;
- }
-
- if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
- error_setg(errp,
- "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
- memory_region_unref(mrs.mr);
- return NULL;
- }
-
- gpa_region_size = int128_make64(size);
- if (int128_lt(mrs.size, gpa_region_size)) {
- error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
- " exceeded.", addr);
- memory_region_unref(mrs.mr);
- return NULL;
- }
-
- *p_mr = mrs.mr;
- return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
-}
-
void hmp_gpa2hva(Monitor *mon, const QDict *qdict)
{
hwaddr addr = qdict_get_int(qdict, "addr");
diff --git a/system/physmem.c b/system/physmem.c
index c21ea929153..d1db81db87b 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -4492,3 +4492,34 @@ void ram_block_del_cpr_blocker(RAMBlock *rb)
{
migrate_del_blocker(&rb->cpr_blocker);
}
+
+void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, uint64_t size, Error **errp)
+{
+ Int128 gpa_region_size;
+ MemoryRegionSection mrs = memory_region_find(get_system_memory(),
+ addr, size);
+
+ if (!mrs.mr) {
+ error_setg(errp,
+ "No memory is mapped at address 0x%" HWADDR_PRIx, addr);
+ return NULL;
+ }
+
+ if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) {
+ error_setg(errp,
+ "Memory at address 0x%" HWADDR_PRIx " is not RAM", addr);
+ memory_region_unref(mrs.mr);
+ return NULL;
+ }
+
+ gpa_region_size = int128_make64(size);
+ if (int128_lt(mrs.size, gpa_region_size)) {
+ error_setg(errp, "Size of memory region at 0x%" HWADDR_PRIx
+ " exceeded.", addr);
+ memory_region_unref(mrs.mr);
+ return NULL;
+ }
+
+ *p_mr = mrs.mr;
+ return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region);
+}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 07/39] s390x: prevent crash if given invalid CPU#
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (5 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 06/39] system: move gpa2hva() to system memory unit Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:44 ` Daniel P. Berrangé
2026-08-10 21:01 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
` (32 subsequent siblings)
39 siblings, 2 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster, Eric Farman
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/s390x/s390-virtio-ccw.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 25a9fa49554..d0fd894eb67 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -729,6 +729,11 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
{
CPUState *cs = qemu_get_cpu(cpu_index);
+ if (!cs) {
+ error_setg(errp, "CPU %d does not exist", cpu_index);
+ return;
+ }
+
s390_cpu_restart(S390_CPU(cs));
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (6 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 07/39] s390x: prevent crash if given invalid CPU# Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:48 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 09/39] hmp: correct the nmi documentation Marc-André Lureau
` (31 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Use first_cpu directly instead of going through monitor_get_cpu_index(),
as this is HMP-territory. QMP doesn't have a `cpu` command, we should
add arguments instead when needed.
Update the inject-nmi doc to accurately describe per-architecture NMI
delivery.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/machine.json | 5 +++--
system/cpus.c | 7 +++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/qapi/machine.json b/qapi/machine.json
index 685e4e29b87..03461f5f723 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -432,8 +432,9 @@
##
# @inject-nmi:
#
-# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
-# all CPUs (ppc64). The command fails when the guest doesn't support
+# Injects a Non-Maskable Interrupt into the virtual machine. The NMI
+# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
+# (s390). The command fails when the guest doesn't support
# injecting.
#
# Since: 0.14
diff --git a/system/cpus.c b/system/cpus.c
index 49f6daec3cd..6e3ef0afeca 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -915,6 +915,9 @@ exit:
void qmp_inject_nmi(Error **errp)
{
- nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
+ int cpu_index = UNASSIGNED_CPU_INDEX;
+ if (first_cpu) {
+ cpu_index = first_cpu->cpu_index;
+ }
+ nmi_monitor_handle(cpu_index, errp);
}
-
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 09/39] hmp: correct the nmi documentation
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (7 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:51 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
` (30 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hmp-commands.hx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1e286b7c89d..129052963c7 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -868,8 +868,9 @@ ERST
.cmd = hmp_nmi,
},
SRST
-``nmi`` *cpu*
- Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
+``nmi``
+ Inject an NMI on the associated monitor vCPU (``cpu`` command, on s390x) or
+ all vCPUs (on other architectures).
ERST
{
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (8 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 09/39] hmp: correct the nmi documentation Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:54 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
` (29 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
mon_cpu_path and reset_seen are only used by HMP monitors; move them
from the base Monitor struct into MonitorHMP to properly encapsulate
HMP-specific state.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor/monitor-internal.h | 4 ++--
monitor/hmp-cmds.c | 17 ++++++++++-------
monitor/hmp.c | 5 +++--
monitor/monitor.c | 16 +++++++++++-----
4 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index a5c4aba306e..e071ad3e2e8 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -108,7 +108,6 @@ struct Monitor {
bool skip_flush;
bool use_io_thread;
- char *mon_cpu_path;
QTAILQ_ENTRY(Monitor) entry;
/*
@@ -124,7 +123,6 @@ struct Monitor {
GString *outbuf;
guint out_watch;
int mux_out;
- int reset_seen;
};
struct MonitorHMP {
@@ -138,6 +136,8 @@ struct MonitorHMP {
* These members can be safely accessed without locks.
*/
ReadLineState *rs;
+ char *mon_cpu_path;
+ int reset_seen;
};
typedef struct {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 521ab8a641c..e7a02b1fddb 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -496,31 +496,34 @@ void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
/* Set the current CPU defined by the user. Callers must hold BQL. */
int monitor_set_cpu(Monitor *mon, int cpu_index)
{
+ assert(!monitor_is_qmp(mon));
+ MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
CPUState *cpu;
cpu = qemu_get_cpu(cpu_index);
if (cpu == NULL) {
return -1;
}
- g_free(mon->mon_cpu_path);
- mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
+ g_free(hmp_mon->mon_cpu_path);
+ hmp_mon->mon_cpu_path = object_get_canonical_path(OBJECT(cpu));
return 0;
}
/* Callers must hold BQL. */
static CPUState *mon_get_cpu_sync(Monitor *mon, bool synchronize)
{
+ MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
CPUState *cpu = NULL;
- if (mon->mon_cpu_path) {
- cpu = (CPUState *) object_resolve_path_type(mon->mon_cpu_path,
+ if (hmp_mon->mon_cpu_path) {
+ cpu = (CPUState *) object_resolve_path_type(hmp_mon->mon_cpu_path,
TYPE_CPU, NULL);
if (!cpu) {
- g_free(mon->mon_cpu_path);
- mon->mon_cpu_path = NULL;
+ g_free(hmp_mon->mon_cpu_path);
+ hmp_mon->mon_cpu_path = NULL;
}
}
- if (!mon->mon_cpu_path) {
+ if (!hmp_mon->mon_cpu_path) {
if (!first_cpu) {
return NULL;
}
diff --git a/monitor/hmp.c b/monitor/hmp.c
index cc4390486e1..de8804af51a 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1453,6 +1453,7 @@ static void monitor_read(void *opaque, const uint8_t *buf, int size)
static void monitor_event(void *opaque, QEMUChrEvent event)
{
Monitor *mon = opaque;
+ MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
switch (event) {
case CHR_EVENT_MUX_IN:
@@ -1467,7 +1468,7 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
case CHR_EVENT_MUX_OUT:
qemu_mutex_lock(&mon->mon_lock);
if (!mon->mux_out) {
- if (mon->reset_seen && !mon->suspend_cnt) {
+ if (hmp_mon->reset_seen && !mon->suspend_cnt) {
monitor_puts_locked(mon, "\n");
} else {
monitor_flush_locked(mon);
@@ -1482,7 +1483,7 @@ static void monitor_event(void *opaque, QEMUChrEvent event)
monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
"information\n", QEMU_VERSION);
qemu_mutex_lock(&mon->mon_lock);
- mon->reset_seen = 1;
+ hmp_mon->reset_seen = 1;
if (!mon->mux_out) {
/* Suspend-resume forces the prompt to be printed. */
monitor_suspend(mon);
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 00b93ed6124..2dec0e299af 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -541,12 +541,17 @@ static void monitor_accept_input(void *opaque)
Monitor *mon = opaque;
qemu_mutex_lock(&mon->mon_lock);
- if (!monitor_is_qmp(mon) && mon->reset_seen) {
+ if (!monitor_is_qmp(mon)) {
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
assert(hmp_mon->rs);
- readline_restart(hmp_mon->rs);
+ bool reset_seen = hmp_mon->reset_seen;
+ if (reset_seen) {
+ readline_restart(hmp_mon->rs);
+ }
qemu_mutex_unlock(&mon->mon_lock);
- readline_show_prompt(hmp_mon->rs);
+ if (reset_seen) {
+ readline_show_prompt(hmp_mon->rs);
+ }
} else {
qemu_mutex_unlock(&mon->mon_lock);
}
@@ -622,12 +627,13 @@ void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
void monitor_data_destroy(Monitor *mon)
{
- g_free(mon->mon_cpu_path);
qemu_chr_fe_deinit(&mon->chr, false);
if (monitor_is_qmp(mon)) {
monitor_data_destroy_qmp(container_of(mon, MonitorQMP, common));
} else {
- readline_free(container_of(mon, MonitorHMP, common)->rs);
+ MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
+ readline_free(hmp_mon->rs);
+ g_free(hmp_mon->mon_cpu_path);
}
g_string_free(mon->outbuf, true);
qemu_mutex_destroy(&mon->mon_lock);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (9 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:54 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 12/39] net/qapi: add x-query-usernet command Marc-André Lureau
` (28 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
Replace the human-monitor-command based version test with the native
QMP query-version command, which returns structured version data.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/functional/generic/test_version.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/tests/functional/generic/test_version.py b/tests/functional/generic/test_version.py
index 3ab3b67f7e3..7764424826e 100755
--- a/tests/functional/generic/test_version.py
+++ b/tests/functional/generic/test_version.py
@@ -16,13 +16,15 @@
class Version(QemuSystemTest):
- def test_qmp_human_info_version(self):
+ def test_qmp_query_version(self):
self.set_machine('none')
self.vm.add_args('-nodefaults')
self.vm.launch()
- res = self.vm.cmd('human-monitor-command',
- command_line='info version')
- self.assertRegex(res, r'^(\d+\.\d+\.\d)')
+ res = self.vm.cmd('query-version')
+ version = res['qemu']
+ self.assertIsInstance(version['major'], int)
+ self.assertIsInstance(version['minor'], int)
+ self.assertIsInstance(version['micro'], int)
if __name__ == '__main__':
QemuSystemTest.main()
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 12/39] net/qapi: add x-query-usernet command
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (10 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 17:56 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
` (27 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add a QMP command to query user-mode network stack (slirp) connection
states, providing a structured alternative to "info usernet" HMP.
The new command returns a list of UsernetInfo, with hub-id, hub-name,
and connection info for each slirp stack. It is marked unstable as it
is meant for debugging.
Rewrite hmp_info_usernet() as a thin wrapper over qmp_x_query_usernet()
so the HMP and QMP paths share the same implementation.
This is part of the effort to decouple HMP from QEMU core.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
qapi/net.json | 44 ++++++++++++++++++++++++++++++++++++++++++++
net/slirp.c | 34 ++++++++++++++++++++++++++++------
2 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/qapi/net.json b/qapi/net.json
index 1a6382825c5..08ec7f37946 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -1261,3 +1261,47 @@
##
{ 'event': 'NETDEV_VHOST_USER_DISCONNECTED',
'data': { 'netdev-id': 'str' } }
+
+##
+# @UsernetInfo:
+#
+# Information about a user-mode network stack (slirp).
+#
+# @hub-id: The hub id, if available.
+#
+# @hub-name: The name of the hub.
+#
+# @info: Network information from slirp.
+#
+# Since: 11.1
+##
+{ 'struct': 'UsernetInfo',
+ 'data': {
+ '*hub-id': 'int',
+ 'hub-name': 'str',
+ 'info': 'str' },
+ 'if': 'CONFIG_SLIRP' }
+
+##
+# @x-query-usernet:
+#
+# Query user-mode network stack connection states.
+#
+# Features:
+#
+# @unstable: This command is meant for debugging.
+#
+# Returns: list of user-mode network stack information.
+#
+# Since: 11.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "x-query-usernet" }
+# <- { "return": [ { "hub-id": 0, "hub-name": "vnet",
+# "info": "..." } ] }
+##
+{ 'command': 'x-query-usernet',
+ 'returns': ['UsernetInfo'],
+ 'if': 'CONFIG_SLIRP',
+ 'features': [ 'unstable' ] }
diff --git a/net/slirp.c b/net/slirp.c
index 9e9941fe73e..517dd23be14 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -43,6 +43,7 @@
#include "system/system.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-net.h"
#include "qobject/qdict.h"
#include "util.h"
#include "migration/register.h"
@@ -1200,18 +1201,39 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
return -1;
}
-void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+UsernetInfoList *qmp_x_query_usernet(Error **errp)
{
+ UsernetInfoList *head = NULL, **tail = &head;
SlirpState *s;
QTAILQ_FOREACH(s, &slirp_stacks, entry) {
+ UsernetInfo *ui = g_new0(UsernetInfo, 1);
int id;
- bool got_hub_id = net_hub_id_for_client(&s->nc, &id) == 0;
- char *info = slirp_connection_info(s->slirp);
+
+ if (net_hub_id_for_client(&s->nc, &id) == 0) {
+ ui->has_hub_id = true;
+ ui->hub_id = id;
+ }
+ ui->hub_name = g_strdup(s->nc.name);
+ ui->info = slirp_connection_info(s->slirp);
+
+ QAPI_LIST_APPEND(tail, ui);
+ }
+
+ return head;
+}
+
+void hmp_info_usernet(Monitor *mon, const QDict *qdict)
+{
+ g_autoptr(UsernetInfoList) list = NULL;
+ UsernetInfoList *entry;
+
+ list = qmp_x_query_usernet(&error_abort);
+ for (entry = list; entry; entry = entry->next) {
+ UsernetInfo *ui = entry->value;
monitor_printf(mon, "Hub %d (%s):\n%s",
- got_hub_id ? id : -1,
- s->nc.name, info);
- g_free(info);
+ ui->has_hub_id ? (int)ui->hub_id : -1,
+ ui->hub_name, ui->info);
}
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (11 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 12/39] net/qapi: add x-query-usernet command Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:00 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
` (26 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Replace human-monitor-command "info usernet" calls with the structured
x-query-usernet QMP command in get_usernet_hostfwd_port() and the VM
test runner boot path.
Since x-query-usernet returns a list of UsernetInfo entries, callers
now iterate over the result and extract the port from each entry's
"info" field. Also switch get_info_usernet_hostfwd_port() from
split('\r\n') to splitlines(), since QMP strings use \n rather than
the HMP monitor's \r\n line endings.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
python/qemu/utils/__init__.py | 5 +++--
tests/functional/qemu_test/utils.py | 8 ++++++--
tests/vm/basevm.py | 13 ++++++++-----
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
index be5daa83634..e32911d4c6d 100644
--- a/python/qemu/utils/__init__.py
+++ b/python/qemu/utils/__init__.py
@@ -46,10 +46,11 @@ def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
"""
Returns the port given to the hostfwd parameter via info usernet
- :param info_usernet_output: output generated by hmp command "info usernet"
+ :param info_usernet_output: output generated by "info usernet" or
+ the "info" field from x-query-usernet
:return: the port number allocated by the hostfwd option
"""
- for line in info_usernet_output.split('\r\n'):
+ for line in info_usernet_output.splitlines():
regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
match = re.search(regex, line)
if match is not None:
diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py
index 826c267785b..0992db49ab2 100644
--- a/tests/functional/qemu_test/utils.py
+++ b/tests/functional/qemu_test/utils.py
@@ -14,8 +14,12 @@
def get_usernet_hostfwd_port(vm):
- res = vm.cmd('human-monitor-command', command_line='info usernet')
- return get_info_usernet_hostfwd_port(res)
+ res = vm.cmd('x-query-usernet')
+ for entry in res:
+ port = get_info_usernet_hostfwd_port(entry['info'])
+ if port is not None:
+ return port
+ return None
def pow2ceil(x):
"""
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 9e879e966a3..198b04e8c37 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -312,12 +312,15 @@ def boot(self, img, extra_args=[]):
self._guest = guest
# Init console so we can start consuming the chars.
self.console_init()
- usernet_info = guest.cmd("human-monitor-command",
- command_line="info usernet")
- self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
+ res = guest.cmd("x-query-usernet")
+ for entry in res:
+ port = get_info_usernet_hostfwd_port(entry['info'])
+ if port is not None:
+ self.ssh_port = port
+ break
if not self.ssh_port:
- raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
- usernet_info)
+ raise Exception("Cannot find ssh port from"
+ " 'x-query-usernet': %s" % res)
def console_init(self, timeout = None):
if timeout == None:
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (12 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:01 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
` (25 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
The pnv-xive2-test and pnv-host-i2c-test pass "-serial mon:stdio"
but never use HMP commands. The "mon:" chardev prefix creates an
HMP monitor mux, which fails when HMP is disabled. Other pnv tests
(e.g. pnv-spi-seeprom-test) don't specify -serial at all.
Drop the unnecessary -serial mon:stdio option.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/pnv-host-i2c-test.c | 2 +-
tests/qtest/pnv-xive2-test.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/qtest/pnv-host-i2c-test.c b/tests/qtest/pnv-host-i2c-test.c
index 51e613ebdcb..368d1a91401 100644
--- a/tests/qtest/pnv-host-i2c-test.c
+++ b/tests/qtest/pnv-host-i2c-test.c
@@ -415,7 +415,7 @@ static void test_host_i2c(const void *data)
}
qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
- "-nodefaults -serial mon:stdio -S "
+ "-nodefaults -S "
"-d guest_errors",
machine, SMT, SMT);
diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c
index 5313d4ef18b..b4f4b601c2a 100644
--- a/tests/qtest/pnv-xive2-test.c
+++ b/tests/qtest/pnv-xive2-test.c
@@ -549,7 +549,7 @@ static void test_xive(void)
QTestState *qts;
qts = qtest_initf("-M powernv10 -smp %d,cores=1,threads=%d -nographic "
- "-nodefaults -serial mon:stdio -S "
+ "-nodefaults -S "
"-d guest_errors -trace '*xive*'",
SMT, SMT);
init_xive(qts);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (13 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:03 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
` (24 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
The test was using 'human-monitor-command' (which requires HMP) to
verify that an integer 'id' is echoed back on failure. Replace with
'query-name' for the success case and 'block_resize' (missing
required args) for the failure case, so the test works regardless of
HMP availability.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/qmp-test.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
index edf08867874..03637b9e2d2 100644
--- a/tests/qtest/qmp-test.c
+++ b/tests/qtest/qmp-test.c
@@ -151,9 +151,14 @@ static void test_qmp_protocol(void)
g_assert_cmpstr(qdict_get_try_str(resp, "id"), ==, "cookie#1");
qobject_unref(resp);
- /* Test command failure with 'id' */
- resp = qtest_qmp(qts, "{ 'execute': 'human-monitor-command', 'id': 2 }");
+ /* Test integer 'id' is echoed back on success */
+ resp = qtest_qmp(qts, "{ 'execute': 'query-name', 'id': 2 }");
g_assert_cmpint(qdict_get_int(resp, "id"), ==, 2);
+ qobject_unref(resp);
+
+ /* Test integer 'id' is echoed back on failure */
+ resp = qtest_qmp(qts, "{ 'execute': 'block_resize', 'id': 3 }");
+ g_assert_cmpint(qdict_get_int(resp, "id"), ==, 3);
qmp_expect_error_and_unref(resp, "GenericError");
qtest_quit(qts);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (14 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:04 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
` (23 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Convert the three test functions that relied on HMP "info numa" to use
QMP "query-cpus-fast" instead, verifying each CPU's node-id through the
structured response. Add a check_cpu_node() helper for the per-CPU
assertions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/numa-test.c | 63 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 12 deletions(-)
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
index d657f389474..8f563c079f6 100644
--- a/tests/qtest/numa-test.c
+++ b/tests/qtest/numa-test.c
@@ -19,19 +19,50 @@ static char *make_cli(const GString *generic_cli, const char *test_cli)
return g_strdup_printf("%s %s", generic_cli->str, test_cli);
}
+static void check_cpu_node(QTestState *qts, int cpu_idx, int expected_node)
+{
+ QDict *resp;
+ QList *cpus;
+ QListEntry *e;
+ bool found = false;
+
+ resp = qtest_qmp(qts, "{ 'execute': 'query-cpus-fast' }");
+ g_assert(resp);
+ g_assert(qdict_haskey(resp, "return"));
+ cpus = qdict_get_qlist(resp, "return");
+ g_assert(cpus);
+
+ QLIST_FOREACH_ENTRY(cpus, e) {
+ QDict *cpu = qobject_to(QDict, qlist_entry_obj(e));
+ int64_t idx = qdict_get_int(cpu, "cpu-index");
+ if (idx == cpu_idx) {
+ QDict *props = qdict_get_qdict(cpu, "props");
+ g_assert(qdict_haskey(props, "node-id"));
+ g_assert_cmpint(qdict_get_int(props, "node-id"), ==, expected_node);
+ found = true;
+ break;
+ }
+ }
+ g_assert(found);
+ qobject_unref(resp);
+}
+
static void test_mon_explicit(const void *data)
{
QTestState *qts;
- g_autofree char *s = NULL;
g_autofree char *cli = NULL;
+ int i;
cli = make_cli(data, "-machine smp.cpus=8 -numa node,nodeid=0,memdev=ram,cpus=0-3 "
"-numa node,nodeid=1,cpus=4-7");
qts = qtest_init(cli);
- s = qtest_hmp(qts, "info numa");
- g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
- g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
+ for (i = 0; i < 4; i++) {
+ check_cpu_node(qts, i, 0);
+ }
+ for (i = 4; i < 8; i++) {
+ check_cpu_node(qts, i, 1);
+ }
qtest_quit(qts);
}
@@ -39,16 +70,19 @@ static void test_mon_explicit(const void *data)
static void test_def_cpu_split(const void *data)
{
QTestState *qts;
- g_autofree char *s = NULL;
g_autofree char *cli = NULL;
+ int even_cpus[] = {0, 2, 4, 6};
+ int odd_cpus[] = {1, 3, 5, 7};
+ int i;
cli = make_cli(data, "-machine smp.cpus=8,smp.sockets=8 "
"-numa node,memdev=ram -numa node");
qts = qtest_init(cli);
- s = qtest_hmp(qts, "info numa");
- g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
- g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
+ for (i = 0; i < 4; i++) {
+ check_cpu_node(qts, even_cpus[i], 0);
+ check_cpu_node(qts, odd_cpus[i], 1);
+ }
qtest_quit(qts);
}
@@ -56,17 +90,22 @@ static void test_def_cpu_split(const void *data)
static void test_mon_partial(const void *data)
{
QTestState *qts;
- g_autofree char *s = NULL;
g_autofree char *cli = NULL;
+ int node0_cpus[] = {0, 1, 2, 3, 6, 7};
+ int node1_cpus[] = {4, 5};
+ int i;
cli = make_cli(data, "-machine smp.cpus=8 "
"-numa node,nodeid=0,memdev=ram,cpus=0-1 "
"-numa node,nodeid=1,cpus=4-5 ");
qts = qtest_init(cli);
- s = qtest_hmp(qts, "info numa");
- g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
- g_assert(strstr(s, "node 1 cpus: 4 5"));
+ for (i = 0; i < 6; i++) {
+ check_cpu_node(qts, node0_cpus[i], 0);
+ }
+ for (i = 0; i < 2; i++) {
+ check_cpu_node(qts, node1_cpus[i], 1);
+ }
qtest_quit(qts);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (15 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:05 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 18/39] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
` (22 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
The test_cdrom_param() function uses qtest_hmp() to run "info block",
which depends on the human-monitor-command QMP endpoint. Replace it
with the QMP query-block command so the test works when HMP is
disabled (-Dhmp=disabled).
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/cdrom-test.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
index a65854d2bc5..bf997be6d69 100644
--- a/tests/qtest/cdrom-test.c
+++ b/tests/qtest/cdrom-test.c
@@ -14,6 +14,7 @@
#include "libqtest.h"
#include "boot-sector.h"
#include "qobject/qdict.h"
+#include "qobject/qlist.h"
static char isoimage[] = "cdrom-boot-iso-XXXXXX";
@@ -92,17 +93,35 @@ cleanup:
/**
* Check that at least the -cdrom parameter is basically working, i.e. we can
- * see the filename of the ISO image in the output of "info block" afterwards
+ * see the filename of the ISO image in the output of "query-block" afterwards
*/
static void test_cdrom_param(gconstpointer data)
{
QTestState *qts;
- char *resp;
+ QDict *response;
+ QList *ret;
+ QListEntry *entry;
+ bool found = false;
qts = qtest_initf("-M %s -cdrom %s", (const char *)data, isoimage);
- resp = qtest_hmp(qts, "info block");
- g_assert(strstr(resp, isoimage) != 0);
- g_free(resp);
+ response = qtest_qmp(qts, "{'execute': 'query-block'}");
+ g_assert(response && qdict_haskey(response, "return"));
+ ret = qdict_get_qlist(response, "return");
+
+ QLIST_FOREACH_ENTRY(ret, entry) {
+ QDict *entry_dict = qobject_to(QDict, entry->value);
+ QDict *inserted = qdict_get_qdict(entry_dict, "inserted");
+ if (inserted) {
+ const char *file = qdict_get_str(inserted, "file");
+ if (file && strstr(file, isoimage)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ g_assert(found);
+ qobject_unref(response);
qtest_quit(qts);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 18/39] tests/qtest/device-introspect-test: fix test without HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (16 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
` (21 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Replace "info qom-tree" with recursive qom-list walk.
Disable HMP-only code paths, info qtree, kinda duplicating the test.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/device-introspect-test.c | 111 +++++++++++++++++++++++++++--------
1 file changed, 88 insertions(+), 23 deletions(-)
diff --git a/tests/qtest/device-introspect-test.c b/tests/qtest/device-introspect-test.c
index f84cec51dc2..f6eca2c8eb7 100644
--- a/tests/qtest/device-introspect-test.c
+++ b/tests/qtest/device-introspect-test.c
@@ -11,10 +11,10 @@
*/
/*
- * Covers QMP device-list-properties and HMP device_add help. We
- * currently don't check that their output makes sense, only that QEMU
- * survives. Useful since we've had an astounding number of crash
- * bugs around here.
+ * Covers QMP device-list-properties and HMP device_add help (if
+ * CONFIG_HMP). We currently don't check that the output makes sense,
+ * only that QEMU survives. Useful since we've had an astounding
+ * number of crash bugs around here.
*/
#include "qemu/osdep.h"
@@ -100,11 +100,60 @@ static QList *device_type_list(QTestState *qts, bool abstract)
return qom_list_types(qts, "device", abstract);
}
+/*
+ * Recursively walk the QOM composition tree via qom-list and build a
+ * string representation. This serves two purposes: detecting dangling
+ * pointers (qom-list would crash QEMU) and detecting leaked objects
+ * (by comparing the output before and after device introspection).
+ */
+static void qom_tree_walk(QTestState *qts, const char *path, GString *result)
+{
+ QDict *resp;
+ QList *list;
+ QListEntry *e;
+ GList *children = NULL;
+
+ resp = qtest_qmp(qts, "{'execute': 'qom-list',"
+ " 'arguments': {'path': %s}}", path);
+ g_assert(qdict_haskey(resp, "return"));
+ list = qdict_get_qlist(resp, "return");
+
+ QLIST_FOREACH_ENTRY(list, e) {
+ QDict *prop = qobject_to(QDict, qlist_entry_obj(e));
+ const char *type = qdict_get_str(prop, "type");
+ if (g_str_has_prefix(type, "child<")) {
+ const char *name = qdict_get_str(prop, "name");
+ children = g_list_prepend(children, g_strdup(name));
+ }
+ }
+
+ children = g_list_sort_with_data(children, (GCompareDataFunc)g_strcmp0,
+ NULL);
+
+ for (GList *l = children; l; l = l->next) {
+ const char *name = l->data;
+ g_autofree char *child_path = (!strcmp(path, "/"))
+ ? g_strdup_printf("/%s", name)
+ : g_strdup_printf("%s/%s", path, name);
+
+ g_string_append_printf(result, "%s\n", child_path);
+ qom_tree_walk(qts, child_path, result);
+ }
+
+ g_list_free_full(children, g_free);
+ qobject_unref(resp);
+}
+
+static char *qom_tree_str(QTestState *qts)
+{
+ GString *result = g_string_new("");
+ qom_tree_walk(qts, "/", result);
+ return g_string_free(result, FALSE);
+}
+
static void test_one_device(QTestState *qts, const char *type)
{
QDict *resp;
- char *help, *escaped;
- GRegex *comma;
g_test_message("Testing device '%s'", type);
@@ -113,19 +162,21 @@ static void test_one_device(QTestState *qts, const char *type)
type);
qobject_unref(resp);
- comma = g_regex_new(",", 0, 0, NULL);
- escaped = g_regex_replace_literal(comma, type, -1, 0, ",,", 0, NULL);
- g_regex_unref(comma);
+#ifdef CONFIG_HMP
+ {
+ g_autofree char *escaped = NULL;
+ g_autoptr(GRegex) comma = NULL;
- help = qtest_hmp(qts, "device_add \"%s,help\"", escaped);
- g_free(help);
- g_free(escaped);
+ comma = g_regex_new(",", 0, 0, NULL);
+ escaped = g_regex_replace_literal(comma, type, -1, 0, ",,", 0, NULL);
+ g_free(qtest_hmp(qts, "device_add \"%s,help\"", escaped));
+ }
+#endif
}
static void test_device_intro_list(void)
{
QList *types;
- char *help;
QTestState *qts;
qts = qtest_init(common_args);
@@ -133,8 +184,11 @@ static void test_device_intro_list(void)
types = device_type_list(qts, true);
qobject_unref(types);
- help = qtest_hmp(qts, "device_add help");
- g_free(help);
+#ifdef CONFIG_HMP
+ {
+ g_free(qtest_hmp(qts, "device_add help"));
+ }
+#endif
qtest_quit(qts);
}
@@ -198,18 +252,22 @@ static void test_qom_list_fields(void)
static void test_device_intro_none(void)
{
QTestState *qts = qtest_init(common_args);
- g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+ g_autofree char *qom_tree_start = qom_tree_str(qts);
g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
g_autofree char *qtree_end = NULL;
+#endif
test_one_device(qts, "nonexistent");
/* Make sure that really nothing changed in the trees */
- qom_tree_end = qtest_hmp(qts, "info qom-tree");
+ qom_tree_end = qom_tree_str(qts);
g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
+#ifdef CONFIG_HMP
qtree_end = qtest_hmp(qts, "info qtree");
g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
qtest_quit(qts);
}
@@ -217,18 +275,22 @@ static void test_device_intro_none(void)
static void test_device_intro_abstract(void)
{
QTestState *qts = qtest_init(common_args);
- g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+ g_autofree char *qom_tree_start = qom_tree_str(qts);
g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
g_autofree char *qtree_end = NULL;
+#endif
test_one_device(qts, "device");
/* Make sure that really nothing changed in the trees */
- qom_tree_end = qtest_hmp(qts, "info qom-tree");
+ qom_tree_end = qom_tree_str(qts);
g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
+#ifdef CONFIG_HMP
qtree_end = qtest_hmp(qts, "info qtree");
g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
qtest_quit(qts);
}
@@ -239,10 +301,12 @@ static void test_device_intro_concrete(const void *args)
QListEntry *entry;
const char *type;
QTestState *qts = qtest_init(args);
- g_autofree char *qom_tree_start = qtest_hmp(qts, "info qom-tree");
+ g_autofree char *qom_tree_start = qom_tree_str(qts);
g_autofree char *qom_tree_end = NULL;
+#ifdef CONFIG_HMP
g_autofree char *qtree_start = qtest_hmp(qts, "info qtree");
g_autofree char *qtree_end = NULL;
+#endif
types = device_type_list(qts, false);
@@ -255,14 +319,15 @@ static void test_device_intro_concrete(const void *args)
/*
* Some devices leave dangling pointers in QOM behind.
- * "info qom-tree" or "info qtree" have a good chance at crashing then.
+ * Walking the QOM tree via qom-list has a good chance at crashing then.
* Also make sure that the tree did not change.
*/
- qom_tree_end = qtest_hmp(qts, "info qom-tree");
+ qom_tree_end = qom_tree_str(qts);
g_assert_cmpstr(qom_tree_start, ==, qom_tree_end);
-
+#ifdef CONFIG_HMP
qtree_end = qtest_hmp(qts, "info qtree");
g_assert_cmpstr(qtree_start, ==, qtree_end);
+#endif
qobject_unref(types);
qtest_quit(qts);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (17 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 18/39] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:15 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 20/39] net: add x-query-network QMP command Marc-André Lureau
` (20 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
After nbd-server-remove with mode=hard and an active client, the
export is removed from the NBD export list synchronously but remains
in the block export list until async cleanup completes (via
blk_exp_delete_bh bottom-half). A subsequent nbd-server-remove call
may find the export still in the block list with user_owned=false,
returning "already shutting down" instead of "not found".
Accept both error messages in assertExportNotFound, since both
indicate the export is no longer usable.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qemu-iotests/205 | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 2370e1a138b..78459065418 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -60,7 +60,9 @@ class TestNbdServerRemove(iotests.QMPTestCase):
def assertExportNotFound(self, name):
result = self.vm.qmp('nbd-server-remove', name=name)
- self.assert_qmp(result, 'error/desc', "Export 'exp' is not found")
+ desc = result.get('error', {}).get('desc', '')
+ self.assertIn(desc, ("Export '%s' is not found" % name,
+ "Export '%s' is already shutting down" % name))
def assertExistingClients(self, result):
self.assert_qmp(result, 'error/desc', "export 'exp' still in use")
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 20/39] net: add x-query-network QMP command
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (18 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 21/39] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
` (19 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add a structured x-query-network QMP command that returns network
configuration as a NetworkInfo struct with pre-grouped hub information
and a flat list of non-hub clients. Each hub includes its ports with
inlined peer client info, and each client includes attached netfilter
details.
Refactor hmp_info_network() to consume only the QMP result instead of
directly accessing internal net_clients state. This decouples HMP from
internal data structures, making it possible to remove HMP support
without losing programmatic network introspection.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/net.json | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/net/net.h | 3 +-
net/hub.h | 4 +-
net/hub.c | 29 +++++++------
net/net-hmp-cmds.c | 59 +++++++++++++++++++-------
net/net.c | 70 +++++++++++++++++++++++-------
6 files changed, 243 insertions(+), 44 deletions(-)
diff --git a/qapi/net.json b/qapi/net.json
index 08ec7f37946..39db58b03d4 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -1305,3 +1305,125 @@
'returns': ['UsernetInfo'],
'if': 'CONFIG_SLIRP',
'features': [ 'unstable' ] }
+
+##
+# @NetFilterInfo:
+#
+# Information about a netfilter attached to a network client.
+#
+# @name: filter object name (QOM path component)
+#
+# @type: QOM type name (e.g. "filter-mirror")
+#
+# @info: filter properties as comma-separated key=value pairs
+# (excluding @type)
+#
+# Since: 11.1
+##
+{ 'struct': 'NetFilterInfo',
+ 'data': {
+ 'name': 'str',
+ 'type': 'str',
+ 'info': 'str' } }
+
+##
+# @NetworkClientInfo:
+#
+# Information about a network client.
+#
+# @name: unique network client identifier
+#
+# @queue-index: index of this queue (0 for single-queue clients)
+#
+# @type: network client driver type
+#
+# @info-str: driver-specific formatted information string (e.g.
+# "model=e1000,macaddr=52:54:00:12:34:56")
+#
+# @peer: the connected peer client (always a leaf; the peer's own
+# peer field is never populated)
+#
+# @filters: attached netfilters
+#
+# Since: 11.1
+##
+{ 'struct': 'NetworkClientInfo',
+ 'data': {
+ 'name': 'str',
+ 'queue-index': 'uint32',
+ 'type': 'NetClientDriver',
+ 'info-str': 'str',
+ '*peer': 'NetworkClientInfo',
+ 'filters': ['NetFilterInfo'] } }
+
+##
+# @NetHubPortInfo:
+#
+# Information about a hub port.
+#
+# @name: hub port identifier
+#
+# @peer: the network client connected through this port
+#
+# Since: 11.1
+##
+{ 'struct': 'NetHubPortInfo',
+ 'data': {
+ 'name': 'str',
+ '*peer': 'NetworkClientInfo' } }
+
+##
+# @NetHubInfo:
+#
+# Information about a network hub.
+#
+# @id: hub identifier
+#
+# @ports: list of ports on this hub
+#
+# Since: 11.1
+##
+{ 'struct': 'NetHubInfo',
+ 'data': {
+ 'id': 'int',
+ 'ports': ['NetHubPortInfo'] } }
+
+##
+# @NetworkInfo:
+#
+# Information about the network configuration.
+#
+# @hubs: network hubs and their ports
+#
+# @clients: network clients not associated with a hub
+#
+# Since: 11.1
+##
+{ 'struct': 'NetworkInfo',
+ 'data': {
+ 'hubs': ['NetHubInfo'],
+ 'clients': ['NetworkClientInfo'] } }
+
+##
+# @x-query-network:
+#
+# Query the network configuration including hubs and clients.
+#
+# Features:
+#
+# @unstable: This command is meant for debugging.
+#
+# Returns: @NetworkInfo describing hubs and clients.
+#
+# Since: 11.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "x-query-network" }
+# <- { "return": { "clients": [ { "name": "st0",
+# "queue-index": 0, "type": "stream",
+# "info-str": "listening" } ] } }
+##
+{ 'command': 'x-query-network',
+ 'returns': 'NetworkInfo',
+ 'features': [ 'unstable' ] }
diff --git a/include/net/net.h b/include/net/net.h
index 45bc86fc86b..0f0b524df00 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -274,7 +274,6 @@ DeviceState *qemu_create_nic_device(const char *typename, bool match_default,
void qemu_create_nic_bus_devices(BusState *bus, const char *parent_type,
const char *default_model,
const char *alias, const char *alias_target);
-void print_net_client(Monitor *mon, NetClientState *nc);
void net_socket_rs_init(SocketReadState *rs,
SocketReadStateFinalize *finalize,
bool vnet_hdr);
@@ -325,6 +324,8 @@ void netdev_add(QemuOpts *opts, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
+NetworkClientInfo *net_client_info(NetClientState *nc);
+
#define DEFAULT_NETWORK_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifdown"
#define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper"
diff --git a/net/hub.h b/net/hub.h
index ce45f7b399d..cab6b1459b1 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -15,10 +15,12 @@
#ifndef NET_HUB_H
#define NET_HUB_H
+#include "qapi/qapi-types-net.h"
+
NetClientState *net_hub_add_port(int hub_id, const char *name,
NetClientState *hubpeer);
-void net_hub_info(Monitor *mon);
void net_hub_check_clients(void);
bool net_hub_flush(NetClientState *nc);
+NetHubInfoList *net_hub_query_info(void);
#endif /* NET_HUB_H */
diff --git a/net/hub.c b/net/hub.c
index ee5881f6d5c..b53a4cc872c 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -14,7 +14,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "monitor/monitor.h"
+#include "qapi/util.h"
#include "net/net.h"
#include "clients.h"
#include "hub.h"
@@ -199,26 +199,31 @@ NetClientState *net_hub_add_port(int hub_id, const char *name,
return &port->nc;
}
-/**
- * Print hub configuration
- */
-void net_hub_info(Monitor *mon)
+NetHubInfoList *net_hub_query_info(void)
{
+ NetHubInfoList *head = NULL, **tail = &head;
NetHub *hub;
- NetHubPort *port;
QLIST_FOREACH(hub, &hubs, next) {
- monitor_printf(mon, "hub %d\n", hub->id);
+ NetHubInfo *hi = g_new0(NetHubInfo, 1);
+ NetHubPortInfoList **ptail = &hi->ports;
+ NetHubPort *port;
+
+ hi->id = hub->id;
+
QLIST_FOREACH(port, &hub->ports, next) {
- monitor_printf(mon, " \\ %s", port->nc.name);
+ NetHubPortInfo *pi = g_new0(NetHubPortInfo, 1);
+ pi->name = g_strdup(port->nc.name);
if (port->nc.peer) {
- monitor_printf(mon, ": ");
- print_net_client(mon, port->nc.peer);
- } else {
- monitor_printf(mon, "\n");
+ pi->peer = net_client_info(port->nc.peer);
}
+ QAPI_LIST_APPEND(ptail, pi);
}
+
+ QAPI_LIST_APPEND(tail, hi);
}
+
+ return head;
}
/**
diff --git a/net/net-hmp-cmds.c b/net/net-hmp-cmds.c
index 2b24c9e6049..52ac8da770d 100644
--- a/net/net-hmp-cmds.c
+++ b/net/net-hmp-cmds.c
@@ -19,37 +19,66 @@
#include "monitor/hmp-completion.h"
#include "monitor/monitor.h"
#include "net/net.h"
-#include "net/hub.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-commands-net.h"
#include "qapi/qapi-visit-net.h"
+#include "qapi/error.h"
#include "qobject/qdict.h"
#include "qemu/config-file.h"
#include "qemu/help_option.h"
#include "qemu/option.h"
-void hmp_info_network(Monitor *mon, const QDict *qdict)
+static void hmp_print_client_info(Monitor *mon, NetworkClientInfo *ci)
{
- NetClientState *nc, *peer;
- NetClientDriver type;
+ NetFilterInfoList *f;
+
+ monitor_printf(mon, "%s: index=%" PRIu32 ",type=%s,%s\n",
+ ci->name, ci->queue_index,
+ NetClientDriver_str(ci->type), ci->info_str);
+ if (ci->filters) {
+ monitor_printf(mon, "filters:\n");
+ for (f = ci->filters; f; f = f->next) {
+ monitor_printf(mon, " - %s: type=%s%s%s\n",
+ f->value->name, f->value->type,
+ f->value->info[0] ? "," : "", f->value->info);
+ }
+ }
+}
- net_hub_info(mon);
+void hmp_info_network(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
+ NetHubInfoList *h;
+ NetworkClientInfoList *entry;
- QTAILQ_FOREACH(nc, &net_clients, next) {
- peer = nc->peer;
- type = nc->info->type;
+ if (hmp_handle_error(mon, err)) {
+ return;
+ }
- /* Skip if already printed in hub info */
- if (net_hub_id_for_client(nc, NULL) == 0) {
- continue;
+ for (h = info->hubs; h; h = h->next) {
+ NetHubPortInfoList *p;
+
+ monitor_printf(mon, "hub %d\n", (int)h->value->id);
+ for (p = h->value->ports; p; p = p->next) {
+ if (p->value->peer) {
+ monitor_printf(mon, " \\ %s: ", p->value->name);
+ hmp_print_client_info(mon, p->value->peer);
+ } else {
+ monitor_printf(mon, " \\ %s\n", p->value->name);
+ }
}
+ }
+
+ for (entry = info->clients; entry; entry = entry->next) {
+ NetworkClientInfo *ci = entry->value;
- if (!peer || type == NET_CLIENT_DRIVER_NIC) {
- print_net_client(mon, nc);
+ if (!ci->peer || ci->type == NET_CLIENT_DRIVER_NIC) {
+ hmp_print_client_info(mon, ci);
} /* else it's a netdev connected to a NIC, printed with the NIC */
- if (peer && type == NET_CLIENT_DRIVER_NIC) {
+ if (ci->peer && ci->type == NET_CLIENT_DRIVER_NIC) {
monitor_printf(mon, " \\ ");
- print_net_client(mon, peer);
+ hmp_print_client_info(mon, ci->peer);
}
}
}
diff --git a/net/net.c b/net/net.c
index 2892f1730d1..2bcd229cd9d 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1523,14 +1523,14 @@ void qmp_netdev_del(const char *id, Error **errp)
}
}
-static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
+static char *netfilter_get_info_str(NetFilterState *nf)
{
char *str;
ObjectProperty *prop;
ObjectPropertyIterator iter;
Visitor *v;
+ GString *buf = g_string_new(NULL);
- /* generate info str */
object_property_iter_init(&iter, OBJECT(nf));
while ((prop = object_property_iter_next(&iter))) {
if (!strcmp(prop->name, "type")) {
@@ -1540,29 +1540,69 @@ static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
object_property_get(OBJECT(nf), prop->name, v, NULL);
visit_complete(v, &str);
visit_free(v);
- monitor_printf(mon, ",%s=%s", prop->name, str);
+ if (buf->len > 0) {
+ g_string_append_c(buf, ',');
+ }
+ g_string_append_printf(buf, "%s=%s", prop->name, str);
g_free(str);
}
- monitor_printf(mon, "\n");
+
+ return g_string_free(buf, false);
}
-void print_net_client(Monitor *mon, NetClientState *nc)
+static NetworkClientInfo *net_client_info_no_peer(NetClientState *nc)
{
+ NetworkClientInfo *info = g_new0(NetworkClientInfo, 1);
NetFilterState *nf;
- monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name,
- nc->queue_index,
- NetClientDriver_str(nc->info->type),
- nc->info_str);
+ info->name = g_strdup(nc->name);
+ info->queue_index = nc->queue_index;
+ info->type = nc->info->type;
+ info->info_str = g_strdup(nc->info_str);
+
if (!QTAILQ_EMPTY(&nc->filters)) {
- monitor_printf(mon, "filters:\n");
+ NetFilterInfoList **ftail = &info->filters;
+ QTAILQ_FOREACH(nf, &nc->filters, next) {
+ NetFilterInfo *fi = g_new0(NetFilterInfo, 1);
+ fi->name = g_strdup(
+ object_get_canonical_path_component(OBJECT(nf)));
+ fi->type = g_strdup(object_get_typename(OBJECT(nf)));
+ fi->info = netfilter_get_info_str(nf);
+ QAPI_LIST_APPEND(ftail, fi);
+ }
}
- QTAILQ_FOREACH(nf, &nc->filters, next) {
- monitor_printf(mon, " - %s: type=%s",
- object_get_canonical_path_component(OBJECT(nf)),
- object_get_typename(OBJECT(nf)));
- netfilter_print_info(mon, nf);
+
+ return info;
+}
+
+NetworkClientInfo *net_client_info(NetClientState *nc)
+{
+ NetworkClientInfo *info = net_client_info_no_peer(nc);
+
+ if (nc->peer) {
+ info->peer = net_client_info_no_peer(nc->peer);
}
+
+ return info;
+}
+
+NetworkInfo *qmp_x_query_network(Error **errp)
+{
+ NetworkInfo *info = g_new0(NetworkInfo, 1);
+ NetworkClientInfoList **tail = &info->clients;
+ NetClientState *nc;
+
+ info->hubs = net_hub_query_info();
+
+ QTAILQ_FOREACH(nc, &net_clients, next) {
+ /* Skip if already gathered in hub info */
+ if (net_hub_id_for_client(nc, NULL) == 0) {
+ continue;
+ }
+ QAPI_LIST_APPEND(tail, net_client_info(nc));
+ }
+
+ return info;
}
RxFilterInfoList *qmp_query_rx_filter(const char *name, Error **errp)
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 21/39] tests/qtest/netdev-socket: replace HMP with x-query-network QMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (19 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 20/39] net: add x-query-network QMP command Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
` (18 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Replace the HMP "info network" text parsing with the structured
x-query-network QMP command. This makes the test assertions more robust
by matching individual fields (info-str) instead of parsing the full HMP
line format.
The EXPECT_STATE macro now takes an explicit netdev id argument to look
up the client by name in the QMP response. The strrchr truncation is
made NULL-safe: if the truncation character is not found, the full
string is compared (and the final g_assert_cmpstr will catch
mismatches).
While at it, fix the pre-existing duplicate "qemu/sockets.h" include,
and reorder includes.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/netdev-socket.c | 143 +++++++++++++++++++++++++-------------------
1 file changed, 82 insertions(+), 61 deletions(-)
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
index b731af0ad95..30005c2e001 100644
--- a/tests/qtest/netdev-socket.c
+++ b/tests/qtest/netdev-socket.c
@@ -7,33 +7,62 @@
*/
#include "qemu/osdep.h"
-#include "qemu/sockets.h"
#include <glib/gstdio.h>
#include "../unit/socket-helpers.h"
#include "libqtest.h"
-#include "qobject/qstring.h"
-#include "qemu/sockets.h"
-#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-sockets.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qemu/sockets.h"
+#include "qobject/qdict.h"
+#include "qobject/qlist.h"
+#include "qobject/qstring.h"
#define CONNECTION_TIMEOUT 60
-#define EXPECT_STATE(q, e, t) \
-do { \
- char *resp = NULL; \
- g_test_timer_start(); \
- do { \
- g_free(resp); \
- resp = qtest_hmp(q, "info network"); \
- if (t) { \
- strrchr(resp, t)[0] = 0; \
- } \
- if (g_str_equal(resp, e)) { \
- break; \
- } \
- } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
- g_assert_cmpstr(resp, ==, e); \
- g_free(resp); \
+/*
+ * Only checks info-str; type is implicit from the netdev created by each test
+ */
+static char *query_net_info_str(QTestState *q, const char *name)
+{
+ QDict *ret;
+ QList *clients;
+ QListEntry *entry;
+
+ ret = qtest_qmp_assert_success_ref(q, "{'execute': 'x-query-network'}");
+ clients = qdict_get_qlist(ret, "clients");
+ g_assert_nonnull(clients);
+
+ QLIST_FOREACH_ENTRY(clients, entry) {
+ QDict *client = qobject_to(QDict, qlist_entry_obj(entry));
+ if (g_str_equal(qdict_get_str(client, "name"), name)) {
+ char *info = g_strdup(qdict_get_str(client, "info-str"));
+ qobject_unref(ret);
+ return info;
+ }
+ }
+
+ g_assert_not_reached();
+}
+
+#define EXPECT_STATE(q, id, e, t) \
+do { \
+ char *info = NULL; \
+ g_test_timer_start(); \
+ do { \
+ g_free(info); \
+ info = query_net_info_str(q, id); \
+ if (t) { \
+ char *p = strrchr(info, t); \
+ if (p) { \
+ p[0] = 0; \
+ } \
+ } \
+ if (g_str_equal(info, e)) { \
+ break; \
+ } \
+ } while (g_test_timer_elapsed() < CONNECTION_TIMEOUT); \
+ g_assert_cmpstr(info, ==, e); \
+ g_free(info); \
} while (0)
static gchar *tmpdir;
@@ -127,20 +156,19 @@ static void test_stream_inet_ipv4(void)
"addr.ipv4=on,addr.ipv6=off,"
"addr.host=127.0.0.1,addr.port=%d", port);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "listening", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,server=false,id=st0,addr.type=inet,"
"addr.ipv4=on,addr.ipv6=off,"
"addr.host=127.0.0.1,addr.port=%d", port);
- expect = g_strdup_printf("st0: index=0,type=stream,tcp:127.0.0.1:%d\r\n",
- port);
- EXPECT_STATE(qts1, expect, 0);
+ expect = g_strdup_printf("tcp:127.0.0.1:%d", port);
+ EXPECT_STATE(qts1, "st0", expect, 0);
g_free(expect);
/* the port is unknown, check only the address */
- EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:127.0.0.1", ':');
+ EXPECT_STATE(qts0, "st0", "tcp:127.0.0.1", ':');
qtest_quit(qts1);
qtest_quit(qts0);
@@ -200,7 +228,7 @@ static void test_stream_unix_reconnect(void)
"-netdev stream,id=st0,server=true,addr.type=unix,"
"addr.path=%s", path);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "listening", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,server=false,id=st0,addr.type=unix,"
@@ -250,20 +278,19 @@ static void test_stream_inet_ipv6(void)
"addr.ipv4=off,addr.ipv6=on,"
"addr.host=::1,addr.port=%d", port);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "listening", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,server=false,id=st0,addr.type=inet,"
"addr.ipv4=off,addr.ipv6=on,"
"addr.host=::1,addr.port=%d", port);
- expect = g_strdup_printf("st0: index=0,type=stream,tcp:::1:%d\r\n",
- port);
- EXPECT_STATE(qts1, expect, 0);
+ expect = g_strdup_printf("tcp:::1:%d", port);
+ EXPECT_STATE(qts1, "st0", expect, 0);
g_free(expect);
/* the port is unknown, check only the address */
- EXPECT_STATE(qts0, "st0: index=0,type=stream,tcp:::1", ':');
+ EXPECT_STATE(qts0, "st0", "tcp:::1", ':');
qtest_quit(qts1);
qtest_quit(qts0);
@@ -282,16 +309,16 @@ static void test_stream_unix(void)
"addr.type=unix,addr.path=%s,",
path);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "listening", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,id=st0,server=false,"
"addr.type=unix,addr.path=%s",
path);
- expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
- EXPECT_STATE(qts1, expect, 0);
- EXPECT_STATE(qts0, expect, 0);
+ expect = g_strdup_printf("unix:%s", path);
+ EXPECT_STATE(qts1, "st0", expect, 0);
+ EXPECT_STATE(qts0, "st0", expect, 0);
g_free(expect);
g_free(path);
@@ -314,16 +341,16 @@ static void test_stream_unix_abstract(void)
"addr.abstract=on",
path);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,listening\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "listening", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,id=st0,server=false,"
"addr.type=unix,addr.path=%s,addr.abstract=on",
path);
- expect = g_strdup_printf("st0: index=0,type=stream,unix:%s\r\n", path);
- EXPECT_STATE(qts1, expect, 0);
- EXPECT_STATE(qts0, expect, 0);
+ expect = g_strdup_printf("unix:%s", path);
+ EXPECT_STATE(qts1, "st0", expect, 0);
+ EXPECT_STATE(qts0, "st0", expect, 0);
g_free(expect);
g_free(path);
@@ -346,14 +373,14 @@ static void test_stream_fd(void)
"-netdev stream,id=st0,addr.type=fd,addr.str=%d",
sock[0]);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);
+ EXPECT_STATE(qts0, "st0", "unix:", 0);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev stream,id=st0,addr.type=fd,addr.str=%d",
sock[1]);
- EXPECT_STATE(qts1, "st0: index=0,type=stream,unix:\r\n", 0);
- EXPECT_STATE(qts0, "st0: index=0,type=stream,unix:\r\n", 0);
+ EXPECT_STATE(qts1, "st0", "unix:", 0);
+ EXPECT_STATE(qts0, "st0", "unix:", 0);
qtest_quit(qts1);
qtest_quit(qts0);
@@ -379,10 +406,9 @@ static void test_dgram_inet(void)
"remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
port[0], port[1]);
- expect = g_strdup_printf("st0: index=0,type=dgram,"
- "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
+ expect = g_strdup_printf("udp=127.0.0.1:%d/127.0.0.1:%d",
port[0], port[1]);
- EXPECT_STATE(qts0, expect, 0);
+ EXPECT_STATE(qts0, "st0", expect, 0);
g_free(expect);
qts1 = qtest_initf("-nodefaults -M none "
@@ -391,10 +417,9 @@ static void test_dgram_inet(void)
"remote.type=inet,remote.host=127.0.0.1,remote.port=%d",
port[1], port[0]);
- expect = g_strdup_printf("st0: index=0,type=dgram,"
- "udp=127.0.0.1:%d/127.0.0.1:%d\r\n",
+ expect = g_strdup_printf("udp=127.0.0.1:%d/127.0.0.1:%d",
port[1], port[0]);
- EXPECT_STATE(qts1, expect, 0);
+ EXPECT_STATE(qts1, "st0", expect, 0);
g_free(expect);
qtest_quit(qts1);
@@ -410,7 +435,7 @@ static void test_dgram_mcast(void)
"-netdev dgram,id=st0,"
"remote.type=inet,remote.host=230.0.0.1,remote.port=1234");
- EXPECT_STATE(qts, "st0: index=0,type=dgram,mcast=230.0.0.1:1234\r\n", 0);
+ EXPECT_STATE(qts, "st0", "mcast=230.0.0.1:1234", 0);
qtest_quit(qts);
}
@@ -431,9 +456,8 @@ static void test_dgram_unix(void)
"remote.type=unix,remote.path=%s",
path0, path1);
- expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
- path0, path1);
- EXPECT_STATE(qts0, expect, 0);
+ expect = g_strdup_printf("udp=%s:%s", path0, path1);
+ EXPECT_STATE(qts0, "st0", expect, 0);
g_free(expect);
qts1 = qtest_initf("-nodefaults -M none "
@@ -441,10 +465,8 @@ static void test_dgram_unix(void)
"remote.type=unix,remote.path=%s",
path1, path0);
-
- expect = g_strdup_printf("st0: index=0,type=dgram,udp=%s:%s\r\n",
- path1, path0);
- EXPECT_STATE(qts1, expect, 0);
+ expect = g_strdup_printf("udp=%s:%s", path1, path0);
+ EXPECT_STATE(qts1, "st0", expect, 0);
g_free(expect);
unlink(path0);
@@ -470,17 +492,16 @@ static void test_dgram_fd(void)
"-netdev dgram,id=st0,local.type=fd,local.str=%d",
sv[0]);
- expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[0]);
- EXPECT_STATE(qts0, expect, 0);
+ expect = g_strdup_printf("fd=%d unix", sv[0]);
+ EXPECT_STATE(qts0, "st0", expect, 0);
g_free(expect);
qts1 = qtest_initf("-nodefaults -M none "
"-netdev dgram,id=st0,local.type=fd,local.str=%d",
sv[1]);
-
- expect = g_strdup_printf("st0: index=0,type=dgram,fd=%d unix\r\n", sv[1]);
- EXPECT_STATE(qts1, expect, 0);
+ expect = g_strdup_printf("fd=%d unix", sv[1]);
+ EXPECT_STATE(qts1, "st0", expect, 0);
g_free(expect);
qtest_quit(qts1);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (20 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 21/39] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:19 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol Marc-André Lureau
` (17 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster,
Philippe Mathieu-Daudé
Convert the qemu-io command infrastructure to use QEMU's Error API
(Error **errp) for error propagation instead of printing directly to
stdout/stderr via printf/fprintf.
The cfunc_t typedef, all ~35 command functions, the dispatcher chain
(command/init_check_command/qemuio_command), and helper functions
(parse_pattern, create_iovec, qemu_io_alloc_from_file) all gain an
Error **errp parameter. Async completion callbacks (aio_read_done,
aio_write_done, aio_discard_done) use error_report() since they have
no Error path back to the caller.
Update tests:
- error_report_err() prepends qemu-io: prefix
- copy-before-write: check the HMP return value, rather than stdio
- other tests: update to check JSON {"return": "Error: error text"}
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qemu-io.h | 4 +-
block/monitor/block-hmp-cmds.c | 2 +-
qemu-io-cmds.c | 414 +++++++++++++------------
qemu-io.c | 17 +-
tests/qemu-iotests/004.out | 20 +-
tests/qemu-iotests/021.out | 60 ++--
tests/qemu-iotests/026.out | 228 +++++++-------
tests/qemu-iotests/060.out | 44 ++-
tests/qemu-iotests/071.out | 10 +-
tests/qemu-iotests/072.out | 2 +-
tests/qemu-iotests/080.out | 4 +-
tests/qemu-iotests/081.out | 2 +-
tests/qemu-iotests/083.out | 36 +--
tests/qemu-iotests/089.out | 4 +-
tests/qemu-iotests/114.out | 2 +-
tests/qemu-iotests/134.out | 2 +-
tests/qemu-iotests/137.out | 2 +-
tests/qemu-iotests/153.out | 12 +-
tests/qemu-iotests/171 | 2 +-
tests/qemu-iotests/171.out | 68 ++--
tests/qemu-iotests/205 | 2 +-
tests/qemu-iotests/214.out | 2 +-
tests/qemu-iotests/220.out | 2 +-
tests/qemu-iotests/225.out | 4 +-
tests/qemu-iotests/244.out | 12 +-
tests/qemu-iotests/249.out | 6 +-
tests/qemu-iotests/271.out | 14 +-
tests/qemu-iotests/289.out | 2 +-
tests/qemu-iotests/305.out | 2 +-
tests/qemu-iotests/307.out | 2 +-
tests/qemu-iotests/tests/backup-discard-source | 4 +-
tests/qemu-iotests/tests/copy-before-write | 66 ++--
tests/qemu-iotests/tests/file-io-error.out | 2 +-
tests/qemu-iotests/tests/image-fleecing.out | 12 +-
tests/qemu-iotests/tests/inactive-node-nbd.out | 8 +-
35 files changed, 552 insertions(+), 523 deletions(-)
diff --git a/include/qemu-io.h b/include/qemu-io.h
index 3af513004a6..240764bb35c 100644
--- a/include/qemu-io.h
+++ b/include/qemu-io.h
@@ -25,7 +25,7 @@
* Operate on @blk using @argc/@argv as the command's arguments, and
* return 0 on success or negative errno on failure.
*/
-typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv);
+typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv, Error **errp);
typedef void (*helpfunc_t)(void);
@@ -45,7 +45,7 @@ typedef struct cmdinfo {
extern bool qemuio_misalign;
-int qemuio_command(BlockBackend *blk, const char *cmd);
+int qemuio_command(BlockBackend *blk, const char *cmd, Error **errp);
void qemuio_add_command(const cmdinfo_t *ci);
void qemuio_command_usage(const cmdinfo_t *ci);
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 69ade0534f1..c7113b8ea5e 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -608,7 +608,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
* extended, possibly resulting in a read-only guest device keeping write
* permissions. Ugly, but it appears to be the lesser evil.
*/
- qemuio_command(blk, command);
+ qemuio_command(blk, command, &err);
fail:
blk_unref(local_blk);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index de4c1966fea..aa795fd87a1 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -55,40 +55,43 @@ void qemuio_command_usage(const cmdinfo_t *ci)
printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
}
-static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct)
+static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct,
+ Error **errp)
{
if (ct->flags & CMD_FLAG_GLOBAL) {
return 1;
}
if (!(ct->flags & CMD_NOFILE_OK) && !blk) {
- fprintf(stderr, "no file open, try 'help open'\n");
+ error_setg(errp, "no file open, try 'help open'");
return 0;
}
return 1;
}
static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
- char **argv)
+ char **argv, Error **errp)
{
char *cmd = argv[0];
- if (!init_check_command(blk, ct)) {
+ if (!init_check_command(blk, ct, errp)) {
return -EINVAL;
}
if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
if (ct->argmax == -1) {
- fprintf(stderr,
- "bad argument count %d to %s, expected at least %d arguments\n",
- argc-1, cmd, ct->argmin);
+ error_setg(errp,
+ "bad argument count %d to %s,"
+ " expected at least %d arguments",
+ argc - 1, cmd, ct->argmin);
} else if (ct->argmin == ct->argmax) {
- fprintf(stderr,
- "bad argument count %d to %s, expected %d arguments\n",
- argc-1, cmd, ct->argmin);
+ error_setg(errp,
+ "bad argument count %d to %s, expected %d arguments",
+ argc - 1, cmd, ct->argmin);
} else {
- fprintf(stderr,
- "bad argument count %d to %s, expected between %d and %d arguments\n",
- argc-1, cmd, ct->argmin, ct->argmax);
+ error_setg(errp,
+ "bad argument count %d to %s,"
+ " expected between %d and %d arguments",
+ argc - 1, cmd, ct->argmin, ct->argmax);
}
return -EINVAL;
}
@@ -112,21 +115,19 @@ static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
if (ct->perm & ~orig_perm) {
uint64_t new_perm;
- Error *local_err = NULL;
int ret;
new_perm = orig_perm | ct->perm;
- ret = blk_set_perm(blk, new_perm, orig_shared_perm, &local_err);
+ ret = blk_set_perm(blk, new_perm, orig_shared_perm, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
}
}
qemu_reset_optind();
- return ct->cfunc(blk, argc, argv);
+ return ct->cfunc(blk, argc, argv, errp);
}
static const cmdinfo_t *find_command(const char *cmd)
@@ -192,18 +193,18 @@ static int64_t cvtnum(const char *s)
return value;
}
-static void print_cvtnum_err(int64_t rc, const char *arg)
+static void set_cvtnum_err(int64_t rc, const char *arg, Error **errp)
{
switch (rc) {
case -EINVAL:
- printf("Parsing error: non-numeric argument,"
- " or extraneous/unrecognized suffix -- %s\n", arg);
+ error_setg(errp, "Parsing error: non-numeric argument,"
+ " or extraneous/unrecognized suffix -- %s", arg);
break;
case -ERANGE:
- printf("Parsing error: argument too large -- %s\n", arg);
+ error_setg(errp, "Parsing error: argument too large -- %s", arg);
break;
default:
- printf("Parsing error: %s\n", arg);
+ error_setg(errp, "Parsing error: %s", arg);
}
}
@@ -316,14 +317,14 @@ static void timestr(struct timespec *tv, char *ts, size_t size, int format)
* Because the pattern is used as an argument to memset it must evaluate
* to an unsigned integer that fits into a single byte.
*/
-static int parse_pattern(const char *arg)
+static int parse_pattern(const char *arg, Error **errp)
{
char *endptr = NULL;
long pattern;
pattern = strtol(arg, &endptr, 0);
if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
- printf("%s is not a valid pattern byte\n", arg);
+ error_setg(errp, "%s is not a valid pattern byte", arg);
return -1;
}
@@ -386,7 +387,8 @@ static void qemu_io_free(BlockBackend *blk, void *p, size_t len,
* NULL on error
*/
static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
- const char *file_name, bool register_buf)
+ const char *file_name, bool register_buf,
+ Error **errp)
{
size_t alloc_len = len + (qemuio_misalign ? MISALIGN_OFFSET : 0);
char *alloc_buf, *buf, *end;
@@ -394,7 +396,7 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
int pattern_len;
if (!f) {
- perror(file_name);
+ error_setg_errno(errp, errno, "%s", file_name);
return NULL;
}
@@ -407,12 +409,12 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
pattern_len = fread(buf, 1, len, f);
if (ferror(f)) {
- perror(file_name);
+ error_setg_errno(errp, errno, "%s", file_name);
goto error;
}
if (pattern_len == 0) {
- fprintf(stderr, "%s: file is empty\n", file_name);
+ error_setg(errp, "%s: file is empty", file_name);
goto error;
}
@@ -494,7 +496,7 @@ static void print_report(const char *op, struct timespec *t, int64_t offset,
*/
static void *
create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
- int pattern, bool register_buf)
+ int pattern, bool register_buf, Error **errp)
{
size_t *sizes = g_new0(size_t, nr_iov);
size_t count = 0;
@@ -508,19 +510,20 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
len = cvtnum(arg);
if (len < 0) {
- print_cvtnum_err(len, arg);
+ set_cvtnum_err(len, arg, errp);
goto fail;
}
if (len > BDRV_REQUEST_MAX_BYTES) {
- printf("Argument '%s' exceeds maximum size %" PRIu64 "\n", arg,
- (uint64_t)BDRV_REQUEST_MAX_BYTES);
+ error_setg(errp, "Argument '%s' exceeds maximum size %" PRIu64,
+ arg, (uint64_t)BDRV_REQUEST_MAX_BYTES);
goto fail;
}
if (count > BDRV_REQUEST_MAX_BYTES - len) {
- printf("The total number of bytes exceed the maximum size %" PRIu64
- "\n", (uint64_t)BDRV_REQUEST_MAX_BYTES);
+ error_setg(errp,
+ "The total number of bytes exceed the maximum size %"
+ PRIu64, (uint64_t)BDRV_REQUEST_MAX_BYTES);
goto fail;
}
@@ -692,7 +695,7 @@ static void read_help(void)
"\n");
}
-static int read_f(BlockBackend *blk, int argc, char **argv);
+static int read_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t read_cmd = {
.name = "read",
@@ -705,7 +708,7 @@ static const cmdinfo_t read_cmd = {
.help = read_help,
};
-static int read_f(BlockBackend *blk, int argc, char **argv)
+static int read_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
struct timespec t1, t2;
bool Cflag = false, qflag = false, vflag = false;
@@ -732,7 +735,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
lflag = true;
pattern_count = cvtnum(optarg);
if (pattern_count < 0) {
- print_cvtnum_err(pattern_count, optarg);
+ set_cvtnum_err(pattern_count, optarg, errp);
return pattern_count;
}
break;
@@ -741,7 +744,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
break;
case 'P':
Pflag = true;
- pattern = parse_pattern(optarg);
+ pattern = parse_pattern(optarg, errp);
if (pattern < 0) {
return -EINVAL;
}
@@ -756,7 +759,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
sflag = true;
pattern_offset = cvtnum(optarg);
if (pattern_offset < 0) {
- print_cvtnum_err(pattern_offset, optarg);
+ set_cvtnum_err(pattern_offset, optarg, errp);
return pattern_offset;
}
break;
@@ -776,18 +779,18 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
count = cvtnum(argv[optind]);
if (count < 0) {
- print_cvtnum_err(count, argv[optind]);
+ set_cvtnum_err(count, argv[optind], errp);
return count;
} else if (count > BDRV_REQUEST_MAX_BYTES) {
- printf("length cannot exceed %" PRIu64 ", given %s\n",
- (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+ error_setg(errp, "length cannot exceed %" PRIu64 ", given %s",
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return -EINVAL;
}
@@ -801,24 +804,26 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
}
if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
- printf("pattern verification range exceeds end of read data\n");
+ error_setg(errp, "pattern verification range exceeds end of read data");
return -EINVAL;
}
if (bflag) {
if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
- printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
- offset);
+ error_setg(errp,
+ "%" PRId64 " is not a sector-aligned value for 'offset'",
+ offset);
return -EINVAL;
}
if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
- printf("%"PRId64" is not a sector-aligned value for 'count'\n",
- count);
+ error_setg(errp,
+ "%" PRId64 " is not a sector-aligned value for 'count'",
+ count);
return -EINVAL;
}
if (flags & BDRV_REQ_REGISTERED_BUF) {
- printf("I/O buffer registration is not supported when reading "
- "from vmstate\n");
+ error_setg(errp, "I/O buffer registration is not supported when"
+ " reading from vmstate");
return -EINVAL;
}
}
@@ -834,7 +839,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("read failed: %s\n", strerror(-ret));
+ error_setg(errp, "read failed: %s", strerror(-ret));
goto out;
}
cnt = ret;
@@ -845,9 +850,9 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
void *cmp_buf = g_malloc(pattern_count);
memset(cmp_buf, pattern, pattern_count);
if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
- printf("Pattern verification failed at offset %"
- PRId64 ", %"PRId64" bytes\n",
- offset + pattern_offset, pattern_count);
+ error_setg(errp, "Pattern verification failed at offset %"
+ PRId64 ", %" PRId64 " bytes",
+ offset + pattern_offset, pattern_count);
ret = -EINVAL;
}
g_free(cmp_buf);
@@ -890,7 +895,7 @@ static void readv_help(void)
"\n");
}
-static int readv_f(BlockBackend *blk, int argc, char **argv);
+static int readv_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t readv_cmd = {
.name = "readv",
@@ -902,7 +907,7 @@ static const cmdinfo_t readv_cmd = {
.help = readv_help,
};
-static int readv_f(BlockBackend *blk, int argc, char **argv)
+static int readv_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
struct timespec t1, t2;
bool Cflag = false, qflag = false, vflag = false;
@@ -924,7 +929,7 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
break;
case 'P':
Pflag = true;
- pattern = parse_pattern(optarg);
+ pattern = parse_pattern(optarg, errp);
if (pattern < 0) {
return -EINVAL;
}
@@ -952,14 +957,14 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
nr_iov = argc - optind;
buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab,
- flags & BDRV_REQ_REGISTERED_BUF);
+ flags & BDRV_REQ_REGISTERED_BUF, errp);
if (buf == NULL) {
return -EINVAL;
}
@@ -969,7 +974,7 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("readv failed: %s\n", strerror(-ret));
+ error_setg(errp, "readv failed: %s", strerror(-ret));
goto out;
}
cnt = ret;
@@ -980,8 +985,8 @@ static int readv_f(BlockBackend *blk, int argc, char **argv)
void *cmp_buf = g_malloc(qiov.size);
memset(cmp_buf, pattern, qiov.size);
if (memcmp(buf, cmp_buf, qiov.size)) {
- printf("Pattern verification failed at offset %"
- PRId64 ", %zu bytes\n", offset, qiov.size);
+ error_setg(errp, "Pattern verification failed at offset %"
+ PRId64 ", %zu bytes", offset, qiov.size);
ret = -EINVAL;
}
g_free(cmp_buf);
@@ -1031,7 +1036,7 @@ static void write_help(void)
"\n");
}
-static int write_f(BlockBackend *blk, int argc, char **argv);
+static int write_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t write_cmd = {
.name = "write",
@@ -1045,7 +1050,7 @@ static const cmdinfo_t write_cmd = {
.help = write_help,
};
-static int write_f(BlockBackend *blk, int argc, char **argv)
+static int write_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
struct timespec t1, t2;
bool Cflag = false, qflag = false, bflag = false;
@@ -1082,7 +1087,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
break;
case 'P':
Pflag = true;
- pattern = parse_pattern(optarg);
+ pattern = parse_pattern(optarg, errp);
if (pattern < 0) {
return -EINVAL;
}
@@ -1115,72 +1120,78 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
}
if (bflag && zflag) {
- printf("-b and -z cannot be specified at the same time\n");
+ error_setg(errp, "-b and -z cannot be specified at the same time");
return -EINVAL;
}
if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
- printf("-f and -b or -c cannot be specified at the same time\n");
+ error_setg(errp,
+ "-f and -b or -c cannot be specified at the same time");
return -EINVAL;
}
if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
- printf("-n requires -z to be specified\n");
+ error_setg(errp, "-n requires -z to be specified");
return -EINVAL;
}
if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
- printf("-u requires -z to be specified\n");
+ error_setg(errp, "-u requires -z to be specified");
return -EINVAL;
}
if (zflag + Pflag + sflag > 1) {
- printf("Only one of -z, -P, and -s "
- "can be specified at the same time\n");
+ error_setg(errp, "Only one of -z, -P, and -s "
+ "can be specified at the same time");
return -EINVAL;
}
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
count = cvtnum(argv[optind]);
if (count < 0) {
- print_cvtnum_err(count, argv[optind]);
+ set_cvtnum_err(count, argv[optind], errp);
return count;
} else if (count > BDRV_REQUEST_MAX_BYTES &&
!(flags & BDRV_REQ_NO_FALLBACK)) {
- printf("length cannot exceed %" PRIu64 " without -n, given %s\n",
- (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+ error_setg(errp,
+ "length cannot exceed %" PRIu64 " without -n, given %s",
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return -EINVAL;
}
if (bflag || cflag) {
if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
- printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
- offset);
+ error_setg(errp,
+ "%" PRId64 " is not a sector-aligned value for 'offset'",
+ offset);
return -EINVAL;
}
if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
- printf("%"PRId64" is not a sector-aligned value for 'count'\n",
- count);
+ error_setg(errp,
+ "%" PRId64 " is not a sector-aligned value for 'count'",
+ count);
return -EINVAL;
}
}
if (zflag) {
if (flags & BDRV_REQ_REGISTERED_BUF) {
- printf("cannot combine zero write with registered I/O buffer\n");
+ error_setg(errp,
+ "cannot combine zero write with registered I/O buffer");
return -EINVAL;
}
} else {
if (sflag) {
buf = qemu_io_alloc_from_file(blk, count, file_name,
- flags & BDRV_REQ_REGISTERED_BUF);
+ flags & BDRV_REQ_REGISTERED_BUF,
+ errp);
if (!buf) {
return -EINVAL;
}
@@ -1203,7 +1214,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("write failed: %s\n", strerror(-ret));
+ error_setg(errp, "write failed: %s", strerror(-ret));
goto out;
}
cnt = ret;
@@ -1245,7 +1256,7 @@ writev_help(void)
"\n");
}
-static int writev_f(BlockBackend *blk, int argc, char **argv);
+static int writev_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t writev_cmd = {
.name = "writev",
@@ -1258,7 +1269,7 @@ static const cmdinfo_t writev_cmd = {
.help = writev_help,
};
-static int writev_f(BlockBackend *blk, int argc, char **argv)
+static int writev_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
struct timespec t1, t2;
bool Cflag = false, qflag = false;
@@ -1287,7 +1298,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
flags |= BDRV_REQ_REGISTERED_BUF;
break;
case 'P':
- pattern = parse_pattern(optarg);
+ pattern = parse_pattern(optarg, errp);
if (pattern < 0) {
return -EINVAL;
}
@@ -1305,14 +1316,14 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
nr_iov = argc - optind;
buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
- flags & BDRV_REQ_REGISTERED_BUF);
+ flags & BDRV_REQ_REGISTERED_BUF, errp);
if (buf == NULL) {
return -EINVAL;
}
@@ -1322,7 +1333,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("writev failed: %s\n", strerror(-ret));
+ error_setg(errp, "writev failed: %s", strerror(-ret));
goto out;
}
cnt = ret;
@@ -1367,7 +1378,7 @@ static void aio_write_done(void *opaque, int ret)
if (ret < 0) {
- printf("aio_write failed: %s\n", strerror(-ret));
+ error_report("aio_write failed: %s", strerror(-ret));
block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
goto out;
}
@@ -1399,7 +1410,7 @@ static void aio_read_done(void *opaque, int ret)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("readv failed: %s\n", strerror(-ret));
+ error_report("readv failed: %s", strerror(-ret));
block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
goto out;
}
@@ -1409,8 +1420,8 @@ static void aio_read_done(void *opaque, int ret)
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
- printf("Pattern verification failed at offset %"
- PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
+ error_report("Pattern verification failed at offset %"
+ PRId64 ", %zu bytes", ctx->offset, ctx->qiov.size);
}
g_free(cmp_buf);
}
@@ -1461,7 +1472,7 @@ static void aio_read_help(void)
"\n");
}
-static int aio_read_f(BlockBackend *blk, int argc, char **argv);
+static int aio_read_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t aio_read_cmd = {
.name = "aio_read",
@@ -1473,7 +1484,7 @@ static const cmdinfo_t aio_read_cmd = {
.help = aio_read_help,
};
-static int aio_read_f(BlockBackend *blk, int argc, char **argv)
+static int aio_read_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int nr_iov, c;
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
@@ -1486,7 +1497,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
break;
case 'P':
ctx->Pflag = true;
- ctx->pattern = parse_pattern(optarg);
+ ctx->pattern = parse_pattern(optarg, errp);
if (ctx->pattern < 0) {
g_free(ctx);
return -EINVAL;
@@ -1522,7 +1533,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
int ret = ctx->offset;
- print_cvtnum_err(ret, argv[optind]);
+ set_cvtnum_err(ret, argv[optind], errp);
g_free(ctx);
return ret;
}
@@ -1530,7 +1541,7 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv)
nr_iov = argc - optind;
ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab,
- ctx->flags & BDRV_REQ_REGISTERED_BUF);
+ ctx->flags & BDRV_REQ_REGISTERED_BUF, errp);
if (ctx->buf == NULL) {
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
g_free(ctx);
@@ -1573,7 +1584,7 @@ static void aio_write_help(void)
"\n");
}
-static int aio_write_f(BlockBackend *blk, int argc, char **argv);
+static int aio_write_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t aio_write_cmd = {
.name = "aio_write",
@@ -1586,7 +1597,7 @@ static const cmdinfo_t aio_write_cmd = {
.help = aio_write_help,
};
-static int aio_write_f(BlockBackend *blk, int argc, char **argv)
+static int aio_write_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int nr_iov, c;
int pattern = 0xcd;
@@ -1611,7 +1622,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
ctx->flags |= BDRV_REQ_MAY_UNMAP;
break;
case 'P':
- pattern = parse_pattern(optarg);
+ pattern = parse_pattern(optarg, errp);
if (pattern < 0) {
g_free(ctx);
return -EINVAL;
@@ -1639,25 +1650,26 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
}
if (ctx->zflag && optind != argc - 2) {
- printf("-z supports only a single length parameter\n");
+ error_setg(errp, "-z supports only a single length parameter");
g_free(ctx);
return -EINVAL;
}
if ((ctx->flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
- printf("-u requires -z to be specified\n");
+ error_setg(errp, "-u requires -z to be specified");
g_free(ctx);
return -EINVAL;
}
if (ctx->zflag && ctx->Pflag) {
- printf("-z and -P cannot be specified at the same time\n");
+ error_setg(errp, "-z and -P cannot be specified at the same time");
g_free(ctx);
return -EINVAL;
}
if (ctx->zflag && (ctx->flags & BDRV_REQ_REGISTERED_BUF)) {
- printf("cannot combine zero write with registered I/O buffer\n");
+ error_setg(errp,
+ "cannot combine zero write with registered I/O buffer");
g_free(ctx);
return -EINVAL;
}
@@ -1665,7 +1677,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
int ret = ctx->offset;
- print_cvtnum_err(ret, argv[optind]);
+ set_cvtnum_err(ret, argv[optind], errp);
g_free(ctx);
return ret;
}
@@ -1674,7 +1686,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
if (ctx->zflag) {
int64_t count = cvtnum(argv[optind]);
if (count < 0) {
- print_cvtnum_err(count, argv[optind]);
+ set_cvtnum_err(count, argv[optind], errp);
g_free(ctx);
return count;
}
@@ -1685,7 +1697,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
} else {
nr_iov = argc - optind;
ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
- pattern, ctx->flags & BDRV_REQ_REGISTERED_BUF);
+ pattern,
+ ctx->flags & BDRV_REQ_REGISTERED_BUF, errp);
if (ctx->buf == NULL) {
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
g_free(ctx);
@@ -1703,7 +1716,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
-static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
+static int aio_flush_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
BlockAcctCookie cookie;
block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
@@ -1718,7 +1731,7 @@ static const cmdinfo_t aio_flush_cmd = {
.oneline = "completes all outstanding aio requests"
};
-static int flush_f(BlockBackend *blk, int argc, char **argv)
+static int flush_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
return blk_flush(blk);
}
@@ -1735,7 +1748,7 @@ static inline int64_t tosector(int64_t bytes)
return bytes >> BDRV_SECTOR_BITS;
}
-static int zone_report_f(BlockBackend *blk, int argc, char **argv)
+static int zone_report_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
int64_t offset;
@@ -1745,17 +1758,17 @@ static int zone_report_f(BlockBackend *blk, int argc, char **argv)
++optind;
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
++optind;
val = cvtnum(argv[optind]);
if (val < 0) {
- print_cvtnum_err(val, argv[optind]);
+ set_cvtnum_err(val, argv[optind], errp);
return val;
}
if (val > UINT_MAX) {
- printf("Number of zones must be less than 2^32\n");
+ error_setg(errp, "Number of zones must be less than 2^32");
return -ERANGE;
}
nr_zones = val;
@@ -1764,7 +1777,7 @@ static int zone_report_f(BlockBackend *blk, int argc, char **argv)
zones = g_new(BlockZoneDescriptor, nr_zones);
ret = blk_zone_report(blk, offset, &nr_zones, zones);
if (ret < 0) {
- printf("zone report failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone report failed: %s", strerror(-ret));
} else {
for (int i = 0; i < nr_zones; ++i) {
printf("start: 0x%" PRIx64 ", len 0x%" PRIx64 ", "
@@ -1788,25 +1801,25 @@ static const cmdinfo_t zone_report_cmd = {
.oneline = "report zone information",
};
-static int zone_open_f(BlockBackend *blk, int argc, char **argv)
+static int zone_open_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
int64_t offset, len;
++optind;
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
++optind;
len = cvtnum(argv[optind]);
if (len < 0) {
- print_cvtnum_err(len, argv[optind]);
+ set_cvtnum_err(len, argv[optind], errp);
return len;
}
ret = blk_zone_mgmt(blk, BLK_ZO_OPEN, offset, len);
if (ret < 0) {
- printf("zone open failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone open failed: %s", strerror(-ret));
}
return ret;
}
@@ -1821,25 +1834,25 @@ static const cmdinfo_t zone_open_cmd = {
.oneline = "explicit open a range of zones in zone block device",
};
-static int zone_close_f(BlockBackend *blk, int argc, char **argv)
+static int zone_close_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
int64_t offset, len;
++optind;
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
++optind;
len = cvtnum(argv[optind]);
if (len < 0) {
- print_cvtnum_err(len, argv[optind]);
+ set_cvtnum_err(len, argv[optind], errp);
return len;
}
ret = blk_zone_mgmt(blk, BLK_ZO_CLOSE, offset, len);
if (ret < 0) {
- printf("zone close failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone close failed: %s", strerror(-ret));
}
return ret;
}
@@ -1854,25 +1867,25 @@ static const cmdinfo_t zone_close_cmd = {
.oneline = "close a range of zones in zone block device",
};
-static int zone_finish_f(BlockBackend *blk, int argc, char **argv)
+static int zone_finish_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
int64_t offset, len;
++optind;
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
++optind;
len = cvtnum(argv[optind]);
if (len < 0) {
- print_cvtnum_err(len, argv[optind]);
+ set_cvtnum_err(len, argv[optind], errp);
return len;
}
ret = blk_zone_mgmt(blk, BLK_ZO_FINISH, offset, len);
if (ret < 0) {
- printf("zone finish failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone finish failed: %s", strerror(-ret));
}
return ret;
}
@@ -1887,25 +1900,25 @@ static const cmdinfo_t zone_finish_cmd = {
.oneline = "finish a range of zones in zone block device",
};
-static int zone_reset_f(BlockBackend *blk, int argc, char **argv)
+static int zone_reset_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
int64_t offset, len;
++optind;
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
++optind;
len = cvtnum(argv[optind]);
if (len < 0) {
- print_cvtnum_err(len, argv[optind]);
+ set_cvtnum_err(len, argv[optind], errp);
return len;
}
ret = blk_zone_mgmt(blk, BLK_ZO_RESET, offset, len);
if (ret < 0) {
- printf("zone reset failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone reset failed: %s", strerror(-ret));
}
return ret;
}
@@ -1934,7 +1947,7 @@ static int do_aio_zone_append(BlockBackend *blk, QEMUIOVector *qiov,
return async_ret < 0 ? async_ret : 1;
}
-static int zone_append_f(BlockBackend *blk, int argc, char **argv)
+static int zone_append_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
bool pflag = false;
@@ -1956,19 +1969,19 @@ static int zone_append_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
nr_iov = argc - optind;
buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
- flags & BDRV_REQ_REGISTERED_BUF);
+ flags & BDRV_REQ_REGISTERED_BUF, errp);
if (buf == NULL) {
return -EINVAL;
}
ret = do_aio_zone_append(blk, &qiov, &offset, flags, &total);
if (ret < 0) {
- printf("zone append failed: %s\n", strerror(-ret));
+ error_setg(errp, "zone append failed: %s", strerror(-ret));
goto out;
}
@@ -1994,7 +2007,7 @@ static const cmdinfo_t zone_append_cmd = {
.oneline = "append write a number of bytes at a specified offset",
};
-static int truncate_f(BlockBackend *blk, int argc, char **argv);
+static int truncate_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t truncate_cmd = {
.name = "truncate",
.altname = "t",
@@ -2006,9 +2019,8 @@ static const cmdinfo_t truncate_cmd = {
.oneline = "truncates the current file at the given offset",
};
-static int truncate_f(BlockBackend *blk, int argc, char **argv)
+static int truncate_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
- Error *local_err = NULL;
int64_t offset;
int c, ret;
PreallocMode prealloc = PREALLOC_MODE_OFF;
@@ -2019,7 +2031,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
PREALLOC_MODE__MAX, NULL);
if (prealloc == PREALLOC_MODE__MAX) {
- error_report("Invalid preallocation mode '%s'", optarg);
+ error_setg(errp, "Invalid preallocation mode '%s'", optarg);
return -EINVAL;
}
break;
@@ -2031,7 +2043,7 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[1]);
+ set_cvtnum_err(offset, argv[1], errp);
return offset;
}
@@ -2040,23 +2052,22 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
* exact=true. It is better to err on the "emit more errors" side
* than to be overly permissive.
*/
- ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
+ ret = blk_truncate(blk, offset, false, prealloc, 0, errp);
if (ret < 0) {
- error_report_err(local_err);
return ret;
}
return 0;
}
-static int length_f(BlockBackend *blk, int argc, char **argv)
+static int length_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int64_t size;
char s1[64];
size = blk_getlength(blk);
if (size < 0) {
- printf("getlength: %s\n", strerror(-size));
+ error_setg(errp, "getlength: %s", strerror(-size));
return size;
}
@@ -2074,12 +2085,12 @@ static const cmdinfo_t length_cmd = {
};
-static int info_f(BlockBackend *blk, int argc, char **argv)
+static int info_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
+ ERRP_GUARD();
BlockDriverState *bs = blk_bs(blk);
BlockDriverInfo bdi;
ImageInfoSpecific *spec_info;
- Error *local_err = NULL;
char s1[64], s2[64];
int ret;
@@ -2104,9 +2115,8 @@ static int info_f(BlockBackend *blk, int argc, char **argv)
printf("cluster size: %s\n", s1);
printf("vm state offset: %s\n", s2);
- spec_info = bdrv_get_specific_info(bs, &local_err);
- if (local_err) {
- error_report_err(local_err);
+ spec_info = bdrv_get_specific_info(bs, errp);
+ if (*errp) {
return -EIO;
}
if (spec_info) {
@@ -2143,7 +2153,7 @@ static void discard_help(void)
"\n");
}
-static int discard_f(BlockBackend *blk, int argc, char **argv);
+static int discard_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t discard_cmd = {
.name = "discard",
@@ -2157,7 +2167,7 @@ static const cmdinfo_t discard_cmd = {
.help = discard_help,
};
-static int discard_f(BlockBackend *blk, int argc, char **argv)
+static int discard_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
struct timespec t1, t2;
bool Cflag = false, qflag = false;
@@ -2185,18 +2195,18 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
offset = cvtnum(argv[optind]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[optind]);
+ set_cvtnum_err(offset, argv[optind], errp);
return offset;
}
optind++;
bytes = cvtnum(argv[optind]);
if (bytes < 0) {
- print_cvtnum_err(bytes, argv[optind]);
+ set_cvtnum_err(bytes, argv[optind], errp);
return bytes;
} else if (bytes > BDRV_REQUEST_MAX_BYTES) {
- printf("length cannot exceed %"PRIu64", given %s\n",
- (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
+ error_setg(errp, "length cannot exceed %" PRIu64 ", given %s",
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return -EINVAL;
}
@@ -2205,7 +2215,7 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("discard failed: %s\n", strerror(-ret));
+ error_setg(errp, "discard failed: %s", strerror(-ret));
return ret;
}
@@ -2238,7 +2248,8 @@ static void aio_discard_help(void)
"\n");
}
-static int aio_discard_f(BlockBackend *blk, int argc, char **argv);
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv,
+ Error **errp);
static const cmdinfo_t aio_discard_cmd = {
.name = "aio_discard",
@@ -2259,7 +2270,7 @@ static void aio_discard_done(void *opaque, int ret)
clock_gettime(CLOCK_MONOTONIC, &t2);
if (ret < 0) {
- printf("aio_discard failed: %s\n", strerror(-ret));
+ error_report("aio_discard failed: %s", strerror(-ret));
block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
goto out;
}
@@ -2278,7 +2289,7 @@ out:
g_free(ctx);
}
-static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int c, ret;
int64_t count;
@@ -2310,7 +2321,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
ret = ctx->offset;
- print_cvtnum_err(ret, argv[optind]);
+ set_cvtnum_err(ret, argv[optind], errp);
g_free(ctx);
return ret;
}
@@ -2318,7 +2329,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
count = cvtnum(argv[optind]);
if (count < 0) {
- print_cvtnum_err(count, argv[optind]);
+ set_cvtnum_err(count, argv[optind], errp);
g_free(ctx);
return count;
}
@@ -2332,7 +2343,7 @@ static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
-static int alloc_f(BlockBackend *blk, int argc, char **argv)
+static int alloc_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
BlockDriverState *bs = blk_bs(blk);
int64_t offset, start, remaining, count;
@@ -2342,14 +2353,14 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
start = offset = cvtnum(argv[1]);
if (offset < 0) {
- print_cvtnum_err(offset, argv[1]);
+ set_cvtnum_err(offset, argv[1], errp);
return offset;
}
if (argc == 3) {
count = cvtnum(argv[2]);
if (count < 0) {
- print_cvtnum_err(count, argv[2]);
+ set_cvtnum_err(count, argv[2], errp);
return count;
}
} else {
@@ -2361,7 +2372,7 @@ static int alloc_f(BlockBackend *blk, int argc, char **argv)
while (remaining) {
ret = bdrv_is_allocated(bs, offset, remaining, &num);
if (ret < 0) {
- printf("is_allocated failed: %s\n", strerror(-ret));
+ error_setg(errp, "is_allocated failed: %s", strerror(-ret));
return ret;
}
offset += num;
@@ -2422,7 +2433,7 @@ static int map_is_allocated(BlockDriverState *bs, int64_t offset,
return firstret;
}
-static int map_f(BlockBackend *blk, int argc, char **argv)
+static int map_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int64_t offset, bytes;
char s1[64], s2[64];
@@ -2433,17 +2444,18 @@ static int map_f(BlockBackend *blk, int argc, char **argv)
offset = 0;
bytes = blk_getlength(blk);
if (bytes < 0) {
- error_report("Failed to query image length: %s", strerror(-bytes));
+ error_setg(errp, "Failed to query image length: %s", strerror(-bytes));
return bytes;
}
while (bytes) {
ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
if (ret < 0) {
- error_report("Failed to get allocation status: %s", strerror(-ret));
+ error_setg(errp, "Failed to get allocation status: %s",
+ strerror(-ret));
return ret;
} else if (!num) {
- error_report("Unexpected end of image");
+ error_setg(errp, "Unexpected end of image");
return -EIO;
}
@@ -2485,7 +2497,7 @@ static void reopen_help(void)
"\n");
}
-static int reopen_f(BlockBackend *blk, int argc, char **argv);
+static int reopen_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static QemuOptsList reopen_opts = {
.name = "reopen",
@@ -2507,7 +2519,7 @@ static const cmdinfo_t reopen_cmd = {
.help = reopen_help,
};
-static int reopen_f(BlockBackend *blk, int argc, char **argv)
+static int reopen_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
BlockDriverState *bs = blk_bs(blk);
QemuOpts *qopts;
@@ -2517,13 +2529,12 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
bool writethrough = !blk_enable_write_cache(blk);
bool has_rw_option = false;
bool has_cache_option = false;
- Error *local_err = NULL;
while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
switch (c) {
case 'c':
if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
- error_report("Invalid cache option: %s", optarg);
+ error_setg(errp, "Invalid cache option: %s", optarg);
return -EINVAL;
}
has_cache_option = true;
@@ -2536,7 +2547,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
break;
case 'r':
if (has_rw_option) {
- error_report("Only one -r/-w option may be given");
+ error_setg(errp, "Only one -r/-w option may be given");
return -EINVAL;
}
flags &= ~BDRV_O_RDWR;
@@ -2544,7 +2555,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
break;
case 'w':
if (has_rw_option) {
- error_report("Only one -r/-w option may be given");
+ error_setg(errp, "Only one -r/-w option may be given");
return -EINVAL;
}
flags |= BDRV_O_RDWR;
@@ -2566,7 +2577,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
if (!writethrough != blk_enable_write_cache(blk) &&
blk_get_attached_dev(blk))
{
- error_report("Cannot change cache.writeback: Device attached");
+ error_setg(errp, "Cannot change cache.writeback: Device attached");
qemu_opts_reset(&reopen_opts);
return -EBUSY;
}
@@ -2589,7 +2600,8 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
if (has_rw_option) {
- error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
+ error_setg(errp,
+ "Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
qobject_unref(opts);
return -EINVAL;
}
@@ -2600,7 +2612,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
if (has_cache_option) {
- error_report("Cannot set both -c and the cache options");
+ error_setg(errp, "Cannot set both -c and the cache options");
qobject_unref(opts);
return -EINVAL;
}
@@ -2609,10 +2621,7 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
}
- bdrv_reopen(bs, opts, true, &local_err);
-
- if (local_err) {
- error_report_err(local_err);
+ if (bdrv_reopen(bs, opts, true, errp) < 0) {
return -EINVAL;
}
@@ -2620,26 +2629,28 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
-static int break_f(BlockBackend *blk, int argc, char **argv)
+static int break_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
if (ret < 0) {
- printf("Could not set breakpoint: %s\n", strerror(-ret));
+ error_setg(errp, "Could not set breakpoint: %s", strerror(-ret));
return ret;
}
return 0;
}
-static int remove_break_f(BlockBackend *blk, int argc, char **argv)
+static int remove_break_f(BlockBackend *blk, int argc, char **argv,
+ Error **errp)
{
int ret;
ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
if (ret < 0) {
- printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
+ error_setg(errp, "Could not remove breakpoint %s: %s",
+ argv[1], strerror(-ret));
return ret;
}
@@ -2665,13 +2676,13 @@ static const cmdinfo_t remove_break_cmd = {
.oneline = "remove a breakpoint by tag",
};
-static int resume_f(BlockBackend *blk, int argc, char **argv)
+static int resume_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int ret;
ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
if (ret < 0) {
- printf("Could not resume request: %s\n", strerror(-ret));
+ error_setg(errp, "Could not resume request: %s", strerror(-ret));
return ret;
}
@@ -2687,7 +2698,7 @@ static const cmdinfo_t resume_cmd = {
.oneline = "resumes the request tagged as tag",
};
-static int wait_break_f(BlockBackend *blk, int argc, char **argv)
+static int wait_break_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
aio_poll(blk_get_aio_context(blk), true);
@@ -2704,7 +2715,7 @@ static const cmdinfo_t wait_break_cmd = {
.oneline = "waits for the suspension of a request",
};
-static int abort_f(BlockBackend *blk, int argc, char **argv)
+static int abort_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
abort();
}
@@ -2730,7 +2741,7 @@ static void sigraise_help(void)
"\n", SIGTERM);
}
-static int sigraise_f(BlockBackend *blk, int argc, char **argv);
+static int sigraise_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t sigraise_cmd = {
.name = "sigraise",
@@ -2743,15 +2754,16 @@ static const cmdinfo_t sigraise_cmd = {
.help = sigraise_help,
};
-static int sigraise_f(BlockBackend *blk, int argc, char **argv)
+static int sigraise_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int64_t sig = cvtnum(argv[1]);
if (sig < 0) {
- print_cvtnum_err(sig, argv[1]);
+ set_cvtnum_err(sig, argv[1], errp);
return sig;
} else if (sig > NSIG) {
- printf("signal argument '%s' is too large to be a valid signal\n",
- argv[1]);
+ error_setg(errp,
+ "signal argument '%s' is too large to be a valid signal",
+ argv[1]);
return -EINVAL;
}
@@ -2772,7 +2784,7 @@ static void sleep_cb(void *opaque)
*expired = true;
}
-static int sleep_f(BlockBackend *blk, int argc, char **argv)
+static int sleep_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
char *endptr;
long ms;
@@ -2781,7 +2793,7 @@ static int sleep_f(BlockBackend *blk, int argc, char **argv)
ms = strtol(argv[1], &endptr, 0);
if (ms < 0 || *endptr != '\0') {
- printf("%s is not a valid number\n", argv[1]);
+ error_setg(errp, "%s is not a valid number", argv[1]);
return -EINVAL;
}
@@ -2833,7 +2845,7 @@ static void help_all(void)
printf("\nUse 'help commandname' for extended help.\n");
}
-static int help_f(BlockBackend *blk, int argc, char **argv)
+static int help_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
const cmdinfo_t *ct;
@@ -2844,7 +2856,7 @@ static int help_f(BlockBackend *blk, int argc, char **argv)
ct = find_command(argv[1]);
if (ct == NULL) {
- printf("command %s not found\n", argv[1]);
+ error_setg(errp, "command %s not found", argv[1]);
return -EINVAL;
}
@@ -2867,7 +2879,7 @@ static const cmdinfo_t help_cmd = {
* Called with aio context of blk acquired. Or with qemu_get_aio_context()
* context acquired if blk is NULL.
*/
-int qemuio_command(BlockBackend *blk, const char *cmd)
+int qemuio_command(BlockBackend *blk, const char *cmd, Error **errp)
{
char *input;
const cmdinfo_t *ct;
@@ -2880,9 +2892,9 @@ int qemuio_command(BlockBackend *blk, const char *cmd)
if (c) {
ct = find_command(v[0]);
if (ct) {
- ret = command(blk, ct, c, v);
+ ret = command(blk, ct, c, v, errp);
} else {
- fprintf(stderr, "command \"%s\" not found\n", v[0]);
+ error_setg(errp, "command \"%s\" not found", v[0]);
ret = -EINVAL;
}
}
diff --git a/qemu-io.c b/qemu-io.c
index 8f2de83f3c8..598d5b1c9ca 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -68,7 +68,7 @@ static int get_eof_char(void)
#endif
}
-static int close_f(BlockBackend *blk, int argc, char **argv)
+static int close_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
blk_unref(qemuio_blk);
qemuio_blk = NULL;
@@ -140,7 +140,7 @@ static void open_help(void)
"\n");
}
-static int open_f(BlockBackend *blk, int argc, char **argv);
+static int open_f(BlockBackend *blk, int argc, char **argv, Error **errp);
static const cmdinfo_t open_cmd = {
.name = "open",
@@ -164,7 +164,7 @@ static QemuOptsList empty_opts = {
},
};
-static int open_f(BlockBackend *blk, int argc, char **argv)
+static int open_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
int flags = BDRV_O_UNMAP;
int readonly = 0;
@@ -268,7 +268,7 @@ static int open_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
-static int quit_f(BlockBackend *blk, int argc, char **argv)
+static int quit_f(BlockBackend *blk, int argc, char **argv, Error **errp)
{
quit_qemu_io = true;
return 0;
@@ -414,7 +414,14 @@ static void prep_fetchline(void *opaque)
static int do_qemuio_command(const char *cmd)
{
- return qemuio_command(qemuio_blk, cmd);
+ Error *local_err = NULL;
+ int ret;
+
+ ret = qemuio_command(qemuio_blk, cmd, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ }
+ return ret;
}
static int command_loop(void)
diff --git a/tests/qemu-iotests/004.out b/tests/qemu-iotests/004.out
index fb8593289f5..37da6024809 100644
--- a/tests/qemu-iotests/004.out
+++ b/tests/qemu-iotests/004.out
@@ -6,36 +6,36 @@ wrote 1048576/1048576 bytes at offset 133169152
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write into image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write past image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
pwrite past image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
writev past image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
read before image boundary
read 1048576/1048576 bytes at offset 133169152
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read into image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read past image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
pread past image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
readv past image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
*** done
diff --git a/tests/qemu-iotests/021.out b/tests/qemu-iotests/021.out
index 8533f8e58ae..dfdfeb50378 100644
--- a/tests/qemu-iotests/021.out
+++ b/tests/qemu-iotests/021.out
@@ -2,92 +2,92 @@ QA output created by 021
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
== testing writev -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing read -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing write -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing readv -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing aio_read -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing aio_write -P -1 ==
--1 is not a valid pattern byte
+qemu-io: -1 is not a valid pattern byte
== testing writev -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing read -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing write -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing readv -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing aio_read -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing aio_write -P 300 ==
-300 is not a valid pattern byte
+qemu-io: 300 is not a valid pattern byte
== testing writev -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing read -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing write -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing readv -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing aio_read -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing aio_write -P 12m ==
-12m is not a valid pattern byte
+qemu-io: 12m is not a valid pattern byte
== testing writev -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing read -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing write -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing readv -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing aio_read -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing aio_write -P 4k ==
-4k is not a valid pattern byte
+qemu-io: 4k is not a valid pattern byte
== testing writev -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
== testing read -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
== testing write -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
== testing readv -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
== testing aio_read -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
== testing aio_write -P route66 ==
-route66 is not a valid pattern byte
+qemu-io: route66 is not a valid pattern byte
*** done
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index 83989996ff6..b998a9ac83d 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -4,442 +4,442 @@ Errors while writing 128 kB
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: on; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: on; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
-read failed: Input/output error
+qemu-io: write failed: Input/output error
+qemu-io: read failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: on; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: on; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: No space left on device
-read failed: No space left on device
+qemu-io: write failed: No space left on device
+qemu-io: read failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc_write; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: on; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: on; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: off; write
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: off; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
=== Refcount table growth tests ===
@@ -447,122 +447,122 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_hookup; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_hookup; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_hookup; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_blocks; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_write_table; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: on; write -b
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc_switch_table; errno: 28; imm: off; once: off; write -b
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
=== L1 growth tests ===
@@ -570,76 +570,76 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_alloc_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_alloc_table; errno: 5; imm: off; once: off
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_alloc_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_alloc_table; errno: 28; imm: off; once: off
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 5; imm: off; once: off
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_write_table; errno: 28; imm: off; once: off
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_activate_table; errno: 5; imm: off; once: on
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_activate_table; errno: 5; imm: off; once: off
+qemu-io: write failed: Input/output error
qemu-io: Failed to flush the L2 table cache: Input/output error
qemu-io: Failed to flush the refcount block cache: Input/output error
-write failed: Input/output error
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_activate_table; errno: 28; imm: off; once: on
-write failed: No space left on device
+qemu-io: write failed: No space left on device
No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow_activate_table; errno: 28; imm: off; once: off
+qemu-io: write failed: No space left on device
qemu-io: Failed to flush the L2 table cache: No space left on device
qemu-io: Failed to flush the refcount block cache: No space left on device
-write failed: No space left on device
No errors were found on the image.
=== Avoid cluster leaks after temporary failure ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
-write failed: Input/output error
+qemu-io: write failed: Input/output error
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
@@ -651,6 +651,6 @@ wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
index a37bf446e94..27275fd6b70 100644
--- a/tests/qemu-iotests/060.out
+++ b/tests/qemu-iotests/060.out
@@ -9,7 +9,7 @@ ERROR cluster 3 refcount=1 reference=3
Data may be corrupted, or further writes to the image may corrupt it.
incompatible_features []
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
incompatible_features [1]
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
@@ -23,7 +23,7 @@ Format specific information:
corrupt: true
extended l2: false
qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -37,7 +37,7 @@ ERROR cluster 2 refcount=1 reference=2
Data may be corrupted, or further writes to the image may corrupt it.
incompatible_features []
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount block); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
incompatible_features [1]
ERROR refcount block 0 refcount=2
ERROR cluster 2 refcount=1 reference=2
@@ -73,7 +73,7 @@ Data may be corrupted, or further writes to the image may corrupt it.
This means waste of disk space, but no harm to data.
incompatible_features []
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with inactive L2 table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
incompatible_features [1]
ERROR cluster 4 refcount=1 reference=2
Leaked cluster 9 refcount=1 reference=0
@@ -108,10 +108,10 @@ wrote 65536/65536 bytes at offset 0
wrote 65536/65536 bytes at offset 536870912
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L2 table); further corruption events will be suppressed
+qemu-io: write failed: Input/output error
+qemu-io: aio_write failed: No medium found
blkdebug: Suspended request '0'
-write failed: Input/output error
blkdebug: Resuming request '0'
-aio_write failed: No medium found
=== Testing unallocated image header ===
@@ -119,7 +119,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with qcow2_header); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
=== Testing unaligned L1 entry ===
@@ -127,7 +127,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: L2 table offset 0x42a00 unaligned (L1 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -140,7 +140,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Testing unaligned pre-allocated zero cluster ===
@@ -154,7 +154,7 @@ qemu-img: Failed to turn zero into data clusters: Input/output error
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qcow2: Marking image as corrupt: Refblock offset 0x22a00 unaligned (reftable index: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
=== Testing non-fatal corruption on freeing ===
@@ -171,8 +171,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Image is corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further non-fatal corruption events will be suppressed
-read failed: Input/output error
-read failed: Input/output error
+qemu-io: read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Testing non-fatal and then fatal corruption report ===
@@ -181,15 +181,15 @@ wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Image is corrupt: Cannot free unaligned cluster 0x52a00; further non-fatal corruption events will be suppressed
qcow2: Marking image as corrupt: Cluster allocation offset 0x62a00 unaligned (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
+qemu-io: read failed: Input/output error
discard 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
=== Testing empty refcount table ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with refcount table); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
ERROR cluster 0 refcount=0 reference=1
ERROR cluster 1 refcount=0 reference=1
ERROR cluster 3 refcount=0 reference=1
@@ -209,7 +209,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid allocation of refcount block at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
ERROR cluster 0 refcount=0 reference=1
ERROR cluster 1 refcount=0 reference=1
ERROR cluster 3 refcount=0 reference=1
@@ -229,7 +229,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
ERROR cluster 0 refcount=0 reference=1
ERROR cluster 1 refcount=0 reference=1
ERROR cluster 2 refcount=0 reference=1
@@ -251,7 +251,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 65536
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preventing invalid allocation of compressed cluster at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
ERROR cluster 0 refcount=0 reference=1
ERROR cluster 1 refcount=0 reference=1
ERROR cluster 2 refcount=0 reference=1
@@ -286,7 +286,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
=== Testing dirty corrupt image ===
@@ -319,7 +319,7 @@ wrote 65536/65536 bytes at offset 0
discard 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
--- Repairing ---
Repairing offset=2a00: Preallocated cluster is not properly aligned; L2 entry corrupted.
The following inconsistencies were found and repaired:
@@ -337,7 +337,7 @@ wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftable index: 0); further corruption events will be suppressed
qcow2_free_clusters failed: Input/output error
-discard failed: No medium found
+qemu-io: discard failed: No medium found
--- Repairing ---
ERROR refcount block 0 is not cluster aligned; refcount table entry corrupted
qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftable index: 0); further corruption events will be suppressed
@@ -419,8 +419,7 @@ qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps
QMP_VERSION
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "none0", "msg": "Preventing invalid write on metadata (overlaps with refcount table)", "offset": 65536, "node-name": "drive", "fatal": true, "size": 65536}}
-write failed: Input/output error
-{"return": ""}
+{"return": "Error: write failed: Input/output error\r\n"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
{"return": {}}
@@ -431,7 +430,6 @@ QMP_VERSION
{"return": {}}
qcow2: Image is corrupt: L2 table offset 0x2a2a2a00 unaligned (L1 index: 0); further non-fatal corruption events will be suppressed
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_IMAGE_CORRUPTED", "data": {"device": "", "msg": "L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)", "node-name": "drive", "fatal": false}}
-{"return": ""}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
{"return": {}}
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index a2923b05c29..f2d015d8cca 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -30,11 +30,11 @@ blkverify: read offset=0 bytes=512 contents mismatch at offset 0
=== Testing blkdebug through filename ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Testing blkdebug through file blockref ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Testing blkdebug on existing block device ===
@@ -43,8 +43,7 @@ QMP_VERSION
{"return": {}}
{"return": {}}
{"return": {}}
-read failed: Input/output error
-{"return": ""}
+{"return": "Error: read failed: Input/output error\r\n"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
{"return": {}}
@@ -82,8 +81,7 @@ read 512/512 bytes at offset 0
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": ""}
-read failed: Input/output error
-{"return": ""}
+{"return": "Error: read failed: Input/output error\r\n"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
QEMU_PROG: Failed to flush the L2 table cache: Input/output error
QEMU_PROG: Failed to flush the refcount block cache: Input/output error
diff --git a/tests/qemu-iotests/072.out b/tests/qemu-iotests/072.out
index fe949d47817..d7ce24da1f7 100644
--- a/tests/qemu-iotests/072.out
+++ b/tests/qemu-iotests/072.out
@@ -15,7 +15,7 @@ read 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 512/512 bytes at offset 1024
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Pattern verification failed at offset 0, 512 bytes
+qemu-io: Pattern verification failed at offset 0, 512 bytes
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
index d8acb3e7235..b20c21faf6a 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -66,8 +66,8 @@ wrote 512/512 bytes at offset 0
qemu-img: Failed to load snapshot: Snapshot L1 table offset invalid
qemu-img: Snapshot L1 table offset invalid
qemu-img: Failed to turn zero into data clusters: Invalid argument
+qemu-io: write failed: Invalid argument
qemu-io: Failed to flush the refcount block cache: Invalid argument
-write failed: Invalid argument
qemu-img: Snapshot L1 table offset invalid
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invalid argument
qemu-img: Could not delete snapshot 'test': Snapshot L1 table offset invalid
@@ -89,8 +89,8 @@ wrote 512/512 bytes at offset 0
qemu-img: Failed to load snapshot: Snapshot L1 table too large
qemu-img: Snapshot L1 table too large
qemu-img: Failed to turn zero into data clusters: File too large
+qemu-io: write failed: File too large
qemu-io: Failed to flush the refcount block cache: File too large
-write failed: File too large
qemu-img: Snapshot L1 table too large
qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File too large
qemu-img: Could not delete snapshot 'test': Snapshot L1 table too large
diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out
index aba85ea5644..bc902bd8183 100644
--- a/tests/qemu-iotests/081.out
+++ b/tests/qemu-iotests/081.out
@@ -81,7 +81,7 @@ wrote 10485760/10485760 bytes at offset 0
10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== checking that quorum is broken ==
-read failed: Input/output error
+qemu-io: read failed: Input/output error
== checking the blkverify mode with broken content ==
quorum: offset=0 bytes=10485760 contents mismatch at offset 0
diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
index 2090ee693c1..a1c446d5365 100644
--- a/tests/qemu-iotests/083.out
+++ b/tests/qemu-iotests/083.out
@@ -41,7 +41,7 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/foo
=== Check disconnect after neg2 ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 8 neg2 ===
@@ -53,31 +53,31 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/foo
=== Check disconnect before request ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after request ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect before reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 4 reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 8 reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect before data ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after data ===
@@ -106,7 +106,7 @@ qemu-io: can't open device nbd+tcp://127.0.0.1:PORT/
=== Check disconnect after neg-classic ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect before neg1 ===
@@ -150,7 +150,7 @@ qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect after neg2 ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 8 neg2 ===
@@ -162,31 +162,31 @@ qemu-io: can't open device nbd+unix:///foo?socket=SOCK_DIR/nbd.sock
=== Check disconnect before request ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after request ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect before reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 4 reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect 8 reply ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect before data ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Check disconnect after data ===
@@ -215,6 +215,6 @@ qemu-io: can't open device nbd+unix:///?socket=SOCK_DIR/nbd.sock
=== Check disconnect after neg-classic ===
-read failed: Input/output error
+qemu-io: read failed: Input/output error
*** done
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
index c53fc4823a1..a29e19b12d7 100644
--- a/tests/qemu-iotests/089.out
+++ b/tests/qemu-iotests/089.out
@@ -16,7 +16,7 @@ read 512/512 bytes at offset 512
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 512/512 bytes at offset 1024
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-Pattern verification failed at offset 0, 512 bytes
+qemu-io: Pattern verification failed at offset 0, 512 bytes
read 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -33,7 +33,7 @@ read 512/512 bytes at offset 0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
=== Testing qemu-img info output ===
diff --git a/tests/qemu-iotests/114.out b/tests/qemu-iotests/114.out
index f51dd9d20a1..80220e440ec 100644
--- a/tests/qemu-iotests/114.out
+++ b/tests/qemu-iotests/114.out
@@ -11,7 +11,7 @@ cluster_size: 65536
backing file: TEST_DIR/t.IMGFMT.base
backing file format: foo
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-img: Could not change the backing file to 'TEST_DIR/t.qcow2.base': backing format must be specified
diff --git a/tests/qemu-iotests/134.out b/tests/qemu-iotests/134.out
index 4abc5b5f7da..ce2a0df166e 100644
--- a/tests/qemu-iotests/134.out
+++ b/tests/qemu-iotests/134.out
@@ -24,7 +24,7 @@ read 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== verify pattern failure with wrong password ==
-Pattern verification failed at offset 0, 134217728 bytes
+qemu-io: Pattern verification failed at offset 0, 134217728 bytes
read 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
index e19df5b6ba8..1947c1a1bd7 100644
--- a/tests/qemu-iotests/137.out
+++ b/tests/qemu-iotests/137.out
@@ -40,5 +40,5 @@ OK: Dirty bit not set
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table at offset 0; further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
*** done
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
index 28e1a22952b..e235d9e59e3 100644
--- a/tests/qemu-iotests/153.out
+++ b/tests/qemu-iotests/153.out
@@ -33,12 +33,12 @@ Is another process using the image [TEST_DIR/t.qcow2]?
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get shared "write" lock
Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_img_wrapper info TEST_DIR/t.qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get shared "write" lock
@@ -107,7 +107,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
@@ -176,7 +176,7 @@ _qemu_io_wrapper -r -c read 0 512 TEST_DIR/t.qcow2
_qemu_io_wrapper -c open TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: Failed to get "write" lock
Is another process using the image [TEST_DIR/t.qcow2]?
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_io_wrapper -c open -r TEST_DIR/t.qcow2 -c read 0 512
@@ -231,7 +231,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
@@ -336,7 +336,7 @@ _qemu_io_wrapper -U -r -c read 0 512 TEST_DIR/t.qcow2
_qemu_io_wrapper -c open -U TEST_DIR/t.qcow2 -c read 0 512
qemu-io: can't open device TEST_DIR/t.qcow2: force-share=on can only be used with read-only images
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
_qemu_io_wrapper -c open -r -U TEST_DIR/t.qcow2 -c read 0 512
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
index d1d77f70130..87a8aa24d96 100755
--- a/tests/qemu-iotests/171
+++ b/tests/qemu-iotests/171
@@ -188,7 +188,7 @@ img_offset=512
img_size=512
_make_test_img $size
(
-$QEMU_IO "$(img_json)" <<EOT
+$QEMU_IO "$(img_json)" 2>&1 <<EOT
write -P 0x0a 0 512
write -P 0x0a 511 1
write -P 0x0a 512 1
diff --git a/tests/qemu-iotests/171.out b/tests/qemu-iotests/171.out
index ec3363b4f44..67ef9b88415 100644
--- a/tests/qemu-iotests/171.out
+++ b/tests/qemu-iotests/171.out
@@ -21,32 +21,32 @@ wrote 1/1 bytes at offset 3583
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
read before image boundary
read 1/1 bytes at offset 3583
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
fill image with pattern
wrote 4096/4096 bytes at offset 0
@@ -60,7 +60,7 @@ read 4/4 bytes at offset 510
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write zeroes at image boundary and check
wrote 2/2 bytes at offset 3582
@@ -68,7 +68,7 @@ wrote 2/2 bytes at offset 3582
00000ffe: 00 00 ..
read 2/2 bytes at offset 4094
2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
fill image with pattern
wrote 4096/4096 bytes at offset 0
@@ -82,7 +82,7 @@ read 4/4 bytes at offset 510
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
discard at image boundary and check
discard 2/2 bytes at offset 3582
@@ -90,7 +90,7 @@ discard 2/2 bytes at offset 3582
00000ffe: 00 00 ..
read 2/2 bytes at offset 4094
2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
== test 'offset' and 'size' options ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
@@ -113,32 +113,32 @@ wrote 1/1 bytes at offset 2047
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
read before image boundary
read 1/1 bytes at offset 2047
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
fill image with pattern
wrote 4096/4096 bytes at offset 0
@@ -152,7 +152,7 @@ read 4/4 bytes at offset 510
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write zeroes at image boundary and check
wrote 2/2 bytes at offset 2046
@@ -176,7 +176,7 @@ read 4/4 bytes at offset 510
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
discard at image boundary and check
discard 2/2 bytes at offset 2046
@@ -209,32 +209,32 @@ wrote 1/1 bytes at offset 2047
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write at image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write after image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
writev before/after image boundary
-writev failed: Input/output error
+qemu-io: writev failed: Input/output error
read before image boundary
read 1/1 bytes at offset 2047
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read across image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read at image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
read after image boundary
-read failed: Input/output error
+qemu-io: read failed: Input/output error
readv before/after image boundary
-readv failed: Input/output error
+qemu-io: readv failed: Input/output error
fill image with pattern
wrote 4096/4096 bytes at offset 0
@@ -248,7 +248,7 @@ read 4/4 bytes at offset 8
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write zeroes across image boundary
-write failed: Input/output error
+qemu-io: write failed: Input/output error
write zeroes at image boundary and check
wrote 2/2 bytes at offset 2046
@@ -272,7 +272,7 @@ read 4/4 bytes at offset 8
4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
discard across image boundary
-discard failed: Input/output error
+qemu-io: discard failed: Input/output error
discard at image boundary and check
discard 2/2 bytes at offset 2046
@@ -290,12 +290,12 @@ wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1/1 bytes at offset 511
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
wrote 1024/1024 bytes at offset 0
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1/1 bytes at offset 1023
1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Input/output error
+qemu-io: write failed: Input/output error
checking boundaries
000001fe: 00 00 0a 0a ....
read 4/4 bytes at offset 510
diff --git a/tests/qemu-iotests/205 b/tests/qemu-iotests/205
index 78459065418..3ed3ed233ac 100755
--- a/tests/qemu-iotests/205
+++ b/tests/qemu-iotests/205
@@ -75,7 +75,7 @@ class TestNbdServerRemove(iotests.QMPTestCase):
def assertReadFailed(self, qemu_io_output):
self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
- 'read failed: Input/output error')
+ 'qemu-io: read failed: Input/output error')
def assertConnectFailed(self, qemu_io_output):
self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
diff --git a/tests/qemu-iotests/214.out b/tests/qemu-iotests/214.out
index 9fc67287f8e..26056938ee9 100644
--- a/tests/qemu-iotests/214.out
+++ b/tests/qemu-iotests/214.out
@@ -7,7 +7,7 @@ wrote 2097152/2097152 bytes at offset 0
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 2097152/2097152 bytes at offset 2097152
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Input/output error
+qemu-io: read failed: Input/output error
No errors were found on the image.
read 4194304/4194304 bytes at offset 0
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/220.out b/tests/qemu-iotests/220.out
index 33b994b8a14..6f200ec8947 100644
--- a/tests/qemu-iotests/220.out
+++ b/tests/qemu-iotests/220.out
@@ -38,7 +38,7 @@ wrote 2097152/2097152 bytes at offset 37748736
No errors were found on the image.
image size 39845888
== Trying to write compressed cluster ==
-write failed: File too large
+qemu-io: write failed: File too large
image size 562949957615616
== Writing normal cluster ==
wrote 2097152/2097152 bytes at offset 0
diff --git a/tests/qemu-iotests/225.out b/tests/qemu-iotests/225.out
index 0998ae094c2..beb8c23bd33 100644
--- a/tests/qemu-iotests/225.out
+++ b/tests/qemu-iotests/225.out
@@ -14,11 +14,11 @@ read 512/512 bytes at offset 0
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qemu-io overlay "read 0 512"
-read failed: Invalid argument
+Error: read failed: Invalid argument
=== Testing non-VMDK backing image ===
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qemu-io overlay "read 0 512"
-read failed: Invalid argument
+Error: read failed: Invalid argument
*** done
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
index c62f5aec25b..c5e62146c93 100644
--- a/tests/qemu-iotests/244.out
+++ b/tests/qemu-iotests/244.out
@@ -10,22 +10,22 @@ read 65536/65536 bytes at offset 0
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
Data file required, but without data file name in the image:
qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' is required for this image
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
Setting data-file for an image with internal data:
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open device TEST_DIR/t.qcow2: 'data-file' can only be set for images with an external data file
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open 'inexistent': No such file or directory
-no file open, try 'help open'
+qemu-io: no file open, try 'help open'
=== Conflicting features ===
@@ -37,7 +37,7 @@ qemu-img: error while writing at byte 0: Operation not supported
Convert uncompressed, then write compressed data manually:
Images are identical.
-write failed: Operation not supported
+qemu-io: write failed: Operation not supported
No errors were found on the image.
Take an internal snapshot:
diff --git a/tests/qemu-iotests/249.out b/tests/qemu-iotests/249.out
index d2bf9be85ea..3d37709a9ef 100644
--- a/tests/qemu-iotests/249.out
+++ b/tests/qemu-iotests/249.out
@@ -9,7 +9,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
{ 'execute': 'human-monitor-command',
'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
=== Run block-commit on base using an invalid filter node name
@@ -24,7 +24,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
{ 'execute': 'human-monitor-command',
'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
=== Run block-commit on base using the default filter node name
@@ -43,5 +43,5 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=TEST_DIR/t.
{ 'execute': 'human-monitor-command',
'arguments': {'command-line': 'qemu-io none0 "aio_write 0 2k"'}}
-{"return": "Block node is read-onlyrn"}
+{"return": "Error: Block node is read-onlyrn"}
*** done
diff --git a/tests/qemu-iotests/271.out b/tests/qemu-iotests/271.out
index 0b24d501595..da92d4b5b1a 100644
--- a/tests/qemu-iotests/271.out
+++ b/tests/qemu-iotests/271.out
@@ -456,7 +456,7 @@ L2 entry #0: 0x8000000000050001 0000000000000001
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #1: 0x8000000000060000 00000001ffffffff
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
### Corrupted L2 entries - read test (unallocated) ###
@@ -471,14 +471,14 @@ L2 entry #0: 0x0000000000000001 0000000000000000
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #0: 0x0000000000000000 0000000000000001
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #1: 0x0000000000000000 0000000100000001
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
### Compressed cluster with subcluster bitmap != 0 - read test ###
@@ -501,7 +501,7 @@ L2 entry #0: 0x8000000000050001 0000000000000001
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #1: 0x8000000000060000 00000001ffffffff
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
### Corrupted L2 entries - write test (unallocated) ###
@@ -516,14 +516,14 @@ L2 entry #0: 0x8000000000060000 0000000000000001
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #0: 0x0000000000000000 0000000000000001
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
# Both 'subcluster is zero' and 'subcluster is allocated' bits set
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
L2 entry #1: 0x0000000000000000 0000000100000001
qcow2: Marking image as corrupt: Invalid cluster entry found (L2 offset: 0x40000, L2 index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
### Compressed cluster with subcluster bitmap != 0 - write test ###
@@ -555,7 +555,7 @@ Double checking the fixed image now...
1 errors were found on the image.
Data may be corrupted, or further writes to the image may corrupt it.
qcow2: Marking image as corrupt: Cluster allocation offset 0x50200 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
-read failed: Input/output error
+qemu-io: read failed: Input/output error
# Corrupted L2 entry, no allocated subclusters #
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=raw
Repairing offset=50200: Preallocated cluster is not properly aligned; L2 entry corrupted.
diff --git a/tests/qemu-iotests/289.out b/tests/qemu-iotests/289.out
index e54e2629d4d..58e4f4942f0 100644
--- a/tests/qemu-iotests/289.out
+++ b/tests/qemu-iotests/289.out
@@ -3,6 +3,6 @@ QA output created by 289
=== Avoid freeing external data clusters on failure ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536 data_file=TEST_DIR/t.IMGFMT.data_file
-write failed: Input/output error
+qemu-io: write failed: Input/output error
No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/305.out b/tests/qemu-iotests/305.out
index 538019e7260..af09d6a3ff4 100644
--- a/tests/qemu-iotests/305.out
+++ b/tests/qemu-iotests/305.out
@@ -12,5 +12,5 @@ discard 1024/1024 bytes at offset 125952
### Corrupt the offset of the second refcount block
### Try to allocate the discarded clusters again
qcow2: Marking image as corrupt: Refblock offset 0x20600 unaligned (reftable index: 0x1); further corruption events will be suppressed
-write failed: Input/output error
+qemu-io: write failed: Input/output error
*** done
diff --git a/tests/qemu-iotests/307.out b/tests/qemu-iotests/307.out
index a9b37d3ac11..608b407a6fc 100644
--- a/tests/qemu-iotests/307.out
+++ b/tests/qemu-iotests/307.out
@@ -127,7 +127,7 @@ exports available: 1
{"error": {"class": "GenericError", "desc": "export 'export1' still in use"}}
{"execute": "block-export-del", "arguments": {"id": "export1", "mode": "hard"}}
{"return": {}}
-read failed: Input/output error
+qemu-io: read failed: Input/output error
{"execute": "query-block-exports", "arguments": {}}
{"return": []}
diff --git a/tests/qemu-iotests/tests/backup-discard-source b/tests/qemu-iotests/tests/backup-discard-source
index 17fef9c6d34..6c624bc8b0b 100755
--- a/tests/qemu-iotests/tests/backup-discard-source
+++ b/tests/qemu-iotests/tests/backup-discard-source
@@ -87,11 +87,11 @@ class TestBackup(iotests.QMPTestCase):
def tearDown(self):
# That should fail, because region is discarded
- self.vm.hmp_qemu_io('access', 'read 0 1M')
+ result = self.vm.hmp_qemu_io('access', 'read 0 1M')
self.vm.shutdown()
- self.assertTrue('read failed: Permission denied' in self.vm.get_log())
+ self.assertIn('read failed: Permission denied', result['return'])
# Final check that temp image is empty
mapping = qemu_img_map(temp_img)
diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write
index 236cb8ac374..3e43e7127f2 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -87,17 +87,17 @@ class TestCbwError(iotests.QMPTestCase):
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 0 1M"')
- self.assert_qmp(result, 'return', '')
+ write_res = result['return']
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io access "read 0 1M"')
- self.assert_qmp(result, 'return', '')
+ read_res = result['return']
self.vm.shutdown()
log = self.vm.get_log()
log = iotests.filter_qtest(log)
log = iotests.filter_qemu_io(log)
- return log
+ return log, write_res, read_res
def do_cbw_error_via_blockdev_backup(self, on_cbw_error=None):
self.vm.cmd('blockdev-add', {
@@ -150,28 +150,29 @@ class TestCbwError(iotests.QMPTestCase):
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 0 1M"')
- self.assert_qmp(result, 'return', '')
+ write_res = result['return']
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io access "read 0 1M"')
- self.assert_qmp(result, 'return', '')
+ read_res = result['return']
self.vm.shutdown()
log = self.vm.get_log()
log = iotests.filter_qemu_io(log)
- return log
+ return log, write_res, read_res
def test_break_snapshot_on_cbw_error(self):
"""break-snapshot behavior:
Guest write succeed, but further snapshot-read fails, as snapshot is
broken.
"""
- log = self.do_cbw_error('break-snapshot')
+ log, write_res, read_res = self.do_cbw_error('break-snapshot')
+ self.assertEqual(write_res, '')
+ self.assertIn('read failed: Permission denied', read_res)
self.assertEqual(log, """\
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
""")
def test_break_guest_write_on_cbw_error(self):
@@ -179,10 +180,11 @@ read failed: Permission denied
Guest write fails, but snapshot-access continues working and further
snapshot-read succeeds.
"""
- log = self.do_cbw_error('break-guest-write')
+ log, write_res, read_res = self.do_cbw_error('break-guest-write')
+ self.assertIn('write failed: Input/output error', write_res)
+ self.assertEqual(read_res, '')
self.assertEqual(log, """\
-write failed: Input/output error
read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
""")
@@ -191,20 +193,24 @@ read 1048576/1048576 bytes at offset 0
"""Ensure CBW filter accepts break-snapshot policy
specified in blockdev-backup QMP command.
"""
- log = self.do_cbw_error_via_blockdev_backup('break-snapshot')
+ log, write_res, read_res = \
+ self.do_cbw_error_via_blockdev_backup('break-snapshot')
+ self.assertEqual(write_res, '')
+ self.assertIn('read failed: Permission denied', read_res)
self.assertEqual(log, """\
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
""")
def test_break_guest_write_policy_forwarding(self):
"""Ensure CBW filter accepts break-guest-write policy
specified in blockdev-backup QMP command.
"""
- log = self.do_cbw_error_via_blockdev_backup('break-guest-write')
+ log, write_res, read_res = \
+ self.do_cbw_error_via_blockdev_backup('break-guest-write')
+ self.assertIn('write failed: Input/output error', write_res)
+ self.assertEqual(read_res, '')
self.assertEqual(log, """\
-write failed: Input/output error
read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
""")
@@ -213,9 +219,11 @@ read 1048576/1048576 bytes at offset 0
"""Ensure break-guest-write policy is used by default when
on-cbw-error is not explicitly specified.
"""
- log = self.do_cbw_error_via_blockdev_backup()
+ log, write_res, read_res = \
+ self.do_cbw_error_via_blockdev_backup()
+ self.assertIn('write failed: Input/output error', write_res)
+ self.assertEqual(read_res, '')
self.assertEqual(log, """\
-write failed: Input/output error
read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
""")
@@ -260,47 +268,53 @@ read 1048576/1048576 bytes at offset 0
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 0 512K"')
- self.assert_qmp(result, 'return', '')
+ write1_res = result['return']
# We need second write to trigger throttling
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 512K 512K"')
- self.assert_qmp(result, 'return', '')
+ write2_res = result['return']
result = self.vm.qmp('human-monitor-command',
command_line='qemu-io access "read 0 1M"')
- self.assert_qmp(result, 'return', '')
+ read_res = result['return']
self.vm.shutdown()
log = self.vm.get_log()
log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
log = iotests.filter_qemu_io(log)
- return log
+ return log, write1_res, write2_res, read_res
def test_timeout_break_guest(self):
- log = self.do_cbw_timeout('break-guest-write')
+ log, write1_res, write2_res, read_res = \
+ self.do_cbw_timeout('break-guest-write')
+ self.assertEqual(write1_res, '')
# macOS and FreeBSD tend to represent ETIMEDOUT as
# "Operation timed out", when Linux prefer
# "Connection timed out"
- log = log.replace('Operation timed out',
- 'Connection timed out')
+ write2_res = write2_res.replace('Operation timed out',
+ 'Connection timed out')
+ self.assertIn('write failed: Connection timed out', write2_res)
+ self.assertEqual(read_res, '')
self.assertEqual(log, """\
wrote 524288/524288 bytes at offset 0
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Connection timed out
read 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
""")
def test_timeout_break_snapshot(self):
- log = self.do_cbw_timeout('break-snapshot')
+ log, write1_res, write2_res, read_res = \
+ self.do_cbw_timeout('break-snapshot')
+ self.assertEqual(write1_res, '')
+ self.assertEqual(write2_res, '')
+ self.assertIn('read failed: Permission denied', read_res)
self.assertEqual(log, """\
wrote 524288/524288 bytes at offset 0
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 524288/524288 bytes at offset 524288
512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-read failed: Permission denied
""")
diff --git a/tests/qemu-iotests/tests/file-io-error.out b/tests/qemu-iotests/tests/file-io-error.out
index 0f46455a94a..bf8c0018ba5 100644
--- a/tests/qemu-iotests/tests/file-io-error.out
+++ b/tests/qemu-iotests/tests/file-io-error.out
@@ -21,7 +21,7 @@ QA output created by file-io-error
}}
{"return": {}}
-write failed: Input/output error
+qemu-io: write failed: Input/output error
{'execute': 'block-export-del',
'arguments': {'id': 'exp0'}}
diff --git a/tests/qemu-iotests/tests/image-fleecing.out b/tests/qemu-iotests/tests/image-fleecing.out
index acfc89ff0e9..dc788f1e20a 100644
--- a/tests/qemu-iotests/tests/image-fleecing.out
+++ b/tests/qemu-iotests/tests/image-fleecing.out
@@ -238,13 +238,13 @@ read -P0xd5 1M 64k
read -P0xdc 32M 64k
read -P0xcd 0x3ff0000 64k
read -P0 0x00f8000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
read -P0 0x2010000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
read -P0 0x3fe0000 64k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
--- Testing COW ---
@@ -265,13 +265,13 @@ read -P0xd5 1M 64k
read -P0xdc 32M 64k
read -P0xcd 0x3ff0000 64k
read -P0 0x00f8000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
read -P0 0x2010000 32k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
read -P0 0x3fe0000 64k
-read failed: Invalid argument
+qemu-io: read failed: Invalid argument
--- Cleanup ---
diff --git a/tests/qemu-iotests/tests/inactive-node-nbd.out b/tests/qemu-iotests/tests/inactive-node-nbd.out
index a458b4fc055..0fb8c18d874 100644
--- a/tests/qemu-iotests/tests/inactive-node-nbd.out
+++ b/tests/qemu-iotests/tests/inactive-node-nbd.out
@@ -215,13 +215,13 @@ target-fmt active: True
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
-write failed: Operation not permitted
+qemu-io: write failed: Operation not permitted
-discard failed: Operation not permitted
+qemu-io: discard failed: Operation not permitted
qemu-io: Failed to get allocation status: Operation not permitted
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (21 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:22 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
` (16 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add a "qemu-io" command to the qtest protocol so that tests can issue
block layer I/O commands without going through the HMP monitor's
"human-monitor-command" QMP, or use QMP at all.
Unfortunately, many tests will prefer to use QMP as they also monitor
and log other events. It's easier if it is pipelined in the same stream.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/libqtest.h | 11 +++++++++++
system/qtest.c | 14 ++++++++++++++
tests/qtest/libqtest.c | 14 ++++++++++++++
3 files changed, 39 insertions(+)
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index 45217fb8dc0..58491ca53ab 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -424,6 +424,17 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
G_GNUC_PRINTF(2, 0);
+/**
+ * qtest_qemu_io:
+ * @s: #QTestState instance to operate on.
+ * @device: block device node-name or BlockBackend name.
+ * @fmt: qemu-io command to send, formats arguments like sprintf().
+ *
+ * Send a qemu-io command via the qtest protocol.
+ */
+void qtest_qemu_io(QTestState *s, const char *device,
+ const char *fmt, ...) G_GNUC_PRINTF(3, 4);
+
void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
/**
diff --git a/system/qtest.c b/system/qtest.c
index fd37bcbfaab..f7f2636854b 100644
--- a/system/qtest.c
+++ b/system/qtest.c
@@ -33,6 +33,7 @@
#include "qom/object_interfaces.h"
#include "qom/qom-qobject.h"
#include "qobject/qobject.h"
+#include "qapi-commands-block.h"
#define MAX_IRQ 256
@@ -800,6 +801,19 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
}
g_slist_free(list);
qtest_send(chr, "OK\n");
+ } else if (strcmp(words[0], "qemu-io") == 0) {
+ const char *io_dev;
+ g_autofree char *io_cmd = NULL;
+ Error *err = NULL;
+
+ g_assert(words[1] && words[2]);
+ io_dev = words[1];
+ io_cmd = g_strjoinv(" ", &words[2]);
+
+ qmp_x_qemu_io(io_dev, NULL, io_cmd, &err);
+ qtest_sendf(chr, err ? "FAIL %s\n" : "OK\n",
+ err ? error_get_pretty(err) : NULL);
+ error_free(err);
} else if (process_command_cb && process_command_cb(chr, words)) {
/* Command got consumed by the callback handler */
} else {
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 4e22c66b754..eccffd3a0c2 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -1012,6 +1012,20 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
return ret;
}
+void qtest_qemu_io(QTestState *s, const char *device,
+ const char *fmt, ...)
+{
+ va_list ap;
+ g_autofree char *cmd = NULL;
+
+ va_start(ap, fmt);
+ cmd = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ qtest_sendf(s, "qemu-io %s %s\n", device, cmd);
+ qtest_rsp(s);
+}
+
const char *qtest_get_arch(void)
{
/*
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (22 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:22 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 25/39] block: add x-qemu-io QMP command Marc-André Lureau
` (15 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Depend on the previous commit to be accepted.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/ide-test.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
index 721e78170bc..3a00c5ff8eb 100644
--- a/tests/qtest/ide-test.c
+++ b/tests/qtest/ide-test.c
@@ -832,7 +832,7 @@ static void test_flush(void)
make_dirty(qts, 0);
/* Delay the completion of the flush request until we explicitly do it */
- g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"break flush_to_os A\""));
+ qtest_qemu_io(qts, "ide0-hd0", "break flush_to_os A");
/* FLUSH CACHE command on device 0*/
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@@ -844,7 +844,7 @@ static void test_flush(void)
assert_bit_clear(data, DF | ERR | DRQ);
/* Complete the command */
- g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"resume A\""));
+ qtest_qemu_io(qts, "ide0-hd0", "resume A");
/* Check registers */
data = qpci_io_readb(dev, ide_bar, reg_device);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 25/39] block: add x-qemu-io QMP command
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (23 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:26 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
` (14 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add an x-qemu-io QMP command that runs qemu-io commands on block
devices. The command accepts a device name (block backend name,
node-name, or qdev ID) and a qemu-io command string.
Refactor hmp_qemu_io() to be a thin wrapper around the new QMP
command, following the standard HMP-over-QMP pattern used by other
block commands.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/block.json | 34 ++++++++++++++++++
block/monitor/block-hmp-cmds.c | 60 ++------------------------------
block/monitor/qmp-cmds.c | 79 ++++++++++++++++++++++++++++++++++++++++++
block/monitor/meson.build | 1 +
4 files changed, 117 insertions(+), 57 deletions(-)
diff --git a/qapi/block.json b/qapi/block.json
index 46955bbb3e3..0a588714ea9 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -603,3 +603,37 @@
'*boundaries-zap': ['uint64'],
'*boundaries-flush': ['uint64'] },
'allow-preconfig': true }
+
+##
+# @x-qemu-io:
+#
+# Run a qemu-io command on a block device. Take either a block
+# backend name or a qdev ID to identify the device.
+#
+# @device: the block backend name, node-name to run the
+# command on.
+#
+# @qdev: the qdev ID of the block device to run the
+# command on.
+#
+# @command: the qemu-io command string to execute.
+#
+# Features:
+#
+# @unstable: This command is for testing only.
+#
+# Since: 11.1
+#
+# .. qmp-example::
+#
+# -> { "execute": "x-qemu-io",
+# "arguments": { "device": "virtio0",
+# "command": "read 0 512" } }
+# <- { "return": {} }
+##
+{ 'command': 'x-qemu-io',
+ 'data': { '*device': 'str',
+ '*qdev': 'str',
+ 'command': 'str' },
+ 'features': [ 'unstable' ],
+ 'allow-preconfig': true }
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index c7113b8ea5e..254a79ce855 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -56,7 +56,6 @@
#include "block/qapi.h"
#include "block/block_int.h"
#include "block/block-hmp-cmds.h"
-#include "qemu-io.h"
static void hmp_drive_add_node(Monitor *mon, const char *optstr)
{
@@ -551,67 +550,14 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
{
- BlockBackend *blk = NULL;
- BlockDriverState *bs = NULL;
- BlockBackend *local_blk = NULL;
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
const char *device = qdict_get_str(qdict, "device");
const char *command = qdict_get_str(qdict, "command");
Error *err = NULL;
- int ret;
-
- if (qdev) {
- blk = blk_by_qdev_id(device, &err);
- if (!blk) {
- goto fail;
- }
- } else {
- blk = blk_by_name(device);
- if (!blk) {
- bs = bdrv_lookup_bs(NULL, device, &err);
- if (!bs) {
- goto fail;
- }
- }
- }
-
- if (bs) {
- blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
- ret = blk_insert_bs(blk, bs, &err);
- if (ret < 0) {
- goto fail;
- }
- }
-
- /*
- * Notably absent: Proper permission management. This is sad, but it seems
- * almost impossible to achieve without changing the semantics and thereby
- * limiting the use cases of the qemu-io HMP command.
- *
- * In an ideal world we would unconditionally create a new BlockBackend for
- * qemuio_command(), but we have commands like 'reopen' and want them to
- * take effect on the exact BlockBackend whose name the user passed instead
- * of just on a temporary copy of it.
- *
- * Another problem is that deleting the temporary BlockBackend involves
- * draining all requests on it first, but some qemu-iotests cases want to
- * issue multiple aio_read/write requests and expect them to complete in
- * the background while the monitor has already returned.
- *
- * This is also what prevents us from saving the original permissions and
- * restoring them later: We can't revoke permissions until all requests
- * have completed, and we don't know when that is nor can we really let
- * anything else run before we have revoken them to avoid race conditions.
- *
- * What happens now is that command() in qemu-io-cmds.c can extend the
- * permissions if necessary for the qemu-io command. And they simply stay
- * extended, possibly resulting in a read-only guest device keeping write
- * permissions. Ugly, but it appears to be the lesser evil.
- */
- qemuio_command(blk, command, &err);
-fail:
- blk_unref(local_blk);
+ qmp_x_qemu_io(qdev ? NULL : device,
+ qdev ? device : NULL,
+ command, &err);
hmp_handle_error(mon, err);
}
diff --git a/block/monitor/qmp-cmds.c b/block/monitor/qmp-cmds.c
new file mode 100644
index 00000000000..e5759d824f1
--- /dev/null
+++ b/block/monitor/qmp-cmds.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "qemu/osdep.h"
+
+#include "system/block-backend.h"
+#include "block/block_int.h"
+#include "qapi/qapi-commands-block.h"
+#include "qapi/error.h"
+#include "qemu-io.h"
+
+void qmp_x_qemu_io(const char *device, const char *qdev,
+ const char *command, Error **errp)
+{
+ BlockBackend *blk = NULL;
+ BlockBackend *local_blk = NULL;
+ BlockDriverState *bs = NULL;
+ int ret;
+
+ if (!device && !qdev) {
+ error_setg(errp, "Must specify either device or qdev");
+ return;
+ }
+ if (qdev && device) {
+ error_setg(errp, "Cannot specify both qdev and device");
+ return;
+ }
+
+ if (qdev) {
+ blk = blk_by_qdev_id(qdev, errp);
+ if (!blk) {
+ return;
+ }
+ } else {
+ blk = blk_by_name(device);
+ if (!blk) {
+ bs = bdrv_lookup_bs(NULL, device, errp);
+ if (!bs) {
+ return;
+ }
+ }
+ }
+
+ if (bs) {
+ blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
+ ret = blk_insert_bs(blk, bs, errp);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
+ /*
+ * Notably absent: Proper permission management. This is sad, but it seems
+ * almost impossible to achieve without changing the semantics and thereby
+ * limiting the use cases of the qemu-io command.
+ *
+ * In an ideal world we would unconditionally create a new BlockBackend for
+ * qemuio_command(), but we have commands like 'reopen' and want them to
+ * take effect on the exact BlockBackend whose name the user passed instead
+ * of just on a temporary copy of it.
+ *
+ * Another problem is that deleting the temporary BlockBackend involves
+ * draining all requests on it first, but some qemu-iotests cases want to
+ * issue multiple aio_read/write requests and expect them to complete in
+ * the background while the monitor has already returned.
+ *
+ * This is also what prevents us from saving the original permissions and
+ * restoring them later: We can't revoke permissions until all requests
+ * have completed, and we don't know when that is nor can we really let
+ * anything else run before we have revoken them to avoid race conditions.
+ *
+ * What happens now is that command() in qemu-io-cmds.c can extend the
+ * permissions if necessary for the qemu-io command. And they simply stay
+ * extended, possibly resulting in a read-only guest device keeping write
+ * permissions. Ugly, but it appears to be the lesser evil.
+ */
+ qemuio_command(blk, command, errp);
+
+fail:
+ blk_unref(local_blk);
+}
diff --git a/block/monitor/meson.build b/block/monitor/meson.build
index 1022516e93c..74faced9e17 100644
--- a/block/monitor/meson.build
+++ b/block/monitor/meson.build
@@ -1,2 +1,3 @@
system_ss.add(files('block-hmp-cmds.c'))
block_ss.add(files('bitmap-qmp-cmds.c'))
+system_ss.add(files('qmp-cmds.c'))
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io()
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (24 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 25/39] block: add x-qemu-io QMP command Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:24 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
` (13 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add qmp_qemu_io() method as a QMP counterpart to hmp_qemu_io(),
using the x-qemu-io QMP command instead of human-monitor-command.
The x-qemu-io command takes separate 'device' (or 'qdev') and
'command' arguments, and returns the error string.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
tests/qemu-iotests/iotests.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 072be80e079..c24f1e3767c 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -953,6 +953,20 @@ def hmp_qemu_io(self, drive: str, cmd: str,
d = '-d ' if qdev else ''
return self.hmp(f'qemu-io {d}{drive} "{cmd}"', use_log=use_log)
+ def qmp_qemu_io(self, drive: str, cmd: str,
+ use_log: bool = False, qdev: bool = False) -> str:
+ """Write to a given drive using the x-qemu-io QMP command"""
+ kwargs: Dict[str, Any] = {'command': cmd}
+ if qdev:
+ kwargs['qdev'] = drive
+ else:
+ kwargs['device'] = drive
+ if use_log:
+ res = self.qmp_log('x-qemu-io', **kwargs)
+ else:
+ res = self.qmp('x-qemu-io', **kwargs)
+ return res.get('error', {}).get('desc', '')
+
def flatten_qmp_object(self, obj, output=None, basestr=''):
if output is None:
output = {}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (25 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:26 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 28/39] build-sys: add 'hmp' option Marc-André Lureau
` (12 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Convert pause_drive() and resume_drive() to use x-qemu-io directly
instead of routing through hmp().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qemu-iotests/iotests.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index c24f1e3767c..f36bcf31642 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -941,11 +941,11 @@ def pause_drive(self, drive: str, event: Optional[str] = None) -> None:
self.pause_drive(drive, "read_aio")
self.pause_drive(drive, "write_aio")
return
- self.hmp(f'qemu-io {drive} "break {event} bp_{drive}"')
+ self.qmp_qemu_io(drive, f'break {event} bp_{drive}')
def resume_drive(self, drive: str) -> None:
"""Resume drive r/w operations"""
- self.hmp(f'qemu-io {drive} "remove_break bp_{drive}"')
+ self.qmp_qemu_io(drive, f'remove_break bp_{drive}')
def hmp_qemu_io(self, drive: str, cmd: str,
use_log: bool = False, qdev: bool = False) -> QMPMessage:
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 28/39] build-sys: add 'hmp' option
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (26 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:27 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
` (11 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add an option to enable/disable HMP support, default to true. The
following commits are going to make --disable-hmp gradually working.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
meson.build | 4 ++++
meson_options.txt | 2 ++
scripts/meson-buildoptions.sh | 3 +++
3 files changed, 9 insertions(+)
diff --git a/meson.build b/meson.build
index e026851309e..824ba695801 100644
--- a/meson.build
+++ b/meson.build
@@ -247,6 +247,9 @@ have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_
have_tcg = get_option('tcg').allowed() and (have_system or have_user)
+have_hmp = get_option('hmp') \
+ .disable_auto_if(not have_system) \
+ .allowed()
have_tools = get_option('tools') \
.disable_auto_if(not have_system) \
.allowed()
@@ -2254,6 +2257,7 @@ endif
config_host_data = configuration_data()
config_host_data.set('CONFIG_HAVE_RUST', have_rust)
+config_host_data.set('CONFIG_HMP', have_hmp)
audio_drivers_selected = []
if have_system
audio_drivers_available = {
diff --git a/meson_options.txt b/meson_options.txt
index a07cb47d35e..d8f59cf92ca 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -111,6 +111,8 @@ option('cfi', type: 'boolean', value: false,
description: 'Control-Flow Integrity (CFI)')
option('cfi_debug', type: 'boolean', value: false,
description: 'Verbose errors in case of CFI violation')
+option('hmp', type : 'feature', value : 'auto',
+ description: 'HMP monitor support')
option('multiprocess', type: 'feature', value: 'auto',
description: 'Out of process device emulation support')
option('relocatable', type : 'boolean', value : true,
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c003985047c..5a67e59a167 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -125,6 +125,7 @@ meson_options_help() {
printf "%s\n" ' gtk GTK+ user interface'
printf "%s\n" ' guest-agent Build QEMU Guest Agent'
printf "%s\n" ' guest-agent-msi Build MSI package for the QEMU Guest Agent'
+ printf "%s\n" ' hmp HMP monitor support'
printf "%s\n" ' hv-balloon hv-balloon driver (requires Glib 2.68+ GTree API)'
printf "%s\n" ' hvf HVF acceleration support'
printf "%s\n" ' iconv Font glyph conversion support'
@@ -339,6 +340,8 @@ _meson_option_parse() {
--disable-guest-agent-msi) printf "%s" -Dguest_agent_msi=disabled ;;
--enable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=true ;;
--disable-hexagon-idef-parser) printf "%s" -Dhexagon_idef_parser=false ;;
+ --enable-hmp) printf "%s" -Dhmp=enabled ;;
+ --disable-hmp) printf "%s" -Dhmp=disabled ;;
--enable-hv-balloon) printf "%s" -Dhv_balloon=enabled ;;
--disable-hv-balloon) printf "%s" -Dhv_balloon=disabled ;;
--enable-hvf) printf "%s" -Dhvf=enabled ;;
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (27 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 28/39] build-sys: add 'hmp' option Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:28 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 30/39] tests: skip HMP-dependent tests " Marc-André Lureau
` (10 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
When QEMU is built without HMP support, reject '-monitor' (which
requests readline/HMP mode) early in monitor_init_opts() with a
clear error message directing users to '-qmp' instead.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
monitor/monitor.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 2dec0e299af..f443f406b4c 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -764,6 +764,16 @@ int monitor_init_opts(QemuOpts *opts, Error **errp)
MonitorOptions *options;
int ret;
+#ifndef CONFIG_HMP
+ const char *mode = qemu_opt_get(opts, "mode");
+ /* readline is HMP.. */
+ if (mode && g_str_equal(mode, "readline")) {
+ error_setg(errp, "HMP monitor is not available,"
+ " use '-qmp' instead of '-monitor'");
+ return -1;
+ }
+#endif
+
v = opts_visitor_new(opts);
visit_type_MonitorOptions(v, NULL, &options, errp);
visit_free(v);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 30/39] tests: skip HMP-dependent tests when HMP is disabled
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (28 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:29 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP Marc-André Lureau
` (9 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add runtime detection of HMP availability so tests gracefully skip
instead of failing when QEMU is built without HMP support.
For qtests (drive_del-test), use compile-time #ifndef CONFIG_HMP guards.
For bash iotests, add _require_hmp() to common.rc that probes QEMU.
For Python iotests, add _verify_hmp() and a require_hmp parameter
threaded through execute_setup_common()/main()/script_initialize()/
script_main().
An earlier version of this series did an almost-complete conversion of
the tests to QMP. However, this made the series even longer. I decided
to post-pone it for now.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
tests/qtest/drive_del-test.c | 25 ++++++++++++++++++++++
tests/qemu-iotests/028 | 1 +
tests/qemu-iotests/045 | 3 ++-
tests/qemu-iotests/051 | 1 +
tests/qemu-iotests/056 | 3 ++-
tests/qemu-iotests/060 | 1 +
tests/qemu-iotests/068 | 1 +
tests/qemu-iotests/071 | 1 +
tests/qemu-iotests/081 | 1 +
tests/qemu-iotests/091 | 1 +
tests/qemu-iotests/093 | 3 ++-
tests/qemu-iotests/102 | 1 +
tests/qemu-iotests/117 | 1 +
tests/qemu-iotests/119 | 1 +
tests/qemu-iotests/120 | 1 +
tests/qemu-iotests/124 | 3 ++-
tests/qemu-iotests/130 | 1 +
tests/qemu-iotests/132 | 3 ++-
tests/qemu-iotests/136 | 3 ++-
tests/qemu-iotests/142 | 1 +
tests/qemu-iotests/145 | 1 +
tests/qemu-iotests/146 | 1 +
tests/qemu-iotests/148 | 3 ++-
tests/qemu-iotests/151 | 3 ++-
tests/qemu-iotests/152 | 3 ++-
tests/qemu-iotests/153 | 1 +
tests/qemu-iotests/156 | 1 +
tests/qemu-iotests/157 | 1 +
tests/qemu-iotests/161 | 1 +
tests/qemu-iotests/165 | 3 ++-
tests/qemu-iotests/172 | 1 +
tests/qemu-iotests/181 | 1 +
tests/qemu-iotests/185 | 1 +
tests/qemu-iotests/186 | 1 +
tests/qemu-iotests/192 | 1 +
tests/qemu-iotests/201 | 1 +
tests/qemu-iotests/216 | 3 ++-
tests/qemu-iotests/225 | 1 +
tests/qemu-iotests/232 | 1 +
tests/qemu-iotests/236 | 3 ++-
tests/qemu-iotests/245 | 3 ++-
tests/qemu-iotests/246 | 3 ++-
tests/qemu-iotests/249 | 1 +
tests/qemu-iotests/254 | 3 ++-
tests/qemu-iotests/255 | 3 ++-
tests/qemu-iotests/257 | 3 ++-
tests/qemu-iotests/260 | 3 ++-
tests/qemu-iotests/264 | 3 ++-
tests/qemu-iotests/267 | 1 +
tests/qemu-iotests/274 | 3 ++-
tests/qemu-iotests/280 | 1 +
tests/qemu-iotests/281 | 3 ++-
tests/qemu-iotests/283 | 1 +
tests/qemu-iotests/286 | 1 +
tests/qemu-iotests/298 | 3 ++-
tests/qemu-iotests/300 | 3 ++-
tests/qemu-iotests/304 | 3 ++-
tests/qemu-iotests/310 | 3 ++-
tests/qemu-iotests/common.rc | 8 +++++++
tests/qemu-iotests/iotests.py | 14 +++++++++++-
tests/qemu-iotests/tests/backup-discard-source | 3 ++-
tests/qemu-iotests/tests/copy-before-write | 3 ++-
tests/qemu-iotests/tests/image-fleecing | 3 ++-
tests/qemu-iotests/tests/iothreads-create | 3 ++-
| 3 ++-
.../tests/migrate-bitmaps-postcopy-test | 3 ++-
tests/qemu-iotests/tests/migrate-bitmaps-test | 3 ++-
tests/qemu-iotests/tests/mirror-change-copy-mode | 3 ++-
tests/qemu-iotests/tests/mirror-ready-cancel-error | 3 ++-
tests/qemu-iotests/tests/qcow2-internal-snapshots | 1 +
tests/qemu-iotests/tests/qsd-migrate | 3 ++-
tests/qemu-iotests/tests/reopen-file | 3 ++-
tests/qemu-iotests/tests/write-zeroes-unmap | 1 +
73 files changed, 152 insertions(+), 37 deletions(-)
diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c
index 30d9451ddda..804f56cc58d 100644
--- a/tests/qtest/drive_del-test.c
+++ b/tests/qtest/drive_del-test.c
@@ -167,6 +167,11 @@ static void test_drive_without_dev(void)
{
QTestState *qts;
+#ifndef CONFIG_HMP
+ g_test_skip("HMP not enabled");
+ return;
+#endif
+
/* Start with an empty drive */
qts = qtest_init("-drive if=none,id=drive0 -M none");
@@ -187,6 +192,11 @@ static void test_after_failed_device_add(void)
QDict *response;
QTestState *qts;
+#ifndef CONFIG_HMP
+ g_test_skip("HMP not enabled");
+ return;
+#endif
+
if (!has_device_builtin("virtio-blk")) {
g_test_skip("Device virtio-blk is not available");
return;
@@ -223,6 +233,11 @@ static void test_drive_del_device_del(void)
{
QTestState *qts;
+#ifndef CONFIG_HMP
+ g_test_skip("HMP not enabled");
+ return;
+#endif
+
if (!has_device_builtin("virtio-scsi")) {
g_test_skip("Device virtio-scsi is not available");
return;
@@ -397,6 +412,11 @@ static void test_drive_add_device_add_and_del(void)
const char *arch = qtest_get_arch();
const char *machine_addition = "";
+#ifndef CONFIG_HMP
+ g_test_skip("HMP not enabled");
+ return;
+#endif
+
if (!has_device_builtin("virtio-blk")) {
g_test_skip("Device virtio-blk is not available");
return;
@@ -424,6 +444,11 @@ static void test_drive_add_device_add_and_del_q35(void)
{
QTestState *qts;
+#ifndef CONFIG_HMP
+ g_test_skip("HMP not enabled");
+ return;
+#endif
+
if (!has_device_builtin("virtio-blk")) {
g_test_skip("Device virtio-blk is not available");
return;
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
index 2b232c46140..28f01439c52 100755
--- a/tests/qemu-iotests/028
+++ b/tests/qemu-iotests/028
@@ -49,6 +49,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2 qed
_supported_proto file fuse
_supported_os Linux
+_require_hmp
# Choose a size that is not necessarily a cluster size multiple for image
# formats that use clusters. This will ensure that the base image doesn't end
diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
index a341f21cd70..cd1b35edb17 100755
--- a/tests/qemu-iotests/045
+++ b/tests/qemu-iotests/045
@@ -172,4 +172,5 @@ class TestSCMFd(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['raw'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 4c079b11e32..a722c0c1bc8 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -45,6 +45,7 @@ _supported_proto file
_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)' data_file \
compression_type
_require_drivers nbd
+_require_hmp
if [ "$QEMU_DEFAULT_MACHINE" = "pc" ]; then
_require_devices lsi53c895a
diff --git a/tests/qemu-iotests/056 b/tests/qemu-iotests/056
index 808ea6b48ab..7cc97486951 100755
--- a/tests/qemu-iotests/056
+++ b/tests/qemu-iotests/056
@@ -332,4 +332,5 @@ class BackupTest(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
index 5cd21a6f686..8d06f84df16 100755
--- a/tests/qemu-iotests/060
+++ b/tests/qemu-iotests/060
@@ -56,6 +56,7 @@ _unsupported_imgopts 'compat=0.10' data_file \
# The repair process will create a large file - so check for availability first
_require_large_file 64G
+_require_hmp
rt_offset=65536 # 0x10000 (XXX: just an assumption)
rb_offset=131072 # 0x20000 (XXX: just an assumption)
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index 7ecd2474093..11b660a8b7c 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -43,6 +43,7 @@ _supported_proto generic
# Internal snapshots are (currently) impossible with refcount_bits=1,
# and generally impossible with external data files
_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
+_require_hmp
IMG_SIZE=128K
diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
index 331f8cfddcf..83c4ce6314c 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -43,6 +43,7 @@ _require_drivers blkdebug blkverify
# blkdebug can only inject errors on bs->file, not on the data_file,
# so this test does not work with external data files
_unsupported_imgopts data_file
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
index 1ac66f197e4..d9e729f674c 100755
--- a/tests/qemu-iotests/081
+++ b/tests/qemu-iotests/081
@@ -44,6 +44,7 @@ _supported_proto file
_supported_os Linux
_require_drivers quorum
_require_devices virtio-scsi
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/091 b/tests/qemu-iotests/091
index e396748a917..626203d6fc9 100755
--- a/tests/qemu-iotests/091
+++ b/tests/qemu-iotests/091
@@ -48,6 +48,7 @@ _supported_fmt qcow2
_supported_proto file fuse
_supported_os Linux
_supported_cache_modes writethrough none writeback
+_require_hmp
_default_cache_mode none writeback
size=1G
diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093
index 4f9e224e8a8..26ae6e2b2d5 100755
--- a/tests/qemu-iotests/093
+++ b/tests/qemu-iotests/093
@@ -419,4 +419,5 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
if __name__ == '__main__':
if 'null-co' not in iotests.supported_formats():
iotests.notrun('null-co driver support missing')
- iotests.main(supported_fmts=["raw"])
+ iotests.main(supported_fmts=["raw"],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
index 141bfe1e902..5db8180d3bb 100755
--- a/tests/qemu-iotests/102
+++ b/tests/qemu-iotests/102
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file fuse
+_require_hmp
IMG_SIZE=64K
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
index 6081473584f..5cc9433f4a6 100755
--- a/tests/qemu-iotests/117
+++ b/tests/qemu-iotests/117
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file fuse
+_require_hmp
_make_test_img 64k
diff --git a/tests/qemu-iotests/119 b/tests/qemu-iotests/119
index 6cac8793bac..ce1b62521f5 100755
--- a/tests/qemu-iotests/119
+++ b/tests/qemu-iotests/119
@@ -41,6 +41,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt raw
_supported_proto nbd
_supported_os Linux
+_require_hmp
_make_test_img 64M
# This should not crash
diff --git a/tests/qemu-iotests/120 b/tests/qemu-iotests/120
index ac7bd8c4e3c..e4ed87e1a70 100755
--- a/tests/qemu-iotests/120
+++ b/tests/qemu-iotests/120
@@ -42,6 +42,7 @@ _supported_fmt generic
_supported_proto file fuse
_unsupported_fmt luks
_require_drivers raw
+_require_hmp
_make_test_img 64M
diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index b2f4328e345..ab9ea4d8b59 100755
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -750,4 +750,5 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
index 7af85d20a89..3d10aba2594 100755
--- a/tests/qemu-iotests/130
+++ b/tests/qemu-iotests/130
@@ -46,6 +46,7 @@ _supported_proto file
_supported_os Linux
# We are going to use lazy-refcounts
_unsupported_imgopts 'compat=0.10'
+_require_hmp
qemu_comm_method="monitor"
diff --git a/tests/qemu-iotests/132 b/tests/qemu-iotests/132
index 12a64b3d95a..3756573a57c 100755
--- a/tests/qemu-iotests/132
+++ b/tests/qemu-iotests/132
@@ -57,4 +57,5 @@ class TestSingleDrive(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index 58df876bafc..72fd638aa04 100755
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -410,4 +410,5 @@ class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
if __name__ == '__main__':
if 'null-co' not in iotests.supported_formats():
iotests.notrun('null-co driver support missing')
- iotests.main(supported_fmts=["raw"])
+ iotests.main(supported_fmts=["raw"],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
index 86d65a2d1a1..8538a727ac0 100755
--- a/tests/qemu-iotests/142
+++ b/tests/qemu-iotests/142
@@ -43,6 +43,7 @@ _supported_proto file
# We test all cache modes anyway, but O_DIRECT needs to be supported
_default_cache_mode none
_supported_cache_modes none directsync
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145
index a2ce92516dc..f61a50f6395 100755
--- a/tests/qemu-iotests/145
+++ b/tests/qemu-iotests/145
@@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt generic
_supported_proto generic
+_require_hmp
_make_test_img 1M
diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
index 661a9d2625c..f63291d0ffb 100755
--- a/tests/qemu-iotests/146
+++ b/tests/qemu-iotests/146
@@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt vpc
_supported_proto file
_supported_os Linux
+_require_hmp
qemu_comm_method="monitor"
diff --git a/tests/qemu-iotests/148 b/tests/qemu-iotests/148
index 7ccbde4633c..4b092dccb7c 100755
--- a/tests/qemu-iotests/148
+++ b/tests/qemu-iotests/148
@@ -140,4 +140,5 @@ class TestFifoQuorumEvents(TestQuorumEvents):
if __name__ == '__main__':
iotests.verify_quorum()
iotests.main(supported_fmts=["raw"],
- supported_protocols=["file"])
+ supported_protocols=["file"],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index 647194094a4..204221a5738 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -434,4 +434,5 @@ class TestHighThrottledWithNbdExport(TestThrottledWithNbdExportBase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'raw'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/152 b/tests/qemu-iotests/152
index 197bea9e778..d9170359213 100755
--- a/tests/qemu-iotests/152
+++ b/tests/qemu-iotests/152
@@ -61,4 +61,5 @@ class TestUnaligned(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
index 1e02f6a6e34..def01d6f3ea 100755
--- a/tests/qemu-iotests/153
+++ b/tests/qemu-iotests/153
@@ -59,6 +59,7 @@ _check_ofd || _notrun "OFD lock not available"
_supported_fmt qcow2
_supported_proto file
+_require_hmp
_run_cmd()
{
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
index 97c2d86ce57..a0e4d1ffd42 100755
--- a/tests/qemu-iotests/156
+++ b/tests/qemu-iotests/156
@@ -53,6 +53,7 @@ _supported_fmt qcow2 qed
_supported_proto file
# Copying files around with cp does not work with external data files
_unsupported_imgopts data_file
+_require_hmp
# Create source disk
TEST_IMG="$TEST_IMG.backing" _make_test_img 1M
diff --git a/tests/qemu-iotests/157 b/tests/qemu-iotests/157
index aa2ebbfb4b4..531dbd3122b 100755
--- a/tests/qemu-iotests/157
+++ b/tests/qemu-iotests/157
@@ -41,6 +41,7 @@ _supported_fmt generic
_supported_proto file
_require_devices virtio-blk
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/161 b/tests/qemu-iotests/161
index f25effab936..8ca13926297 100755
--- a/tests/qemu-iotests/161
+++ b/tests/qemu-iotests/161
@@ -45,6 +45,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2 qed
_supported_proto file fuse
_supported_os Linux
+_require_hmp
IMG_SIZE=1M
diff --git a/tests/qemu-iotests/165 b/tests/qemu-iotests/165
index b3b1709d71f..8fc79daae16 100755
--- a/tests/qemu-iotests/165
+++ b/tests/qemu-iotests/165
@@ -154,4 +154,5 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'],
- unsupported_imgopts=['compat'])
+ unsupported_imgopts=['compat'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index 4da0e0f2e29..a78e42ff0ad 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -42,6 +42,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
+_require_hmp
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
_notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
index b904e8ce012..458cb737f1c 100755
--- a/tests/qemu-iotests/181
+++ b/tests/qemu-iotests/181
@@ -47,6 +47,7 @@ _supported_fmt generic
_unsupported_fmt qcow vdi vhdx vmdk vpc vvfat parallels
_supported_proto generic
_supported_os Linux
+_require_hmp
_flaky_test https://gitlab.com/qemu-project/qemu/-/work_items/3515
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
index a62ae8d3293..bb577a9cc99 100755
--- a/tests/qemu-iotests/185
+++ b/tests/qemu-iotests/185
@@ -50,6 +50,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
+_require_hmp
_flaky_test https://gitlab.com/qemu-project/qemu/-/issues/3270
size=$((64 * 1048576))
diff --git a/tests/qemu-iotests/186 b/tests/qemu-iotests/186
index eaf13c7a334..9a4215d28e9 100755
--- a/tests/qemu-iotests/186
+++ b/tests/qemu-iotests/186
@@ -41,6 +41,7 @@ _supported_fmt qcow2
_supported_proto file fuse
_require_drivers null-co
_require_devices virtio-scsi-pci
+_require_hmp
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
_notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/192 b/tests/qemu-iotests/192
index e66e1a4f06a..6869bd17153 100755
--- a/tests/qemu-iotests/192
+++ b/tests/qemu-iotests/192
@@ -43,6 +43,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt generic
_supported_proto file
+_require_hmp
if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
_notrun "Requires a PC machine"
diff --git a/tests/qemu-iotests/201 b/tests/qemu-iotests/201
index 1b8eb51d8f3..a5c750c38a8 100755
--- a/tests/qemu-iotests/201
+++ b/tests/qemu-iotests/201
@@ -47,6 +47,7 @@ _supported_os Linux
# Internal snapshots are (currently) impossible with refcount_bits=1,
# and generally impossible with external data files
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
+_require_hmp
size=64M
_make_test_img $size
diff --git a/tests/qemu-iotests/216 b/tests/qemu-iotests/216
index 311e02af3a7..4eabada9b35 100755
--- a/tests/qemu-iotests/216
+++ b/tests/qemu-iotests/216
@@ -25,7 +25,8 @@ from iotests import log, qemu_img, qemu_io
# Need backing file support
iotests.script_initialize(supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk'],
- supported_platforms=['linux'])
+ supported_platforms=['linux'],
+ require_hmp=True)
log('')
log('=== Copy-on-read across nodes ===')
diff --git a/tests/qemu-iotests/225 b/tests/qemu-iotests/225
index b5949fcb58e..8128d583d60 100755
--- a/tests/qemu-iotests/225
+++ b/tests/qemu-iotests/225
@@ -46,6 +46,7 @@ _supported_os Linux
_unsupported_imgopts "subformat=monolithicFlat" \
"subformat=twoGbMaxExtentFlat" \
"subformat=twoGbMaxExtentSparse"
+_require_hmp
TEST_IMG="$TEST_IMG.base" _make_test_img 1M
TEST_IMG="$TEST_IMG.not_base" _make_test_img 1M
diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232
index b30faaa2180..1ee0aae481d 100755
--- a/tests/qemu-iotests/232
+++ b/tests/qemu-iotests/232
@@ -43,6 +43,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt generic
_supported_proto file
_supported_os Linux
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/236 b/tests/qemu-iotests/236
index 20419bbb9e5..3cf0de4043f 100755
--- a/tests/qemu-iotests/236
+++ b/tests/qemu-iotests/236
@@ -23,7 +23,8 @@
import iotests
from iotests import log
-iotests.script_initialize(supported_fmts=['generic'])
+iotests.script_initialize(supported_fmts=['generic'],
+ require_hmp=True)
size = 64 * 1024 * 1024
granularity = 64 * 1024
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index f96610f5109..af08bcf0c96 100755
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -1160,4 +1160,5 @@ class TestBlockdevReopen(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.activate_logging()
iotests.main(supported_fmts=["qcow2"],
- supported_protocols=["file"])
+ supported_protocols=["file"],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/246 b/tests/qemu-iotests/246
index b009a783977..cee5131c3ce 100755
--- a/tests/qemu-iotests/246
+++ b/tests/qemu-iotests/246
@@ -24,7 +24,8 @@ import iotests
from iotests import log
iotests.script_initialize(supported_fmts=['qcow2'],
- unsupported_imgopts=['compat'])
+ unsupported_imgopts=['compat'],
+ require_hmp=True)
size = 64 * 1024 * 1024 * 1024
gran_small = 32 * 1024
gran_large = 128 * 1024
diff --git a/tests/qemu-iotests/249 b/tests/qemu-iotests/249
index 28bffd4d571..1254bf94291 100755
--- a/tests/qemu-iotests/249
+++ b/tests/qemu-iotests/249
@@ -45,6 +45,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2 qed
_supported_proto file fuse
_supported_os Linux
+_require_hmp
IMG_SIZE=1M
diff --git a/tests/qemu-iotests/254 b/tests/qemu-iotests/254
index 7ea098818cf..d3d18a1bbf1 100755
--- a/tests/qemu-iotests/254
+++ b/tests/qemu-iotests/254
@@ -23,7 +23,8 @@ import iotests
from iotests import qemu_img_create, file_path, log
iotests.script_initialize(supported_fmts=['qcow2'],
- unsupported_imgopts=['compat'])
+ unsupported_imgopts=['compat'],
+ require_hmp=True)
disk, top = file_path('disk', 'top')
size = 1024 * 1024
diff --git a/tests/qemu-iotests/255 b/tests/qemu-iotests/255
index 88b29d64b44..8f88522f1e9 100755
--- a/tests/qemu-iotests/255
+++ b/tests/qemu-iotests/255
@@ -24,7 +24,8 @@
import iotests
from iotests import imgfmt
-iotests.script_initialize(supported_fmts=['qcow2'])
+iotests.script_initialize(supported_fmts=['qcow2'],
+ require_hmp=True)
iotests.log('Finishing a commit job with background reads')
iotests.log('============================================')
diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257
index cd0468aaa16..5e4dba02e76 100755
--- a/tests/qemu-iotests/257
+++ b/tests/qemu-iotests/257
@@ -533,4 +533,5 @@ def main():
if __name__ == '__main__':
iotests.script_main(main, supported_fmts=['qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/260 b/tests/qemu-iotests/260
index c2133f99801..65165446607 100755
--- a/tests/qemu-iotests/260
+++ b/tests/qemu-iotests/260
@@ -24,7 +24,8 @@ from iotests import qemu_img_create, file_path, log, filter_qmp_event
iotests.script_initialize(
supported_fmts=['qcow2'],
- unsupported_imgopts=['compat']
+ unsupported_imgopts=['compat'],
+ require_hmp=True,
)
base, top = file_path('base', 'top')
diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
index c6ba2754e27..b621f11ab42 100755
--- a/tests/qemu-iotests/264
+++ b/tests/qemu-iotests/264
@@ -114,4 +114,5 @@ class TestNbdReconnect(iotests.QMPTestCase):
if __name__ == '__main__':
- iotests.main(supported_fmts=['qcow2'])
+ iotests.main(supported_fmts=['qcow2'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
index 2e2afdad9c5..e14aeb1f18d 100755
--- a/tests/qemu-iotests/267
+++ b/tests/qemu-iotests/267
@@ -48,6 +48,7 @@ _require_drivers copy-on-read
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
_require_devices virtio-blk
+_require_hmp
do_run_qemu()
{
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
index 2495e051a22..d91c11c70d2 100755
--- a/tests/qemu-iotests/274
+++ b/tests/qemu-iotests/274
@@ -24,7 +24,8 @@ import iotests
iotests.script_initialize(supported_fmts=['qcow2'],
supported_platforms=['linux'],
- unsupported_imgopts=['refcount_bits', 'compat'])
+ unsupported_imgopts=['refcount_bits', 'compat'],
+ require_hmp=True)
size_short = 1 * 1024 * 1024
size_long = 2 * 1024 * 1024
diff --git a/tests/qemu-iotests/280 b/tests/qemu-iotests/280
index 5f50500fdb8..8f4750de074 100755
--- a/tests/qemu-iotests/280
+++ b/tests/qemu-iotests/280
@@ -27,6 +27,7 @@ iotests.script_initialize(
supported_fmts=['qcow2'],
supported_protocols=['file'],
supported_platforms=['linux'],
+ require_hmp=True,
)
with iotests.FilePath('base') as base_path , \
diff --git a/tests/qemu-iotests/281 b/tests/qemu-iotests/281
index f6746a12e88..5f3050f50d0 100755
--- a/tests/qemu-iotests/281
+++ b/tests/qemu-iotests/281
@@ -336,4 +336,5 @@ class TestYieldingAndTimers(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'],
- unsupported_imgopts=['compat'])
+ unsupported_imgopts=['compat'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/283 b/tests/qemu-iotests/283
index 5defe48e97d..6d341d3e974 100755
--- a/tests/qemu-iotests/283
+++ b/tests/qemu-iotests/283
@@ -24,6 +24,7 @@ import iotests
# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs
iotests.script_initialize(
supported_fmts=['qcow2'],
+ require_hmp=True,
)
size = 1024 * 1024
diff --git a/tests/qemu-iotests/286 b/tests/qemu-iotests/286
index cc6aacf0228..3b030ec58aa 100755
--- a/tests/qemu-iotests/286
+++ b/tests/qemu-iotests/286
@@ -40,6 +40,7 @@ _supported_proto file fuse
# Internal snapshots are (currently) impossible with refcount_bits=1,
# and generally impossible with external data files
_unsupported_imgopts 'refcount_bits=1[^0-9]' data_file
+_require_hmp
_make_test_img 64M
diff --git a/tests/qemu-iotests/298 b/tests/qemu-iotests/298
index 09c9290711a..f2b94077f43 100755
--- a/tests/qemu-iotests/298
+++ b/tests/qemu-iotests/298
@@ -177,4 +177,5 @@ class TestTruncate(iotests.QMPTestCase):
if __name__ == '__main__':
- iotests.main(supported_fmts=['qcow2'], required_fmts=['preallocate'])
+ iotests.main(supported_fmts=['qcow2'], required_fmts=['preallocate'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
index e46616d7b19..df2ba326327 100755
--- a/tests/qemu-iotests/300
+++ b/tests/qemu-iotests/300
@@ -683,4 +683,5 @@ class TestAliasTransformMigration(TestDirtyBitmapMigration):
self.verify_dest_error(None)
if __name__ == '__main__':
- iotests.main(supported_protocols=['file'])
+ iotests.main(supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/304 b/tests/qemu-iotests/304
index 198f2820871..d465a519a93 100755
--- a/tests/qemu-iotests/304
+++ b/tests/qemu-iotests/304
@@ -24,7 +24,8 @@ import iotests
from iotests import qemu_img_create, qemu_img_log, file_path
iotests.script_initialize(supported_fmts=['qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
test_img = file_path('test.qcow2')
target_img = file_path('target.qcow2')
diff --git a/tests/qemu-iotests/310 b/tests/qemu-iotests/310
index 650d2cb6fb3..7f290898fea 100755
--- a/tests/qemu-iotests/310
+++ b/tests/qemu-iotests/310
@@ -25,7 +25,8 @@ from iotests import log, qemu_img, qemu_io
# Need backing file support
iotests.script_initialize(supported_fmts=['qcow2'],
- supported_platforms=['linux'])
+ supported_platforms=['linux'],
+ require_hmp=True)
log('')
log('=== Copy-on-read across nodes ===')
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 298bc483e0c..7dd4f6e0d8e 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -981,6 +981,14 @@ _require_drivers()
done
}
+_require_hmp()
+{
+ if echo quit | $QEMU -M none -display none -monitor stdio 2>&1 |
+ grep -q "HMP monitor is not available"; then
+ _notrun "HMP monitor not available"
+ fi
+}
+
# Check that we have a file system that allows huge (but very sparse) files
#
_require_large_file()
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index f36bcf31642..7d5a77a85e5 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1456,6 +1456,15 @@ def _verify_formats(required_formats: Sequence[str] = ()) -> None:
notrun(f'formats {usf_list} are not whitelisted')
+def _verify_hmp() -> None:
+ args = [qemu_prog] + qemu_opts + ['-M', 'none', '-monitor', 'stdio']
+ with subprocess.Popen(args, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ universal_newlines=True) as subp:
+ out, _ = subp.communicate('quit\n')
+ if 'HMP monitor is not available' in out:
+ notrun('HMP monitor not available')
+
def _verify_virtio_blk() -> None:
out = qemu_pipe('-M', 'none', '-device', 'help')
if 'virtio-blk' not in out:
@@ -1694,7 +1703,8 @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
supported_protocols: Sequence[str] = (),
unsupported_protocols: Sequence[str] = (),
required_fmts: Sequence[str] = (),
- unsupported_imgopts: Sequence[str] = ()) -> bool:
+ unsupported_imgopts: Sequence[str] = (),
+ require_hmp: bool = False) -> bool:
"""
Perform necessary setup for either script-style or unittest-style tests.
@@ -1715,6 +1725,8 @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
_verify_formats(required_fmts)
_verify_virtio_blk()
_verify_imgopts(unsupported_imgopts)
+ if require_hmp:
+ _verify_hmp()
return debug
diff --git a/tests/qemu-iotests/tests/backup-discard-source b/tests/qemu-iotests/tests/backup-discard-source
index 6c624bc8b0b..80ea32c46e3 100755
--- a/tests/qemu-iotests/tests/backup-discard-source
+++ b/tests/qemu-iotests/tests/backup-discard-source
@@ -160,4 +160,5 @@ class TestBackup(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/copy-before-write b/tests/qemu-iotests/tests/copy-before-write
index 3e43e7127f2..5531ad8a4c0 100755
--- a/tests/qemu-iotests/tests/copy-before-write
+++ b/tests/qemu-iotests/tests/copy-before-write
@@ -321,4 +321,5 @@ wrote 524288/524288 bytes at offset 524288
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'],
- required_fmts=['copy-before-write'])
+ required_fmts=['copy-before-write'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/image-fleecing b/tests/qemu-iotests/tests/image-fleecing
index 5e3b2c7e46a..b42aa6967f6 100755
--- a/tests/qemu-iotests/tests/image-fleecing
+++ b/tests/qemu-iotests/tests/image-fleecing
@@ -31,7 +31,8 @@ iotests.script_initialize(
supported_fmts=['qcow2'],
supported_platforms=['linux'],
required_fmts=['copy-before-write'],
- unsupported_imgopts=['compat']
+ unsupported_imgopts=['compat'],
+ require_hmp=True,
)
patterns = [('0x5d', '0', '64k'),
diff --git a/tests/qemu-iotests/tests/iothreads-create b/tests/qemu-iotests/tests/iothreads-create
index 0c862d73f20..09fe57a09ac 100755
--- a/tests/qemu-iotests/tests/iothreads-create
+++ b/tests/qemu-iotests/tests/iothreads-create
@@ -22,7 +22,8 @@ import asyncio
import iotests
iotests.script_initialize(supported_fmts=['qcow2', 'qcow', 'qed', 'vdi',
- 'vmdk', 'parallels'])
+ 'vmdk', 'parallels'],
+ require_hmp=True)
iotests.verify_virtio_scsi_pci_or_ccw()
with iotests.FilePath('disk.img') as img_path, \
--git a/tests/qemu-iotests/tests/luks-detached-header b/tests/qemu-iotests/tests/luks-detached-header
index 3455fd8de1e..58eb3c2cc48 100755
--- a/tests/qemu-iotests/tests/luks-detached-header
+++ b/tests/qemu-iotests/tests/luks-detached-header
@@ -313,4 +313,5 @@ class TestDetachedLUKSHeader(QMPTestCase):
if __name__ == "__main__":
# Test image creation and I/O
- iotests.main(supported_fmts=["luks"], supported_protocols=["file"])
+ iotests.main(supported_fmts=["luks"], supported_protocols=["file"],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
index c519e6db8c7..9014c2a19e2 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
@@ -266,4 +266,5 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'],
- unsupported_imgopts=['compat'])
+ unsupported_imgopts=['compat'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test b/tests/qemu-iotests/tests/migrate-bitmaps-test
index 8fb4099201d..7b0e709f9b4 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test
@@ -296,7 +296,8 @@ def main() -> None:
iotests.main(
supported_fmts=['qcow2'],
supported_protocols=['file'],
- unsupported_imgopts=['compat']
+ unsupported_imgopts=['compat'],
+ require_hmp=True,
)
diff --git a/tests/qemu-iotests/tests/mirror-change-copy-mode b/tests/qemu-iotests/tests/mirror-change-copy-mode
index 51788b85c7a..c9c345f1397 100755
--- a/tests/qemu-iotests/tests/mirror-change-copy-mode
+++ b/tests/qemu-iotests/tests/mirror-change-copy-mode
@@ -190,4 +190,5 @@ class TestMirrorChangeCopyMode(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'raw'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/mirror-ready-cancel-error b/tests/qemu-iotests/tests/mirror-ready-cancel-error
index ed2e46447e3..ffa045af219 100755
--- a/tests/qemu-iotests/tests/mirror-ready-cancel-error
+++ b/tests/qemu-iotests/tests/mirror-ready-cancel-error
@@ -139,4 +139,5 @@ if __name__ == '__main__':
# LUKS would require special key-secret handling in add_blockdevs()
iotests.main(supported_fmts=['generic'],
unsupported_fmts=['luks'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/qcow2-internal-snapshots b/tests/qemu-iotests/tests/qcow2-internal-snapshots
index 9f83aa89039..d301f0941b5 100755
--- a/tests/qemu-iotests/tests/qcow2-internal-snapshots
+++ b/tests/qemu-iotests/tests/qcow2-internal-snapshots
@@ -43,6 +43,7 @@ _supported_proto file
# Internal snapshots are (currently) impossible with refcount_bits=1,
# and generally impossible with external data files
_unsupported_imgopts 'compat=0.10' 'refcount_bits=1[^0-9]' data_file
+_require_hmp
IMG_SIZE=64M
diff --git a/tests/qemu-iotests/tests/qsd-migrate b/tests/qemu-iotests/tests/qsd-migrate
index a4c6592420c..d76278b576c 100755
--- a/tests/qemu-iotests/tests/qsd-migrate
+++ b/tests/qemu-iotests/tests/qsd-migrate
@@ -24,7 +24,8 @@ from iotests import filter_qemu_io, filter_qtest
iotests.script_initialize(supported_fmts=['qcow2', 'qed', 'raw'],
supported_protocols=['file'],
- supported_platforms=['linux'])
+ supported_platforms=['linux'],
+ require_hmp=True)
with iotests.FilePath('disk.img') as path, \
iotests.FilePath('nbd-src.sock', base_dir=iotests.sock_dir) as nbd_src, \
diff --git a/tests/qemu-iotests/tests/reopen-file b/tests/qemu-iotests/tests/reopen-file
index 5a50794ffc4..f8812320ea8 100755
--- a/tests/qemu-iotests/tests/reopen-file
+++ b/tests/qemu-iotests/tests/reopen-file
@@ -85,4 +85,5 @@ if __name__ == '__main__':
# Must support creating images and reopen
iotests.main(supported_fmts=['qcow', 'qcow2', 'qed', 'raw', 'vdi', 'vhdx',
'vmdk', 'vpc'],
- supported_protocols=['file'])
+ supported_protocols=['file'],
+ require_hmp=True)
diff --git a/tests/qemu-iotests/tests/write-zeroes-unmap b/tests/qemu-iotests/tests/write-zeroes-unmap
index f90fb8e8d27..506ced647bc 100755
--- a/tests/qemu-iotests/tests/write-zeroes-unmap
+++ b/tests/qemu-iotests/tests/write-zeroes-unmap
@@ -33,6 +33,7 @@ _supported_fmt raw
_supported_proto file
_supported_os Linux
_require_disk_usage
+_require_hmp
create_test_image() {
_make_test_img -f $IMGFMT 1m
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (29 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 30/39] tests: skip HMP-dependent tests " Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:34 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
` (8 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Guard calls to monitor_vprintf in error-report and qemu-print so
they compile without HMP. When CONFIG_HMP is not set,
error_vprintf_mon falls back directly to stderr and qemu_vfprintf
returns -1 for NULL streams.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/unit/test-util-sockets.c | 4 +++-
tools/qemu-vnc/stubs.c | 2 ++
util/error-report.c | 8 +++++---
util/qemu-print.c | 6 ++++++
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
index b9f2453e299..23ebe1e26b5 100644
--- a/tests/unit/test-util-sockets.c
+++ b/tests/unit/test-util-sockets.c
@@ -73,8 +73,10 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
*/
Monitor *monitor_cur(void) { return cur_mon; }
Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { abort(); }
-int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
bool monitor_cur_is_qmp(void) { abort(); };
+#ifdef CONFIG_HMP
+int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
+#endif
#ifndef _WIN32
static void test_socket_fd_pass_name_good(void)
diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
index a865ce85f04..f476dd6d956 100644
--- a/tools/qemu-vnc/stubs.c
+++ b/tools/qemu-vnc/stubs.c
@@ -46,10 +46,12 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
return NULL;
}
+#ifdef CONFIG_HMP
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
return -1;
}
+#endif
/*
* Link-time stubs for VMState symbols referenced by VNC code.
diff --git a/util/error-report.c b/util/error-report.c
index f832ad9b6b6..e2e46281455 100644
--- a/util/error-report.c
+++ b/util/error-report.c
@@ -40,11 +40,13 @@ error_vprintf_mon(Monitor *cur_mon, const char *fmt, va_list ap)
* IOW this will only print if in HMP, otherwise we
* fallback to stderr for QMP / no-monitor scenarios.
*/
+#ifdef CONFIG_HMP
int ret = monitor_vprintf(cur_mon, fmt, ap);
- if (ret == -1) {
- ret = vfprintf(stderr, fmt, ap);
+ if (ret != -1) {
+ return ret;
}
- return ret;
+#endif
+ return vfprintf(stderr, fmt, ap);
}
/*
diff --git a/util/qemu-print.c b/util/qemu-print.c
index 7b9591035e5..ee80000722b 100644
--- a/util/qemu-print.c
+++ b/util/qemu-print.c
@@ -20,10 +20,12 @@
*/
int qemu_vprintf(const char *fmt, va_list ap)
{
+#ifdef CONFIG_HMP
Monitor *cur_mon = monitor_cur();
if (cur_mon) {
return monitor_vprintf(cur_mon, fmt, ap);
}
+#endif
return vprintf(fmt, ap);
}
@@ -52,7 +54,11 @@ int qemu_printf(const char *fmt, ...)
int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap)
{
if (!stream) {
+#ifdef CONFIG_HMP
return monitor_vprintf(monitor_cur(), fmt, ap);
+#else
+ return -1;
+#endif
}
return vfprintf(stream, fmt, ap);
}
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (30 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:35 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 33/39] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
` (7 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Make the 'readline' value of MonitorMode and the
'human-monitor-command' command conditional on CONFIG_HMP, so
they are only available when HMP support is compiled in.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/control.json | 4 +++-
qapi/misc.json | 3 ++-
monitor/monitor.c | 8 +++++++-
monitor/qmp-cmds.c | 2 ++
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/qapi/control.json b/qapi/control.json
index 9a5302193d6..9898552814b 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -186,7 +186,9 @@
#
# Since: 5.0
##
-{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
+{ 'enum': 'MonitorMode', 'data': [
+ { 'name': 'readline', 'if': 'CONFIG_HMP' },
+ 'control' ] }
##
# @MonitorOptions:
diff --git a/qapi/misc.json b/qapi/misc.json
index 22b7afed9f6..a21ba61b96e 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -247,7 +247,8 @@
{ 'command': 'human-monitor-command',
'data': {'command-line': 'str', '*cpu-index': 'int'},
'returns': 'str',
- 'features': [ 'savevm-monitor-nodes' ] }
+ 'features': [ 'savevm-monitor-nodes' ],
+ 'if': 'CONFIG_HMP' }
##
# @getfd:
diff --git a/monitor/monitor.c b/monitor/monitor.c
index f443f406b4c..50f1fe77c33 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -733,13 +733,18 @@ int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
}
if (!opts->has_mode) {
- opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
+ opts->mode =
+#ifdef CONFIG_HMP
+ allow_hmp ? MONITOR_MODE_READLINE :
+#endif
+ MONITOR_MODE_CONTROL;
}
switch (opts->mode) {
case MONITOR_MODE_CONTROL:
monitor_init_qmp(chr, opts->pretty, errp);
break;
+#ifdef CONFIG_HMP
case MONITOR_MODE_READLINE:
if (!allow_hmp) {
error_setg(errp, "Only QMP is supported");
@@ -751,6 +756,7 @@ int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
}
monitor_init_hmp(chr, true, errp);
break;
+#endif /* CONFIG_HMP */
default:
g_assert_not_reached();
}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 0c409c27dc3..5e642a2b14d 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -162,6 +162,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
}
}
+#ifdef CONFIG_HMP
char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
int64_t cpu_index, Error **errp)
{
@@ -189,6 +190,7 @@ out:
monitor_data_destroy(&hmp.common);
return output;
}
+#endif /* CONFIG_HMP */
static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
{
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 33/39] system: guard HMP initialization paths with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (31 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 34/39] Guard HMP command implementations " Marc-André Lureau
` (6 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
- disable default monitor when HMP is not available
- hide 'readline' from -mon help text
- error out on mux chardev monitor when no HMP
- skip HMP monitor terminal for gdb, return E01 for 'qRcmd' remote
commands
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
chardev/char.c | 7 +++++++
gdbstub/system.c | 8 ++++++++
system/vl.c | 4 ++++
qemu-options.hx | 6 +++++-
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/chardev/char.c b/chardev/char.c
index ca8b37ed8d7..5f2b9fbc4bf 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -805,6 +805,7 @@ static Chardev *qemu_chr_new_from_name(const char *label, const char *filename,
if (qemu_opt_get_bool(opts, "mux", 0)) {
assert(permit_mux_mon);
+#ifdef CONFIG_HMP
monitor_init_hmp(chr, true, &err);
if (err) {
error_report_err(err);
@@ -812,6 +813,12 @@ static Chardev *qemu_chr_new_from_name(const char *label, const char *filename,
chr = NULL;
goto out;
}
+#else
+ error_report("HMP monitor is disabled");
+ object_unparent(OBJECT(chr));
+ chr = NULL;
+ goto out;
+#endif
}
out:
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 2063b63b2f8..4e0e94ffb28 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -386,10 +386,14 @@ bool gdbserver_start(const char *device, Error **errp)
qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
+#ifdef CONFIG_HMP
/* Initialize a monitor terminal for gdb */
mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
NULL, NULL, &error_abort);
monitor_init_hmp(mon_chr, false, &error_abort);
+#else
+ mon_chr = NULL;
+#endif
} else {
qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
mon_chr = gdbserver_system_state.mon_chr;
@@ -528,10 +532,14 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx)
len = len / 2;
gdb_hextomem(gdbserver_state.mem_buf, gdb_get_cmd_param(params, 0)->data, len);
g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
+#ifdef CONFIG_HMP
qemu_chr_be_write(gdbserver_system_state.mon_chr,
gdbserver_state.mem_buf->data,
gdbserver_state.mem_buf->len);
gdb_put_packet("OK");
+#else
+ gdb_put_packet("E01");
+#endif
}
/*
diff --git a/system/vl.c b/system/vl.c
index dd7fe828118..1e693710920 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -199,7 +199,11 @@ static int has_defaults = 1;
static int default_audio = 1;
static int default_serial = 1;
static int default_parallel = 1;
+#ifdef CONFIG_HMP
static int default_monitor = 1;
+#else
+static int default_monitor; /* false */
+#endif
static int default_floppy = 1;
static int default_cdrom = 1;
static bool auto_create_sdcard = true;
diff --git a/qemu-options.hx b/qemu-options.hx
index c799286153f..4714b5e8f85 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4962,7 +4962,11 @@ SRST
ERST
DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
- "-mon [chardev=]name[,mode=readline|control][,pretty=on|off]\n", QEMU_ARCH_ALL)
+ "-mon [chardev=]name[,mode="
+#ifdef CONFIG_HMP
+ "readline|"
+#endif
+ "control][,pretty=on|off]\n", QEMU_ARCH_ALL)
SRST
``-mon [chardev=]name[,mode=readline|control][,pretty=on|off]``
Set up a monitor connected to the chardev ``name``.
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 34/39] Guard HMP command implementations with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (32 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 33/39] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 18:36 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 35/39] target: guard MonitorDef tables " Marc-André Lureau
` (5 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Add #ifdef CONFIG_HMP around all hmp_* function implementations and
their HMP-only helpers across subsystems.
This covers monitor_register_hmp* callers, hmp_info_* handlers, and
HMP-only helper functions like slirp_lookup.
To link succesfully, use empty cmds tables in hmp-cmds.c (to be removed
once meson build-sys is updated with !hmp support later in the series)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
accel/accel-system.c | 2 ++
accel/tcg/monitor.c | 2 ++
hw/i386/kvm/xen-stubs.c | 2 ++
hw/i386/kvm/xen_evtchn.c | 3 ++-
hw/i386/sgx.c | 2 ++
hw/misc/mos6522-stub.c | 2 ++
hw/misc/mos6522.c | 2 ++
hw/pci/pci-stub.c | 2 ++
hw/s390x/s390-skeys.c | 2 ++
hw/s390x/s390-stattrib.c | 4 ++++
hw/uefi/ovmf-log.c | 2 ++
hw/usb/host-libusb.c | 6 ++++++
migration/dirtyrate.c | 2 ++
monitor/hmp-cmds.c | 5 +++++
net/slirp.c | 7 ++++++-
replay/replay-debugging.c | 8 ++++++++
replay/stubs-system.c | 6 ++++++
system/dirtylimit.c | 6 ++++++
system/qdev-monitor.c | 4 ++++
target/i386/cpu-apic.c | 2 ++
target/i386/monitor.c | 3 +++
target/i386/sev.c | 2 ++
target/m68k/monitor.c | 2 ++
target/ppc/monitor.c | 2 ++
target/riscv/monitor.c | 3 +++
target/sh4/monitor.c | 2 ++
target/sparc/monitor.c | 2 ++
target/xtensa/monitor.c | 2 ++
28 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/accel/accel-system.c b/accel/accel-system.c
index 9176665202d..a8715924729 100644
--- a/accel/accel-system.c
+++ b/accel/accel-system.c
@@ -108,7 +108,9 @@ void accel_init_ops_interfaces(AccelClass *ac)
static void accel_ops_class_init(ObjectClass *oc, const void *data)
{
+#ifdef CONFIG_HMP
monitor_register_hmp_info_hrt("accel", qmp_x_accel_stats);
+#endif
}
static const TypeInfo accel_ops_type_info = {
diff --git a/accel/tcg/monitor.c b/accel/tcg/monitor.c
index be5c1950177..c860744536b 100644
--- a/accel/tcg/monitor.c
+++ b/accel/tcg/monitor.c
@@ -29,9 +29,11 @@ HumanReadableText *qmp_x_query_jit(Error **errp)
return human_readable_text_from_str(buf);
}
+#ifdef CONFIG_HMP
static void hmp_tcg_register(void)
{
monitor_register_hmp_info_hrt("jit", qmp_x_query_jit);
}
type_init(hmp_tcg_register);
+#endif
diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c
index bf6ac28bef4..df36c84a4f4 100644
--- a/hw/i386/kvm/xen-stubs.c
+++ b/hw/i386/kvm/xen-stubs.c
@@ -40,6 +40,7 @@ void xen_primary_console_set_be_port(uint16_t port)
{
}
+#ifdef CONFIG_HMP
void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
@@ -49,3 +50,4 @@ void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "XEN emulation is not available in this QEMU\n");
}
+#endif
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 8b243984e41..cb7b4c7a81b 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -2344,6 +2344,7 @@ void qmp_xen_event_inject(uint32_t port, Error **errp)
}
}
+#ifdef CONFIG_HMP
void hmp_xen_event_list(Monitor *mon, const QDict *qdict)
{
EvtchnInfoList *iter, *info_list;
@@ -2391,4 +2392,4 @@ void hmp_xen_event_inject(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "Delivered port %d\n", port);
}
}
-
+#endif
diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c
index 7e4c509f5a4..4ac8ea75aa7 100644
--- a/hw/i386/sgx.c
+++ b/hw/i386/sgx.c
@@ -234,6 +234,7 @@ SgxInfo *qmp_query_sgx(Error **errp)
return info;
}
+#ifdef CONFIG_HMP
void hmp_info_sgx(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
@@ -265,6 +266,7 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "total size=%" PRIu64 "\n",
size);
}
+#endif
bool check_sgx_support(void)
{
diff --git a/hw/misc/mos6522-stub.c b/hw/misc/mos6522-stub.c
index 85eb0ee36ee..03fea6985a9 100644
--- a/hw/misc/mos6522-stub.c
+++ b/hw/misc/mos6522-stub.c
@@ -10,7 +10,9 @@
#include "monitor/monitor.h"
#include "monitor/hmp.h"
+#ifdef CONFIG_HMP
void hmp_info_via(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "MOS6522 VIA is not available in this QEMU\n");
}
+#endif
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index bae766ef178..6be7ed3ff30 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -497,6 +497,7 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
}
}
+#ifdef CONFIG_HMP
static int qmp_x_query_via_foreach(Object *obj, void *opaque)
{
GString *buf = opaque;
@@ -596,6 +597,7 @@ void hmp_info_via(Monitor *mon, const QDict *qdict)
}
monitor_puts(mon, info->human_readable_text);
}
+#endif /* CONFIG_HMP */
static const MemoryRegionOps mos6522_ops = {
.read = mos6522_read,
diff --git a/hw/pci/pci-stub.c b/hw/pci/pci-stub.c
index 3397d0c82ea..f217373ef03 100644
--- a/hw/pci/pci-stub.c
+++ b/hw/pci/pci-stub.c
@@ -34,6 +34,7 @@ PciInfoList *qmp_query_pci(Error **errp)
return NULL;
}
+#ifdef CONFIG_HMP
void hmp_info_pci(Monitor *mon, const QDict *qdict)
{
}
@@ -42,6 +43,7 @@ void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
{
monitor_printf(mon, "PCI devices not supported\n");
}
+#endif
/* kvm-all wants this */
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 7dca67d6618..81885a1640c 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -104,6 +104,7 @@ static void write_keys(FILE *f, uint8_t *keys, uint64_t startgfn,
}
}
+#ifdef CONFIG_HMP
void hmp_info_skeys(Monitor *mon, const QDict *qdict)
{
S390SKeysState *ss = s390_get_skeys_device();
@@ -144,6 +145,7 @@ void hmp_dump_skeys(Monitor *mon, const QDict *qdict)
error_report_err(err);
}
}
+#endif
void s390_qmp_dump_skeys(const char *filename, Error **errp)
{
diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c
index c334714b31a..2fdf70bf2ed 100644
--- a/hw/s390x/s390-stattrib.c
+++ b/hw/s390x/s390-stattrib.c
@@ -32,6 +32,7 @@
#define STATTR_FLAG_ERROR 0x04ULL
#define STATTR_FLAG_DONE 0x08ULL
+#ifdef CONFIG_HMP
static S390StAttribState *s390_get_stattrib_device(void)
{
S390StAttribState *sas;
@@ -40,6 +41,7 @@ static S390StAttribState *s390_get_stattrib_device(void)
assert(sas);
return sas;
}
+#endif
void s390_stattrib_init(void)
{
@@ -59,6 +61,7 @@ void s390_stattrib_init(void)
/* Console commands: */
+#ifdef CONFIG_HMP
void hmp_migrationmode(Monitor *mon, const QDict *qdict)
{
S390StAttribState *sas = s390_get_stattrib_device();
@@ -110,6 +113,7 @@ void hmp_info_cmma(Monitor *mon, const QDict *qdict)
out:
g_free(vals);
}
+#endif
/* Migration support: */
diff --git a/hw/uefi/ovmf-log.c b/hw/uefi/ovmf-log.c
index 3a24afd9417..395a2d10a37 100644
--- a/hw/uefi/ovmf-log.c
+++ b/hw/uefi/ovmf-log.c
@@ -256,6 +256,7 @@ FirmwareLog *qmp_query_firmware_log(bool have_max_size, uint64_t max_size,
return ret;
}
+#ifdef CONFIG_HMP
void hmp_info_firmware_log(Monitor *mon, const QDict *qdict)
{
g_autofree gchar *log_esc = NULL;
@@ -284,3 +285,4 @@ void hmp_info_firmware_log(Monitor *mon, const QDict *qdict)
log_esc = g_strescape((gchar *)log_out, "\r\n");
monitor_printf(mon, "%s\n", log_esc);
}
+#endif
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index b9f3ad3f66d..121fd817e82 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -183,6 +183,7 @@ static void usb_host_attach_kernel(USBHostDevice *s);
# define HAVE_SUPER_PLUS 1
#endif
+#ifdef CONFIG_HMP
static const char *speed_name[] = {
[LIBUSB_SPEED_UNKNOWN] = "?",
[LIBUSB_SPEED_LOW] = "1.5",
@@ -193,6 +194,7 @@ static const char *speed_name[] = {
[LIBUSB_SPEED_SUPER_PLUS] = "5000+",
#endif
};
+#endif
static const unsigned int speed_map[] = {
[LIBUSB_SPEED_LOW] = USB_SPEED_LOW,
@@ -1814,7 +1816,9 @@ module_kconfig(USB);
static void usb_host_register_types(void)
{
type_register_static(&usb_host_dev_info);
+#ifdef CONFIG_HMP
monitor_register_hmp("usbhost", true, hmp_info_usbhost);
+#endif
}
type_init(usb_host_register_types)
@@ -1919,6 +1923,7 @@ static void usb_host_auto_check(void *unused)
timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
}
+#ifdef CONFIG_HMP
void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
{
libusb_device **devs = NULL;
@@ -1962,3 +1967,4 @@ void hmp_info_usbhost(Monitor *mon, const QDict *qdict)
}
libusb_free_device_list(devs, 1);
}
+#endif
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index b360f49efea..8808f20f1b9 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -856,6 +856,7 @@ struct DirtyRateInfo *qmp_query_dirty_rate(bool has_calc_time_unit,
has_calc_time_unit ? calc_time_unit : TIME_UNIT_SECOND);
}
+#ifdef CONFIG_HMP
void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict)
{
DirtyRateInfo *info = query_dirty_rate_info(TIME_UNIT_SECOND);
@@ -932,3 +933,4 @@ void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict)
" seconds\n", sec);
monitor_printf(mon, "[Please use 'info dirty_rate' to check results]\n");
}
+#endif
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index e7a02b1fddb..a68d3b828d2 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -42,6 +42,7 @@
#include "disas/disas.h"
/* Please update hmp-commands.hx when adding or changing commands */
+#ifdef CONFIG_HMP
static HMPCommand hmp_info_cmds[] = {
#include "hmp-commands-info.h"
{ NULL, NULL, },
@@ -52,6 +53,10 @@ static HMPCommand hmp_cmds[] = {
#include "hmp-commands.h"
{ NULL, NULL, },
};
+#else
+static HMPCommand hmp_info_cmds[] = { { NULL, NULL, }, };
+static HMPCommand hmp_cmds[] = { { NULL, NULL, }, };
+#endif
HMPCommand *hmp_cmds_for_target(bool info_command)
{
diff --git a/net/slirp.c b/net/slirp.c
index 517dd23be14..d9527e663aa 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -710,6 +710,7 @@ error:
return -1;
}
+#ifdef CONFIG_HMP
static SlirpState *slirp_lookup(Monitor *mon, const char *id)
{
if (id) {
@@ -800,6 +801,7 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
fail_syntax:
monitor_printf(mon, "invalid format\n");
}
+#endif
static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
{
@@ -956,6 +958,7 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp)
return -1;
}
+#ifdef CONFIG_HMP
void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
{
const char *redir_str;
@@ -976,8 +979,8 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
error_report_err(err);
}
}
-
}
+#endif
#if defined(CONFIG_SMBD_COMMAND)
@@ -1223,6 +1226,7 @@ UsernetInfoList *qmp_x_query_usernet(Error **errp)
return head;
}
+#ifdef CONFIG_HMP
void hmp_info_usernet(Monitor *mon, const QDict *qdict)
{
g_autoptr(UsernetInfoList) list = NULL;
@@ -1236,6 +1240,7 @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
ui->hub_name, ui->info);
}
}
+#endif
static void
net_init_slirp_configs_host(const NetdevUserHostForwardList *fwd)
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
index 11053640021..1adf7422e36 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -31,6 +31,7 @@ bool replay_running_debug(void)
return replay_is_debugging;
}
+#ifdef CONFIG_HMP
void hmp_info_replay(Monitor *mon, const QDict *qdict)
{
if (replay_mode == REPLAY_MODE_NONE) {
@@ -42,6 +43,7 @@ void hmp_info_replay(Monitor *mon, const QDict *qdict)
replay_get_filename(), replay_get_current_icount());
}
}
+#endif
ReplayInfo *qmp_query_replay(Error **errp)
{
@@ -103,6 +105,7 @@ void qmp_replay_break(int64_t icount, Error **errp)
}
}
+#ifdef CONFIG_HMP
void hmp_replay_break(Monitor *mon, const QDict *qdict)
{
int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
@@ -114,6 +117,7 @@ void hmp_replay_break(Monitor *mon, const QDict *qdict)
return;
}
}
+#endif
void qmp_replay_delete_break(Error **errp)
{
@@ -124,6 +128,7 @@ void qmp_replay_delete_break(Error **errp)
}
}
+#ifdef CONFIG_HMP
void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
@@ -134,6 +139,7 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
return;
}
}
+#endif
static char *replay_find_nearest_snapshot(int64_t icount,
int64_t *snapshot_icount)
@@ -208,6 +214,7 @@ void qmp_replay_seek(int64_t icount, Error **errp)
replay_seek(icount, replay_stop_vm, errp);
}
+#ifdef CONFIG_HMP
void hmp_replay_seek(Monitor *mon, const QDict *qdict)
{
int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
@@ -219,6 +226,7 @@ void hmp_replay_seek(Monitor *mon, const QDict *qdict)
return;
}
}
+#endif
static void replay_stop_vm_debug(void *opaque)
{
diff --git a/replay/stubs-system.c b/replay/stubs-system.c
index f8e17dcf1ce..5ca80b4439d 100644
--- a/replay/stubs-system.c
+++ b/replay/stubs-system.c
@@ -63,22 +63,28 @@ void replay_vmstate_init(void)
#include "qapi/error.h"
#include "qemu/error-report.h"
+#ifdef CONFIG_HMP
void hmp_info_replay(Monitor *mon, const QDict *qdict)
{
error_report("replay support not available");
}
+
void hmp_replay_break(Monitor *mon, const QDict *qdict)
{
error_report("replay support not available");
}
+
void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
{
error_report("replay support not available");
}
+
void hmp_replay_seek(Monitor *mon, const QDict *qdict)
{
error_report("replay support not available");
}
+#endif
+
ReplayInfo *qmp_query_replay(Error **errp)
{
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
diff --git a/system/dirtylimit.c b/system/dirtylimit.c
index 50fa67f3d6a..8992c45a509 100644
--- a/system/dirtylimit.c
+++ b/system/dirtylimit.c
@@ -491,6 +491,7 @@ void qmp_cancel_vcpu_dirty_limit(bool has_cpu_index,
dirtylimit_state_unlock();
}
+#ifdef CONFIG_HMP
void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
{
int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1);
@@ -505,6 +506,7 @@ void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "[Please use 'info vcpu_dirty_limit' to query "
"dirty limit for virtual CPU]\n");
}
+#endif
void qmp_set_vcpu_dirty_limit(bool has_cpu_index,
int64_t cpu_index,
@@ -548,6 +550,7 @@ void qmp_set_vcpu_dirty_limit(bool has_cpu_index,
dirtylimit_state_unlock();
}
+#ifdef CONFIG_HMP
void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
{
int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate");
@@ -564,6 +567,7 @@ void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
out:
hmp_handle_error(mon, err);
}
+#endif
/* Return the max throttle time of each virtual CPU */
uint64_t dirtylimit_throttle_time_per_round(void)
@@ -647,6 +651,7 @@ struct DirtyLimitInfoList *qmp_query_vcpu_dirty_limit(Error **errp)
return dirtylimit_query_all();
}
+#ifdef CONFIG_HMP
void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
{
DirtyLimitInfoList *info;
@@ -672,3 +677,4 @@ void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict)
info->value->current_rate);
}
}
+#endif
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index dfc95a08c10..68454bc7909 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -763,6 +763,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
return ret;
}
+#ifdef CONFIG_HMP
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qdev_print_props(Monitor *mon, DeviceState *dev, DeviceClass *dc,
@@ -864,6 +865,7 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict)
{
qdev_print_devinfos(true);
}
+#endif /* CONFIG_HMP */
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
{
@@ -1001,6 +1003,7 @@ void qmp_device_sync_config(const char *id, Error **errp)
qdev_sync_config(dev, errp);
}
+#ifdef CONFIG_HMP
void hmp_device_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
@@ -1043,6 +1046,7 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
qmp_device_del(id, &err);
hmp_handle_error(mon, err);
}
+#endif
void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
{
diff --git a/target/i386/cpu-apic.c b/target/i386/cpu-apic.c
index 04b7257ad12..2f4c8a58fb2 100644
--- a/target/i386/cpu-apic.c
+++ b/target/i386/cpu-apic.c
@@ -80,6 +80,7 @@ void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
}
}
+#ifdef CONFIG_HMP
void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
{
CPUState *cs;
@@ -102,3 +103,4 @@ void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
}
x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
}
+#endif
diff --git a/target/i386/monitor.c b/target/i386/monitor.c
index 9ed772e6d7f..18329b6cc98 100644
--- a/target/i386/monitor.c
+++ b/target/i386/monitor.c
@@ -31,6 +31,8 @@
#include "qapi/qapi-commands-misc.h"
#include "system/memory.h"
+#ifdef CONFIG_HMP
+
/* Perform linear address sign extension */
static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
{
@@ -595,3 +597,4 @@ void hmp_mce(Monitor *mon, const QDict *qdict)
}
hmp_handle_error(mon, err);
}
+#endif
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 99cf30806be..b6d975ae2b2 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -758,6 +758,7 @@ SevInfo *qmp_query_sev(Error **errp)
return info;
}
+#ifdef CONFIG_HMP
void hmp_info_sev(Monitor *mon, const QDict *qdict)
{
SevInfo *info = sev_get_info();
@@ -791,6 +792,7 @@ void hmp_info_sev(Monitor *mon, const QDict *qdict)
out:
qapi_free_SevInfo(info);
}
+#endif
static int
sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
diff --git a/target/m68k/monitor.c b/target/m68k/monitor.c
index 3e0df40a6b8..27f65d556e5 100644
--- a/target/m68k/monitor.c
+++ b/target/m68k/monitor.c
@@ -10,6 +10,7 @@
#include "monitor/hmp.h"
#include "monitor/monitor.h"
+#ifdef CONFIG_HMP
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu_env(mon);
@@ -21,3 +22,4 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
dump_mmu(env1);
}
+#endif
diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c
index 7c88e0e2bda..2fa27105a34 100644
--- a/target/ppc/monitor.c
+++ b/target/ppc/monitor.c
@@ -11,6 +11,7 @@
#include "monitor/hmp.h"
#include "cpu.h"
+#ifdef CONFIG_HMP
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu_env(mon);
@@ -21,3 +22,4 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
}
dump_mmu(env1);
}
+#endif
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 3e89dcaf7c6..da9975dd1b9 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -39,6 +39,8 @@
#define PTE_HEADER_DELIMITER "-------- ---------------- -------- -------\n"
#endif
+#ifdef CONFIG_HMP
+
/* Perform linear address sign extension */
static target_ulong addr_canonical(int va_bits, target_ulong addr)
{
@@ -244,6 +246,7 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
mem_info_svxx(mon, env);
}
+#endif /* CONFIG_HMP */
static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
target_ulong *val, bool is_gprh)
diff --git a/target/sh4/monitor.c b/target/sh4/monitor.c
index 50324d3600c..619d2678d0a 100644
--- a/target/sh4/monitor.c
+++ b/target/sh4/monitor.c
@@ -26,6 +26,7 @@
#include "monitor/monitor.h"
#include "monitor/hmp.h"
+#ifdef CONFIG_HMP
static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
{
monitor_printf(mon, " tlb%i:\t"
@@ -55,3 +56,4 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
for (i = 0 ; i < UTLB_SIZE ; i++)
print_tlb (mon, i, &env->utlb[i]);
}
+#endif
diff --git a/target/sparc/monitor.c b/target/sparc/monitor.c
index 36f3d8d58e9..ed7e3b4b8b2 100644
--- a/target/sparc/monitor.c
+++ b/target/sparc/monitor.c
@@ -27,6 +27,7 @@
#include "monitor/hmp.h"
+#ifdef CONFIG_HMP
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu_env(mon);
@@ -37,3 +38,4 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
}
dump_mmu(env1);
}
+#endif
diff --git a/target/xtensa/monitor.c b/target/xtensa/monitor.c
index 2af84934f83..3f8a93ed724 100644
--- a/target/xtensa/monitor.c
+++ b/target/xtensa/monitor.c
@@ -26,6 +26,7 @@
#include "monitor/monitor.h"
#include "monitor/hmp.h"
+#ifdef CONFIG_HMP
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
CPUArchState *env1 = mon_get_cpu_env(mon);
@@ -36,3 +37,4 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
}
dump_mmu(env1);
}
+#endif
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 35/39] target: guard MonitorDef tables with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (33 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 34/39] Guard HMP command implementations " Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 21:44 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 36/39] hw: guard BusClass::print_dev " Marc-André Lureau
` (4 subsequent siblings)
39 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Guard SysemuCPUOps::monitor_defs field and the per-target MonitorDef
arrays with CONFIG_HMP. These tables are only used by HMP 'print' and
'info registers' commands.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/hw/core/sysemu-cpu-ops.h | 2 ++
monitor/hmp.c | 4 +++-
target/i386/cpu.c | 4 ++++
target/m68k/cpu.c | 4 ++++
target/sparc/cpu.c | 5 +++--
5 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h
index 8be6a84bd54..09bb193e453 100644
--- a/include/hw/core/sysemu-cpu-ops.h
+++ b/include/hw/core/sysemu-cpu-ops.h
@@ -106,11 +106,13 @@ typedef struct SysemuCPUOps {
*/
int (*monitor_get_register)(CPUState *cs, const char *name, int64_t *pval);
+#ifdef CONFIG_HMP
/**
* @monitor_defs: Array of MonitorDef entries. This field is legacy,
* use @gdb_core_xml_file to dump registers instead.
*/
const MonitorDef *monitor_defs;
+#endif
/**
* @legacy_vmsd: Legacy state for migration.
diff --git a/monitor/hmp.c b/monitor/hmp.c
index de8804af51a..c9e207c7a30 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1610,13 +1610,15 @@ void monitor_register_hmp_info_hrt(const char *name,
static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
{
CPUState *cs = mon_get_cpu(mon);
- const MonitorDef *md;
+ const MonitorDef *md = NULL;
void *ptr;
if (cs == NULL) {
return -1;
}
+#ifdef CONFIG_HMP
md = cs->cc->sysemu_ops->monitor_defs;
+#endif
if (md == NULL) {
return -1;
}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8929a75c7c9..9fc7677735e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -10845,6 +10845,7 @@ static const Property x86_cpu_properties[] = {
#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_HMP
static int64_t monitor_get_pc(Monitor *mon, const struct MonitorDef *md,
int offset)
{
@@ -10870,6 +10871,7 @@ static const MonitorDef x86_monitor_defs[] = {
{ NULL },
#undef SEG
};
+#endif
#include "hw/core/sysemu-cpu-ops.h"
@@ -10884,7 +10886,9 @@ static const struct SysemuCPUOps i386_sysemu_ops = {
.write_elf64_note = x86_cpu_write_elf64_note,
.write_elf32_qemunote = x86_cpu_write_elf32_qemunote,
.write_elf64_qemunote = x86_cpu_write_elf64_qemunote,
+#ifdef CONFIG_HMP
.monitor_defs = x86_monitor_defs,
+#endif
.legacy_vmsd = &vmstate_x86_cpu,
};
#endif
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 9ad3057d91c..9955acb6c8d 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -603,6 +603,7 @@ static const VMStateDescription vmstate_m68k_cpu = {
},
};
+#ifdef CONFIG_HMP
static const MonitorDef m68k_monitor_defs[] = {
{ "ssp", offsetof(CPUM68KState, sp[0]) },
{ "usp", offsetof(CPUM68KState, sp[1]) },
@@ -618,13 +619,16 @@ static const MonitorDef m68k_monitor_defs[] = {
{ "mmusr", offsetof(CPUM68KState, mmu.mmusr) },
{ NULL },
};
+#endif
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps m68k_sysemu_ops = {
.has_work = m68k_cpu_has_work,
.get_phys_addr_debug = m68k_cpu_get_phys_addr_debug,
+#ifdef CONFIG_HMP
.monitor_defs = m68k_monitor_defs,
+#endif
};
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 13ebb122a38..51c720bdbc0 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -997,7 +997,7 @@ static const Property sparc_cpu_properties[] = {
#ifdef TARGET_SPARC64
#include "monitor/hmp.h"
-
+#ifdef CONFIG_HMP
static const MonitorDef sparc64_monitor_defs[] = {
{ "asi", offsetof(CPUSPARCState, asi) },
{ "pstate", offsetof(CPUSPARCState, pstate) },
@@ -1009,6 +1009,7 @@ static const MonitorDef sparc64_monitor_defs[] = {
{ NULL },
};
#endif
+#endif
#include "hw/core/sysemu-cpu-ops.h"
@@ -1016,7 +1017,7 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
.has_work = sparc_cpu_has_work,
.get_phys_addr_debug = sparc_cpu_get_phys_addr_debug,
.legacy_vmsd = &vmstate_sparc_cpu,
-#if defined(TARGET_SPARC64)
+#if defined(TARGET_SPARC64) && defined(CONFIG_HMP)
.monitor_defs = sparc64_monitor_defs,
#endif
};
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 36/39] hw: guard BusClass::print_dev with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (34 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 35/39] target: guard MonitorDef tables " Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 37/39] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
` (3 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
The print_dev callback is only used by HMP 'info qtree'. Guard the field
in BusClass, all implementations, and the caller with CONFIG_HMP.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/hw/core/qdev.h | 2 ++
hw/char/virtio-serial-bus.c | 6 ++++++
hw/core/sysbus.c | 6 ++++++
hw/misc/auxbus.c | 16 +++++++++++-----
hw/pci/pci-hmp-cmds.c | 2 ++
hw/pci/pci.c | 2 ++
hw/usb/bus.c | 6 ++++++
hw/xen/xen-bus.c | 4 ++++
8 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index e1476223411..22dd143acf0 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -322,8 +322,10 @@ DECLARE_OBJ_CHECKERS(BusState, BusClass,
struct BusClass {
ObjectClass parent_class;
+#ifdef CONFIG_HMP
/* FIXME first arg should be BusState */
void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
+#endif
/*
* Return a newly allocated string containing the path of the
* device on this bus.
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index cd234dc6db1..34a723a8715 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -833,7 +833,9 @@ static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
return 0;
}
+#ifdef CONFIG_HMP
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+#endif
static const Property virtser_props[] = {
DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
@@ -842,8 +844,10 @@ static const Property virtser_props[] = {
static void virtser_bus_class_init(ObjectClass *klass, const void *data)
{
+#ifdef CONFIG_HMP
BusClass *k = BUS_CLASS(klass);
k->print_dev = virtser_bus_dev_print;
+#endif
}
static const TypeInfo virtser_bus_info = {
@@ -853,6 +857,7 @@ static const TypeInfo virtser_bus_info = {
.class_init = virtser_bus_class_init,
};
+#ifdef CONFIG_HMP
static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
{
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev);
@@ -863,6 +868,7 @@ static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
port->host_connected ? "on" : "off",
port->throttled ? "on" : "off");
}
+#endif
/* This function is only used if a port id is not provided by the user */
static uint32_t find_free_port_id(VirtIOSerial *vser)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 3e1160ee921..0b970d6b64f 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -23,7 +23,9 @@
#include "monitor/monitor.h"
#include "system/address-spaces.h"
+#ifdef CONFIG_HMP
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
+#endif
static char *sysbus_get_fw_dev_path(DeviceState *dev);
typedef struct SysBusFind {
@@ -75,7 +77,9 @@ static void system_bus_class_init(ObjectClass *klass, const void *data)
{
BusClass *k = BUS_CLASS(klass);
+#ifdef CONFIG_HMP
k->print_dev = sysbus_dev_print;
+#endif
k->get_fw_dev_path = sysbus_get_fw_dev_path;
}
@@ -248,6 +252,7 @@ bool sysbus_realize_and_unref(SysBusDevice *dev, Error **errp)
return qdev_realize_and_unref(DEVICE(dev), sysbus_get_default(), errp);
}
+#ifdef CONFIG_HMP
static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
{
SysBusDevice *s = SYS_BUS_DEVICE(dev);
@@ -260,6 +265,7 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
indent, "", s->mmio[i].addr, size);
}
}
+#endif
static char *sysbus_get_fw_dev_path(DeviceState *dev)
{
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index 877f3456062..dd0629620ac 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -46,18 +46,22 @@
} while (0)
+#ifdef CONFIG_HMP
static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent);
+#endif
static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge);
/* aux-bus implementation (internal not public) */
static void aux_bus_class_init(ObjectClass *klass, const void *data)
{
+#ifdef CONFIG_HMP
BusClass *k = BUS_CLASS(klass);
/* AUXSlave has an MMIO so we need to change the way we print information
* in monitor.
*/
k->print_dev = aux_slave_dev_print;
+#endif
}
AUXBus *aux_bus_init(DeviceState *parent, const char *name)
@@ -90,11 +94,6 @@ void aux_map_slave(AUXSlave *aux_dev, hwaddr addr)
memory_region_add_subregion(bus->aux_io, addr, aux_dev->mmio);
}
-static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
-{
- return (dev == DEVICE(bus->bridge));
-}
-
I2CBus *aux_get_i2c_bus(AUXBus *bus)
{
return aux_bridge_get_i2c_bus(bus->bridge);
@@ -287,6 +286,12 @@ static const TypeInfo aux_to_i2c_type_info = {
};
/* aux-slave implementation */
+#ifdef CONFIG_HMP
+static bool aux_bus_is_bridge(AUXBus *bus, DeviceState *dev)
+{
+ return (dev == DEVICE(bus->bridge));
+}
+
static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
{
AUXBus *bus = AUX_BUS(qdev_get_parent_bus(dev));
@@ -304,6 +309,7 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent)
object_property_get_uint(OBJECT(s->mmio), "addr", NULL),
memory_region_size(s->mmio));
}
+#endif
void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio)
{
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index a5f6483cc3d..3e378eadfaa 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -134,6 +134,7 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
qapi_free_PciInfoList(info_list);
}
+#ifdef CONFIG_HMP
void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
{
PCIDevice *d = (PCIDevice *)dev;
@@ -169,6 +170,7 @@ void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
r->addr, r->addr + r->size - 1);
}
}
+#endif
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
{
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d3191609e28..9e5db952937 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -290,7 +290,9 @@ static void pci_bus_class_init(ObjectClass *klass, const void *data)
ResettableClass *rc = RESETTABLE_CLASS(klass);
FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(klass);
+#ifdef CONFIG_HMP
k->print_dev = pcibus_dev_print;
+#endif
k->get_dev_path = pcibus_get_dev_path;
k->get_fw_dev_path = pcibus_get_fw_dev_path;
k->realize = pci_bus_realize;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 3b6fbd46ac3..753f2d9be56 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -12,7 +12,9 @@
#include "trace.h"
#include "qemu/cutils.h"
+#ifdef CONFIG_HMP
static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
+#endif
static char *usb_get_dev_path(DeviceState *dev);
static char *usb_get_fw_dev_path(DeviceState *qdev);
@@ -31,7 +33,9 @@ static void usb_bus_class_init(ObjectClass *klass, const void *data)
BusClass *k = BUS_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
+#ifdef CONFIG_HMP
k->print_dev = usb_bus_dev_print;
+#endif
k->get_dev_path = usb_get_dev_path;
k->get_fw_dev_path = usb_get_fw_dev_path;
hc->unplug = qdev_simple_device_unplug_cb;
@@ -543,6 +547,7 @@ static const char *usb_speed(unsigned int speed)
return txt[speed];
}
+#ifdef CONFIG_HMP
static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
{
USBDevice *dev = USB_DEVICE(qdev);
@@ -554,6 +559,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
usb_speed(dev->speed), dev->product_desc,
dev->attached ? ", attached" : "");
}
+#endif
static char *usb_get_dev_path(DeviceState *qdev)
{
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index dfad2bc5085..439cd47e849 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -100,6 +100,7 @@ abort:
qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
}
+#ifdef CONFIG_HMP
static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
{
XenDevice *xendev = XEN_DEVICE(dev);
@@ -107,6 +108,7 @@ static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
indent, "", xendev->name, xendev->frontend_id);
}
+#endif
static char *xen_bus_get_dev_path(DeviceState *dev)
{
@@ -385,7 +387,9 @@ static void xen_bus_class_init(ObjectClass *class, const void *data)
BusClass *bus_class = BUS_CLASS(class);
HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
+#ifdef CONFIG_HMP
bus_class->print_dev = xen_bus_print_dev;
+#endif
bus_class->get_dev_path = xen_bus_get_dev_path;
bus_class->realize = xen_bus_realize;
bus_class->unrealize = xen_bus_unrealize;
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 37/39] build-sys: make HMP source files conditional on have_hmp
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (35 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 36/39] hw: guard BusClass::print_dev " Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 38/39] monitor: guard HMP internal helpers with CONFIG_HMP Marc-André Lureau
` (2 subsequent siblings)
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Exclude all *-hmp-cmds.c files and HMP-only source files from the
build when HMP is disabled.
Also conditionalise the hmp-commands.hx header generation and the
test-hmp qtest.
Drop the transient #ifdef CONFIG_HMP, no longer needed.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
meson.build | 2 +-
hw/pci/pci-hmp-cmds.c | 2 --
monitor/hmp.c | 2 --
audio/meson.build | 4 +++-
backends/meson.build | 5 ++++-
block/monitor/meson.build | 4 +++-
chardev/meson.build | 5 ++++-
disas/meson.build | 4 +++-
dump/meson.build | 5 ++++-
hw/core/meson.build | 5 +++--
hw/i386/meson.build | 4 +++-
hw/net/meson.build | 4 +++-
hw/pci/meson.build | 4 +++-
hw/virtio/meson.build | 4 +++-
migration/meson.build | 4 +++-
monitor/meson.build | 9 +++++++--
net/meson.build | 4 +++-
qom/meson.build | 4 +++-
stats/meson.build | 5 ++++-
stubs/meson.build | 12 +++++++-----
system/meson.build | 9 +++++++--
tests/qtest/meson.build | 8 +++++++-
trace/meson.build | 5 ++++-
ui/meson.build | 4 +++-
24 files changed, 85 insertions(+), 33 deletions(-)
diff --git a/meson.build b/meson.build
index 824ba695801..4b208a2c56e 100644
--- a/meson.build
+++ b/meson.build
@@ -3536,7 +3536,7 @@ hx_headers = [
['qemu-options.hx', 'qemu-options.def'],
['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
]
-if have_system
+if have_system and have_hmp
hx_headers += [
['hmp-commands.hx', 'hmp-commands.h'],
['hmp-commands-info.hx', 'hmp-commands-info.h'],
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index 3e378eadfaa..a5f6483cc3d 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -134,7 +134,6 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
qapi_free_PciInfoList(info_list);
}
-#ifdef CONFIG_HMP
void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
{
PCIDevice *d = (PCIDevice *)dev;
@@ -170,7 +169,6 @@ void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
r->addr, r->addr + r->size - 1);
}
}
-#endif
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict)
{
diff --git a/monitor/hmp.c b/monitor/hmp.c
index c9e207c7a30..4926972a3fb 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -1616,9 +1616,7 @@ static int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
if (cs == NULL) {
return -1;
}
-#ifdef CONFIG_HMP
md = cs->cc->sysemu_ops->monitor_defs;
-#endif
if (md == NULL) {
return -1;
}
diff --git a/audio/meson.build b/audio/meson.build
index 0e33b6f9836..6655f601b11 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -9,7 +9,9 @@ audio_ss.add(files(
))
# deprecated since v10.2, to be removed
-system_ss.add(files('audio-hmp-cmds.c', 'wavcapture.c'))
+if have_hmp
+ system_ss.add(files('audio-hmp-cmds.c', 'wavcapture.c'))
+endif
audio_modules = {}
foreach m : [
diff --git a/backends/meson.build b/backends/meson.build
index 60021f45d12..a59729f56fe 100644
--- a/backends/meson.build
+++ b/backends/meson.build
@@ -1,6 +1,5 @@
system_ss.add([files(
'cryptodev-builtin.c',
- 'cryptodev-hmp-cmds.c',
'cryptodev.c',
'hostmem-ram.c',
'hostmem.c',
@@ -10,6 +9,10 @@ system_ss.add([files(
'confidential-guest-support.c',
), numa])
+if have_hmp
+ system_ss.add(files('cryptodev-hmp-cmds.c'))
+endif
+
if host_os != 'windows'
system_ss.add(files('rng-random.c'))
if host_os != 'emscripten'
diff --git a/block/monitor/meson.build b/block/monitor/meson.build
index 74faced9e17..2d5c157a739 100644
--- a/block/monitor/meson.build
+++ b/block/monitor/meson.build
@@ -1,3 +1,5 @@
-system_ss.add(files('block-hmp-cmds.c'))
+if have_hmp
+ system_ss.add(files('block-hmp-cmds.c'))
+endif
block_ss.add(files('bitmap-qmp-cmds.c'))
system_ss.add(files('qmp-cmds.c'))
diff --git a/chardev/meson.build b/chardev/meson.build
index 56ee39ac0b0..031b6d7238c 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -30,11 +30,14 @@ endif
chardev_ss = chardev_ss.apply({})
system_ss.add(files(
- 'char-hmp-cmds.c',
'msmouse.c',
'wctablet.c',
'testdev.c'))
+if have_hmp
+ system_ss.add(files('char-hmp-cmds.c'))
+endif
+
chardev_modules = {}
if brlapi.found()
diff --git a/disas/meson.build b/disas/meson.build
index 42977a1f74d..b382550e41f 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -20,5 +20,7 @@ common_ss.add(when: 'CONFIG_TCG', if_true: files(
'objdump.c'
))
common_ss.add(files('disas-common.c'))
-system_ss.add(files('disas-mon.c'))
+if have_hmp
+ system_ss.add(files('disas-mon.c'))
+endif
specific_ss.add(capstone)
diff --git a/dump/meson.build b/dump/meson.build
index 26e1561ed48..bef8276aa5a 100644
--- a/dump/meson.build
+++ b/dump/meson.build
@@ -1,3 +1,6 @@
-system_ss.add([files('dump.c', 'dump-hmp-cmds.c'), snappy, lzo])
+system_ss.add([files('dump.c'), snappy, lzo])
+if have_hmp
+ system_ss.add(files('dump-hmp-cmds.c'))
+endif
specific_ss.add(when: 'CONFIG_WINDUMP', if_true: files('win_dump-x86.c'))
system_ss.add(when: 'CONFIG_WINDUMP', if_false: files('win_dump-stubs.c'))
diff --git a/hw/core/meson.build b/hw/core/meson.build
index 8a96567de8f..8fe776d2c86 100644
--- a/hw/core/meson.build
+++ b/hw/core/meson.build
@@ -26,13 +26,11 @@ system_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c'))
system_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c'))
system_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
system_ss.add(when: 'CONFIG_EIF', if_true: [files('eif.c'), zlib, libcbor, gnutls])
-
system_ss.add(files(
'cpu-system.c',
'fw-path-provider.c',
'hotplug.c',
'loader.c',
- 'machine-hmp-cmds.c',
'machine-qmp-cmds.c',
'machine.c',
'nmi.c',
@@ -46,6 +44,9 @@ system_ss.add(files(
'vm-change-state-handler.c',
'clock-vmstate.c',
))
+if have_hmp
+ system_ss.add(files('machine-hmp-cmds.c'))
+endif
user_ss.add(files(
'cpu-user.c',
'qdev-user.c',
diff --git a/hw/i386/meson.build b/hw/i386/meson.build
index b611fbb5a7f..125f4ce894c 100644
--- a/hw/i386/meson.build
+++ b/hw/i386/meson.build
@@ -24,7 +24,9 @@ i386_ss.add(when: 'CONFIG_VTD', if_true: files('intel_iommu.c'))
i386_ss.add(when: 'CONFIG_VTD_ACCEL', if_true: files('intel_iommu_accel.c'))
i386_ss.add(when: 'CONFIG_SGX', if_true: files('sgx-epc.c','sgx.c'),
if_false: files('sgx-stub.c'))
-stub_ss.add(files('sgx-hmp-stub.c'))
+if have_hmp
+ stub_ss.add(files('sgx-hmp-stub.c'))
+endif
i386_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-common.c'))
i386_ss.add(when: 'CONFIG_PC', if_true: files(
diff --git a/hw/net/meson.build b/hw/net/meson.build
index 84f142df222..df3373be03b 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -67,6 +67,8 @@ system_ss.add(when: 'CONFIG_ROCKER', if_true: files(
'rocker/rocker_world.c',
))
stub_ss.add(files('rocker/rocker-stubs.c'))
-system_ss.add(files('rocker/rocker-hmp-cmds.c'))
+if have_hmp
+ system_ss.add(files('rocker/rocker-hmp-cmds.c'))
+endif
subdir('can')
diff --git a/hw/pci/meson.build b/hw/pci/meson.build
index a6cbd89c0a3..984c7327e5d 100644
--- a/hw/pci/meson.build
+++ b/hw/pci/meson.build
@@ -5,12 +5,14 @@ pci_ss.add(files(
'pci.c',
'pci_bridge.c',
'pci_host.c',
- 'pci-hmp-cmds.c',
'pci-qmp-cmds.c',
'pcie_sriov.c',
'shpc.c',
'slotid_cap.c'
))
+if have_hmp
+ pci_ss.add(files('pci-hmp-cmds.c'))
+endif
# The functions in these modules can be used by devices too. Since we
# allow plugging PCIe devices into PCI buses, include them even if
# CONFIG_PCI_EXPRESS=n.
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 0e023235164..b59f455a511 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -100,6 +100,8 @@ stub_ss.add(files('vhost-user-stub.c'))
stub_ss.add(files('virtio-stub.c'))
stub_ss.add(files('virtio-md-stubs.c'))
-system_ss.add(files('virtio-hmp-cmds.c'))
+if have_hmp
+ system_ss.add(files('virtio-hmp-cmds.c'))
+endif
system_ss.add(when: 'CONFIG_ACPI', if_true: files('virtio-acpi.c'))
diff --git a/migration/meson.build b/migration/meson.build
index 0a9a5d0d374..4ab9d99cea6 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -36,7 +36,9 @@ system_ss.add(files(
'socket.c',
'tls.c',
), gnutls, zlib)
-system_ss.add([spice_headers, files('migration-hmp-cmds.c'), spice])
+if have_hmp
+ system_ss.add([spice_headers, files('migration-hmp-cmds.c'), spice])
+endif
if get_option('replication').allowed()
system_ss.add(files('colo-failover.c', 'colo.c', 'multifd-colo.c'))
diff --git a/monitor/meson.build b/monitor/meson.build
index 4c58dd148c0..f67e0291a42 100644
--- a/monitor/meson.build
+++ b/monitor/meson.build
@@ -2,8 +2,13 @@ qmp_ss.add(files('monitor.c', 'qmp.c', 'qmp-cmds-control.c'))
system_ss.add(files(
'fds.c',
- 'hmp-cmds.c',
- 'hmp.c',
'qemu-config-qmp.c',
'qmp-cmds.c',
))
+
+if have_hmp
+ system_ss.add(files(
+ 'hmp-cmds.c',
+ 'hmp.c',
+ ))
+endif
diff --git a/net/meson.build b/net/meson.build
index 9c8068b06d1..5bb76d13649 100644
--- a/net/meson.build
+++ b/net/meson.build
@@ -8,7 +8,6 @@ system_ss.add(files(
'filter-mirror.c',
'filter.c',
'hub.c',
- 'net-hmp-cmds.c',
'net.c',
'queue.c',
'socket.c',
@@ -16,6 +15,9 @@ system_ss.add(files(
'stream_data.c',
'util.c',
))
+if have_hmp
+ system_ss.add(files('net-hmp-cmds.c'))
+endif
if get_option('replication').allowed() or \
get_option('colo_proxy').allowed()
diff --git a/qom/meson.build b/qom/meson.build
index bd6f4aadd78..022d3ad5c8f 100644
--- a/qom/meson.build
+++ b/qom/meson.build
@@ -10,4 +10,6 @@ if have_system
endif
qmp_ss.add(files('qom-qmp-cmds.c'))
-system_ss.add(files('qom-hmp-cmds.c'))
+if have_hmp
+ system_ss.add(files('qom-hmp-cmds.c'))
+endif
diff --git a/stats/meson.build b/stats/meson.build
index 0728dafcd1c..b5f68a94052 100644
--- a/stats/meson.build
+++ b/stats/meson.build
@@ -1 +1,4 @@
-system_ss.add(files('stats-hmp-cmds.c', 'stats-qmp-cmds.c'))
+system_ss.add(files('stats-qmp-cmds.c'))
+if have_hmp
+ system_ss.add(files('stats-hmp-cmds.c'))
+endif
diff --git a/stubs/meson.build b/stubs/meson.build
index 3b2f2680b19..fe77107cc86 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -85,11 +85,13 @@ if have_system
stub_ss.add(files('qmp-cpu.c'))
stub_ss.add(files('qmp-cpu-s390x.c'))
stub_ss.add(files('qmp-cpu-s390x-kvm.c'))
- stub_ss.add(files('hmp-cmd-info_mem.c'))
- stub_ss.add(files('hmp-cmd-info_sev.c'))
- stub_ss.add(files('hmp-cmd-info_tlb.c'))
- stub_ss.add(files('hmp-cmds-hw-s390x.c'))
- stub_ss.add(files('hmp-cmds-target-i386.c'))
+ if have_hmp
+ stub_ss.add(files('hmp-cmd-info_mem.c'))
+ stub_ss.add(files('hmp-cmd-info_sev.c'))
+ stub_ss.add(files('hmp-cmd-info_tlb.c'))
+ stub_ss.add(files('hmp-cmds-hw-s390x.c'))
+ stub_ss.add(files('hmp-cmds-target-i386.c'))
+ endif
endif
if have_system or have_user
diff --git a/system/meson.build b/system/meson.build
index cd3193d170b..da4d4fe1f6c 100644
--- a/system/meson.build
+++ b/system/meson.build
@@ -22,12 +22,17 @@ system_ss.add(files(
'qtest.c',
'rtc.c',
'runstate-action.c',
- 'runstate-hmp-cmds.c',
'runstate.c',
- 'tpm-hmp-cmds.c',
'watchpoint.c',
))
+if have_hmp
+ system_ss.add(files(
+ 'runstate-hmp-cmds.c',
+ 'tpm-hmp-cmds.c',
+ ))
+endif
+
if have_tpm
system_ss.add(files('tpm.c'))
endif
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index e154abb05d2..c00a53b2bba 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -26,7 +26,13 @@ qtests_generic = [
'qmp-test',
'qmp-cmd-test',
'qom-test',
- 'test-hmp',
+]
+if have_hmp
+ qtests_generic += [
+ 'test-hmp',
+ ]
+endif
+qtests_generic += [
'qos-test',
'readconfig-test',
'netdev-socket',
diff --git a/trace/meson.build b/trace/meson.build
index d89a0db82a1..4e5681c44ca 100644
--- a/trace/meson.build
+++ b/trace/meson.build
@@ -1,4 +1,7 @@
-system_ss.add(files('control-target.c', 'trace-hmp-cmds.c'))
+system_ss.add(files('control-target.c'))
+if have_hmp
+ system_ss.add(files('trace-hmp-cmds.c'))
+endif
trace_rs_targets = []
trace_events_files = []
foreach item : [ '.' ] + trace_events_subdirs + qapi_trace_events
diff --git a/ui/meson.build b/ui/meson.build
index 0c6a432948c..433b3b9118c 100644
--- a/ui/meson.build
+++ b/ui/meson.build
@@ -55,10 +55,12 @@ system_ss.add(png)
system_ss.add(files(
'input-barrier.c',
'input.c',
- 'ui-hmp-cmds.c',
'ui-qmp-cmds.c',
'util.c',
))
+if have_hmp
+ system_ss.add(files('ui-hmp-cmds.c'))
+endif
system_ss.add(ui)
system_ss.add(when: pixman, if_true: files('console-vc.c'), if_false: files('console-vc-stubs.c'))
if dbus_display
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 38/39] monitor: guard HMP internal helpers with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (36 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 37/39] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 39/39] monitor: guard HMP monitor API " Marc-André Lureau
2026-08-10 21:49 ` [PATCH v2 00/39] Make HMP optional (and later standalone) Philippe Mathieu-Daudé
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Guard monitor_uses_readline() and monitor_is_hmp_non_interactive()
with CONFIG_HMP, providing a stub returning false when HMP is
disabled. Also guard the HMP code paths in monitor_accept_input()
and monitor_data_destroy() that reference MonitorHMP fields.
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
monitor/monitor.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 50f1fe77c33..c8207af57ec 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -116,6 +116,7 @@ bool monitor_cur_is_qmp(void)
return cur_mon && monitor_is_qmp(cur_mon);
}
+#ifdef CONFIG_HMP
/**
* Is @mon is using readline?
* Note: not all HMP monitors use readline, e.g., gdbserver has a
@@ -134,6 +135,12 @@ static inline bool monitor_is_hmp_non_interactive(const Monitor *mon)
return !monitor_uses_readline(container_of(mon, MonitorHMP, common));
}
+#else
+static inline bool monitor_is_hmp_non_interactive(const Monitor *mon)
+{
+ return false;
+}
+#endif
static gboolean monitor_unblocked(void *do_not_use, GIOCondition cond,
void *opaque)
@@ -540,6 +547,7 @@ static void monitor_accept_input(void *opaque)
{
Monitor *mon = opaque;
+#ifdef CONFIG_HMP
qemu_mutex_lock(&mon->mon_lock);
if (!monitor_is_qmp(mon)) {
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
@@ -555,6 +563,7 @@ static void monitor_accept_input(void *opaque)
} else {
qemu_mutex_unlock(&mon->mon_lock);
}
+#endif
qemu_chr_fe_accept_input(&mon->chr);
}
@@ -631,9 +640,11 @@ void monitor_data_destroy(Monitor *mon)
if (monitor_is_qmp(mon)) {
monitor_data_destroy_qmp(container_of(mon, MonitorQMP, common));
} else {
+#ifdef CONFIG_HMP
MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
readline_free(hmp_mon->rs);
g_free(hmp_mon->mon_cpu_path);
+#endif
}
g_string_free(mon->outbuf, true);
qemu_mutex_destroy(&mon->mon_lock);
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* [PATCH v2 39/39] monitor: guard HMP monitor API with CONFIG_HMP
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (37 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 38/39] monitor: guard HMP internal helpers with CONFIG_HMP Marc-André Lureau
@ 2026-06-25 21:19 ` Marc-André Lureau
2026-08-10 21:49 ` [PATCH v2 00/39] Make HMP optional (and later standalone) Philippe Mathieu-Daudé
39 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-06-25 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: Marc-André Lureau, Philippe Mathieu-Daudé,
Daniel P. Berrangé, Markus Armbruster
Now that all callers of HMP-specific monitor APIs have been guarded
by prior patches, wrap the public declarations and their definitions
with CONFIG_HMP:
- monitor.h: guard monitor_vprintf/printf/printc,
monitor_init_hmp, monitor_read_command/password, and
monitor_register_hmp*
- monitor.c: guard monitor_vprintf/printf/printc definitions
- stubs/monitor-core.c: guard monitor_vprintf stub
- stubs/monitor-internal.c: guard monitor_init_hmp stub
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
---
include/monitor/monitor.h | 11 +++++++++++
monitor/monitor.c | 2 ++
stubs/monitor-core.c | 2 ++
stubs/monitor-internal.c | 2 ++
4 files changed, 17 insertions(+)
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 17182e626a7..3457f4a7f88 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -20,7 +20,9 @@ bool monitor_cur_is_qmp(void);
void monitor_init_globals(void);
void monitor_init_globals_core(void);
void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp);
+#ifdef CONFIG_HMP
void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp);
+#endif
int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);
@@ -32,28 +34,37 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
int monitor_puts(Monitor *mon, const char *str);
+
+#ifdef CONFIG_HMP
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
G_GNUC_PRINTF(2, 0);
int monitor_printf(Monitor *mon, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
void monitor_printc(Monitor *mon, int ch);
+#endif
+
void monitor_flush(Monitor *mon);
int monitor_get_cpu_index(Monitor *mon);
int monitor_puts_locked(Monitor *mon, const char *str);
void monitor_flush_locked(Monitor *mon);
+
+#ifdef CONFIG_HMP
void monitor_read_command(MonitorHMP *mon, int show_prompt);
int monitor_read_password(MonitorHMP *mon, ReadLineFunc *readline_func,
void *opaque);
+#endif
AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
const char *opaque, Error **errp);
int monitor_fdset_dup_fd_add(int64_t fdset_id, int flags, Error **errp);
void monitor_fdset_dup_fd_remove(int dup_fd);
+#ifdef CONFIG_HMP
void monitor_register_hmp(const char *name, bool info,
void (*cmd)(Monitor *mon, const QDict *qdict));
void monitor_register_hmp_info_hrt(const char *name,
HumanReadableText *(*handler)(Error **errp));
+#endif
#endif /* MONITOR_H */
diff --git a/monitor/monitor.c b/monitor/monitor.c
index c8207af57ec..8ea1bafd99e 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -218,6 +218,7 @@ int monitor_puts(Monitor *mon, const char *str)
return monitor_puts_locked(mon, str);
}
+#ifdef CONFIG_HMP
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
char *buf;
@@ -274,6 +275,7 @@ void monitor_printc(Monitor *mon, int c)
}
monitor_printf(mon, "'");
}
+#endif
static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
/* Limit guest-triggerable events to 1 per second */
diff --git a/stubs/monitor-core.c b/stubs/monitor-core.c
index 078a5012e9b..b4a4de41aa2 100644
--- a/stubs/monitor-core.c
+++ b/stubs/monitor-core.c
@@ -21,6 +21,7 @@ void qapi_event_emit(QAPIEvent event, QDict *qdict)
{
}
+#ifdef CONFIG_HMP
int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
{
/*
@@ -37,3 +38,4 @@ int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
}
return -1;
}
+#endif
diff --git a/stubs/monitor-internal.c b/stubs/monitor-internal.c
index 4fece49d531..29274bd2b4a 100644
--- a/stubs/monitor-internal.c
+++ b/stubs/monitor-internal.c
@@ -8,6 +8,8 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
return -1;
}
+#ifdef CONFIG_HMP
void monitor_init_hmp(Chardev *chr, bool use_readline, Error **errp)
{
}
+#endif
--
2.54.0
^ permalink raw reply related [flat|nested] 79+ messages in thread
* Re: [PATCH v2 01/39] vl: fix -monitor none prefix matching
2026-06-25 21:19 ` [PATCH v2 01/39] vl: fix -monitor none prefix matching Marc-André Lureau
@ 2026-08-10 17:30 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:30 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:02AM +0400, Marc-André Lureau wrote:
> Use g_strcmp0() for exact match instead of strncmp() which would
> incorrectly treat any string starting with "none" as disabling
> the monitor.
>
> Fixes: 70e098af88f ("monitor: allow to disable the default monitor")
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> system/vl.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help
2026-06-25 21:19 ` [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
@ 2026-08-10 17:31 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:31 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:03AM +0400, Marc-André Lureau wrote:
> Fixes: 89aafcf2a793 ("trace: remove code that depends on setting vcpu")
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hmp-commands-info.hx | 6 +++---
> hmp-commands.hx | 7 +++----
> 2 files changed, 6 insertions(+), 7 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type
2026-06-25 21:19 ` [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type Marc-André Lureau
@ 2026-08-10 17:35 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:35 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:04AM +0400, Marc-André Lureau wrote:
> The `snapshot-file` argument for `snapshot_blkdev` is mandatory. Correct
> the `args_type` definition to reflect this.
>
> Fixes: 6106e2492fe ("qapi: Convert blockdev_snapshot_sync")
This seems to have been an intentional design choice, rather than a
bug. In hmp_snapshot_blkdev there is code with a comment:
if (!filename) {
/* In the future, if 'snapshot-file' is not specified, the snapshot
will be taken internally. Today it's actually required. */
error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
hmp_handle_error(mon, &errp);
return;
}
15 years on though, the future enhancement still hasn't arrived.
IMHO the original design choice was a mistake. We should have
been it mandatory at the start, since we had freedom to relax
that later.
So I'm in favour of your change, but it should update
hmp_snapshot_blkdev to remove what will now be dead
code checking for "!filename".
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hmp-commands.hx | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 2b658bbbf28..1e286b7c89d 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1168,7 +1168,7 @@ ERST
>
> {
> .name = "snapshot_blkdev",
> - .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
> + .args_type = "reuse:-n,device:B,snapshot-file:s,format:s?",
> .params = "[-n] device [new-image-file] [format]",
> .help = "initiates a live snapshot\n\t\t\t"
> "of device. If a new image file is specified, the\n\t\t\t"
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor
2026-06-25 21:19 ` [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
@ 2026-08-10 17:40 ` Daniel P. Berrangé
2026-08-11 7:56 ` Marc-André Lureau
0 siblings, 1 reply; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:40 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:05AM +0400, Marc-André Lureau wrote:
> Replace monitor_printf() error reporting with the standard **errp
> pattern. Drop the Monitor *mon parameter and return bool to indicate
> success, improving the function usage from non-HMP contexts. Update the
> KVM MCE injection path and hmp_mce() accordingly.
>
> Notes:
> - we may want to print the error in KVM path too
> - multiple error prints are now accumulated with error hints
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> target/i386/cpu.h | 4 ++--
> target/i386/helper.c | 49 ++++++++++++++++++++++++++++---------------------
> target/i386/kvm/kvm.c | 4 ++--
> target/i386/monitor.c | 6 ++++--
> 4 files changed, 36 insertions(+), 27 deletions(-)
> typedef struct MCEInjectionParams {
> - Monitor *mon;
> + GString *err;
Why not have "Error **errp"
> int bank;
> uint64_t status;
> uint64_t mcg_status;
> @@ -428,9 +428,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> * reporting is disabled
> */
> if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
> - monitor_printf(params->mon,
> - "CPU %d: Uncorrected error reporting disabled\n",
> - cs->cpu_index);
> + g_string_append_printf(params->err,
> + "CPU %d: Uncorrected error reporting disabled\n",
> + cs->cpu_index);
and use error_setg here and the other two places below.
> return;
> }
>
> @@ -439,10 +439,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> * reporting is disabled for the bank
> */
> if (banks[0] != ~(uint64_t)0) {
> - monitor_printf(params->mon,
> - "CPU %d: Uncorrected error reporting disabled for"
> - " bank %d\n",
> - cs->cpu_index, params->bank);
> + g_string_append_printf(params->err,
> + "CPU %d: Uncorrected error reporting disabled for bank %d\n",
> + cs->cpu_index, params->bank);
> return;
> }
>
> @@ -459,7 +458,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> if (need_reset) {
> emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
> recursive);
> - monitor_printf(params->mon, "%s", msg);
> + g_string_append_printf(params->err, "%s\n", msg);
> qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
> qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> return;
> @@ -488,14 +487,16 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
> }
>
> -void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> +bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
> uint64_t status, uint64_t mcg_status, uint64_t addr,
> - uint64_t misc, int flags)
> + uint64_t misc, int flags, Error **errp)
> {
> + ERRP_GUARD();
> CPUState *cs = CPU(cpu);
> CPUX86State *cenv = &cpu->env;
> + g_autoptr(GString) err = g_string_new(NULL);
> MCEInjectionParams params = {
> - .mon = mon,
> + .err = err,
This indirection via GString feels overkill when we could
use directly pass 'errp', given the ERRP_GUARD we have
> .bank = bank,
> .status = status,
> .mcg_status = mcg_status,
> @@ -506,21 +507,21 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> unsigned bank_num = cenv->mcg_cap & 0xff;
>
> if (!cenv->mcg_cap) {
> - monitor_printf(mon, "MCE injection not supported\n");
> - return;
> + error_setg(errp, "MCE injection not supported");
> + return false;
> }
> if (bank >= bank_num) {
> - monitor_printf(mon, "Invalid MCE bank number\n");
> - return;
> + error_setg(errp, "Invalid MCE bank number");
> + return false;
> }
> if (!(status & MCI_STATUS_VAL)) {
> - monitor_printf(mon, "Invalid MCE status code\n");
> - return;
> + error_setg(errp, "Invalid MCE status code");
> + return false;
> }
> if ((flags & MCE_INJECT_BROADCAST)
> && !cpu_x86_support_mca_broadcast(cenv)) {
> - monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
> - return;
> + error_setg(errp, "Guest CPU does not support MCA broadcast");
> + return false;
> }
>
> run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
> @@ -539,6 +540,12 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
> }
> }
> + if (params.err->len) {
> + error_setg(errp, "Failed to inject MCE");
> + error_append_hint(errp, "%s", params.err->str);
> + return false;
> + }
This could be just
if (*params.errp) {
return false;
}
> + return true;
> }
>
> static inline target_ulong get_memio_eip(CPUX86State *env)
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce()
2026-06-25 21:19 ` [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
@ 2026-08-10 17:42 ` Daniel P. Berrangé
2026-08-10 20:16 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:42 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:06AM +0400, Marc-André Lureau wrote:
> Rather than silently doing nothing.
>
> Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> target/i386/monitor.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 06/39] system: move gpa2hva() to system memory unit
2026-06-25 21:19 ` [PATCH v2 06/39] system: move gpa2hva() to system memory unit Marc-André Lureau
@ 2026-08-10 17:44 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:44 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:07AM +0400, Marc-André Lureau wrote:
> The function is now used by SEV code path. Move it to physmem.c rather
> than hmp-cmds.c.
Fun, a nice example of why we would benefit from a clear separation
of HMP and internal code.
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/monitor/monitor.h | 2 --
> include/system/memory.h | 2 ++
> monitor/hmp-cmds.c | 31 -------------------------------
> system/physmem.c | 31 +++++++++++++++++++++++++++++++
> 4 files changed, 33 insertions(+), 33 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 07/39] s390x: prevent crash if given invalid CPU#
2026-06-25 21:19 ` [PATCH v2 07/39] s390x: prevent crash if given invalid CPU# Marc-André Lureau
@ 2026-08-10 17:44 ` Daniel P. Berrangé
2026-08-10 21:01 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:44 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster,
Eric Farman
On Fri, Jun 26, 2026 at 01:19:08AM +0400, Marc-André Lureau wrote:
> Reviewed-by: Eric Farman <farman@linux.ibm.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hw/s390x/s390-virtio-ccw.c | 5 +++++
> 1 file changed, 5 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor
2026-06-25 21:19 ` [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
@ 2026-08-10 17:48 ` Daniel P. Berrangé
2026-08-11 8:18 ` Marc-André Lureau
0 siblings, 1 reply; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:48 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:09AM +0400, Marc-André Lureau wrote:
> Use first_cpu directly instead of going through monitor_get_cpu_index(),
> as this is HMP-territory. QMP doesn't have a `cpu` command, we should
> add arguments instead when needed.
>
> Update the inject-nmi doc to accurately describe per-architecture NMI
> delivery.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/machine.json | 5 +++--
> system/cpus.c | 7 +++++--
> 2 files changed, 8 insertions(+), 4 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 685e4e29b87..03461f5f723 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -432,8 +432,9 @@
> ##
> # @inject-nmi:
> #
> -# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
> -# all CPUs (ppc64). The command fails when the guest doesn't support
> +# Injects a Non-Maskable Interrupt into the virtual machine. The NMI
> +# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
> +# (s390). The command fails when the guest doesn't support
> # injecting.
> #
> # Since: 0.14
> diff --git a/system/cpus.c b/system/cpus.c
> index 49f6daec3cd..6e3ef0afeca 100644
> --- a/system/cpus.c
> +++ b/system/cpus.c
> @@ -915,6 +915,9 @@ exit:
>
> void qmp_inject_nmi(Error **errp)
> {
> - nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
> + int cpu_index = UNASSIGNED_CPU_INDEX;
> + if (first_cpu) {
> + cpu_index = first_cpu->cpu_index;
> + }
I'm wondering how this "if" logic turns into the behaviour documented
for x86/hppa/pc64 vs s390 ? Don't all those arches have 'first_cpu'
defined, such that this changes semantics to 'first vCPU' instead of
'all vCPUs' ?
> + nmi_monitor_handle(cpu_index, errp);
> }
> -
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 09/39] hmp: correct the nmi documentation
2026-06-25 21:19 ` [PATCH v2 09/39] hmp: correct the nmi documentation Marc-André Lureau
@ 2026-08-10 17:51 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:51 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:10AM +0400, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hmp-commands.hx | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 1e286b7c89d..129052963c7 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -868,8 +868,9 @@ ERST
> .cmd = hmp_nmi,
> },
> SRST
> -``nmi`` *cpu*
> - Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
> +``nmi``
> + Inject an NMI on the associated monitor vCPU (``cpu`` command, on s390x) or
> + all vCPUs (on other architectures).
For consistency with QMP shouldn't this say
Inject an NMI on the associated monitor vCPU (``cpu`` command, on s390x) or
all vCPUs (x86, hppa, ppc64), or does nothing on other architectures
?
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP
2026-06-25 21:19 ` [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
@ 2026-08-10 17:54 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:54 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:11AM +0400, Marc-André Lureau wrote:
> mon_cpu_path and reset_seen are only used by HMP monitors; move them
> from the base Monitor struct into MonitorHMP to properly encapsulate
> HMP-specific state.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> monitor/monitor-internal.h | 4 ++--
> monitor/hmp-cmds.c | 17 ++++++++++-------
> monitor/hmp.c | 5 +++--
> monitor/monitor.c | 16 +++++++++++-----
> 4 files changed, 26 insertions(+), 16 deletions(-)
> void monitor_data_destroy(Monitor *mon)
> {
> - g_free(mon->mon_cpu_path);
> qemu_chr_fe_deinit(&mon->chr, false);
> if (monitor_is_qmp(mon)) {
> monitor_data_destroy_qmp(container_of(mon, MonitorQMP, common));
> } else {
> - readline_free(container_of(mon, MonitorHMP, common)->rs);
> + MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
> + readline_free(hmp_mon->rs);
> + g_free(hmp_mon->mon_cpu_path);
> }
This will clash with my now merged series that turned monitors
into QOM classes.
A new patch will need to move the g_free out of monitor_finalize
and into monitor_hmp_finalize.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP
2026-06-25 21:19 ` [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
@ 2026-08-10 17:54 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:54 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:12AM +0400, Marc-André Lureau wrote:
> Replace the human-monitor-command based version test with the native
> QMP query-version command, which returns structured version data.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/functional/generic/test_version.py | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 12/39] net/qapi: add x-query-usernet command
2026-06-25 21:19 ` [PATCH v2 12/39] net/qapi: add x-query-usernet command Marc-André Lureau
@ 2026-08-10 17:56 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 17:56 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:13AM +0400, Marc-André Lureau wrote:
> Add a QMP command to query user-mode network stack (slirp) connection
> states, providing a structured alternative to "info usernet" HMP.
>
> The new command returns a list of UsernetInfo, with hub-id, hub-name,
> and connection info for each slirp stack. It is marked unstable as it
> is meant for debugging.
>
> Rewrite hmp_info_usernet() as a thin wrapper over qmp_x_query_usernet()
> so the HMP and QMP paths share the same implementation.
>
> This is part of the effort to decouple HMP from QEMU core.
>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/net.json | 44 ++++++++++++++++++++++++++++++++++++++++++++
> net/slirp.c | 34 ++++++++++++++++++++++++++++------
> 2 files changed, 72 insertions(+), 6 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
> diff --git a/qapi/net.json b/qapi/net.json
> index 1a6382825c5..08ec7f37946 100644
> --- a/qapi/net.json
> +++ b/qapi/net.json
> @@ -1261,3 +1261,47 @@
> ##
> { 'event': 'NETDEV_VHOST_USER_DISCONNECTED',
> 'data': { 'netdev-id': 'str' } }
> +
> +##
> +# @UsernetInfo:
> +#
> +# Information about a user-mode network stack (slirp).
> +#
> +# @hub-id: The hub id, if available.
> +#
> +# @hub-name: The name of the hub.
> +#
> +# @info: Network information from slirp.
> +#
> +# Since: 11.1
s/11.1/11.2/ when you rebase here and the next
comment.
> +##
> +{ 'struct': 'UsernetInfo',
> + 'data': {
> + '*hub-id': 'int',
> + 'hub-name': 'str',
> + 'info': 'str' },
> + 'if': 'CONFIG_SLIRP' }
> +
> +##
> +# @x-query-usernet:
> +#
> +# Query user-mode network stack connection states.
> +#
> +# Features:
> +#
> +# @unstable: This command is meant for debugging.
> +#
> +# Returns: list of user-mode network stack information.
> +#
> +# Since: 11.1
> +#
> +# .. qmp-example::
> +#
> +# -> { "execute": "x-query-usernet" }
> +# <- { "return": [ { "hub-id": 0, "hub-name": "vnet",
> +# "info": "..." } ] }
> +##
> +{ 'command': 'x-query-usernet',
> + 'returns': ['UsernetInfo'],
> + 'if': 'CONFIG_SLIRP',
> + 'features': [ 'unstable' ] }
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP
2026-06-25 21:19 ` [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
@ 2026-08-10 18:00 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:00 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:14AM +0400, Marc-André Lureau wrote:
> Replace human-monitor-command "info usernet" calls with the structured
> x-query-usernet QMP command in get_usernet_hostfwd_port() and the VM
> test runner boot path.
>
> Since x-query-usernet returns a list of UsernetInfo entries, callers
> now iterate over the result and extract the port from each entry's
> "info" field. Also switch get_info_usernet_hostfwd_port() from
> split('\r\n') to splitlines(), since QMP strings use \n rather than
> the HMP monitor's \r\n line endings.
>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
> python/qemu/utils/__init__.py | 5 +++--
> tests/functional/qemu_test/utils.py | 8 ++++++--
> tests/vm/basevm.py | 13 ++++++++-----
> 3 files changed, 17 insertions(+), 9 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
> diff --git a/python/qemu/utils/__init__.py b/python/qemu/utils/__init__.py
> index be5daa83634..e32911d4c6d 100644
> --- a/python/qemu/utils/__init__.py
> +++ b/python/qemu/utils/__init__.py
> @@ -46,10 +46,11 @@ def get_info_usernet_hostfwd_port(info_usernet_output: str) -> Optional[int]:
> """
> Returns the port given to the hostfwd parameter via info usernet
>
> - :param info_usernet_output: output generated by hmp command "info usernet"
> + :param info_usernet_output: output generated by "info usernet" or
> + the "info" field from x-query-usernet
> :return: the port number allocated by the hostfwd option
> """
> - for line in info_usernet_output.split('\r\n'):
> + for line in info_usernet_output.splitlines():
> regex = r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.'
> match = re.search(regex, line)
> if match is not None:
> diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py
> index 826c267785b..0992db49ab2 100644
> --- a/tests/functional/qemu_test/utils.py
> +++ b/tests/functional/qemu_test/utils.py
> @@ -14,8 +14,12 @@
>
>
> def get_usernet_hostfwd_port(vm):
> - res = vm.cmd('human-monitor-command', command_line='info usernet')
> - return get_info_usernet_hostfwd_port(res)
> + res = vm.cmd('x-query-usernet')
I think there's an error handling behaviour difference here.
HMP has no concept of errors, just stuffing messages onto stderr.
So in !CONFIG_SLIRP scenarios this "info usernet" command
probably didn't return an error that this code would detect.
I think get_info_usernet_hostfwd_port() simply wouldn't
find a port number.
x-query-usernet by contrast will have clear error handling,
so should raise an exception in !CONFIG_SLIRP scenarios
which will break callers of this method I expect
> + for entry in res:
> + port = get_info_usernet_hostfwd_port(entry['info'])
> + if port is not None:
> + return port
> + return None
>
> def pow2ceil(x):
> """
> diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
> index 9e879e966a3..198b04e8c37 100644
> --- a/tests/vm/basevm.py
> +++ b/tests/vm/basevm.py
> @@ -312,12 +312,15 @@ def boot(self, img, extra_args=[]):
> self._guest = guest
> # Init console so we can start consuming the chars.
> self.console_init()
> - usernet_info = guest.cmd("human-monitor-command",
> - command_line="info usernet")
> - self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
> + res = guest.cmd("x-query-usernet")
Same concern here about likely breaking in !CONFIG_SLIRP
scenarios
> + for entry in res:
> + port = get_info_usernet_hostfwd_port(entry['info'])
> + if port is not None:
> + self.ssh_port = port
> + break
> if not self.ssh_port:
> - raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
> - usernet_info)
> + raise Exception("Cannot find ssh port from"
> + " 'x-query-usernet': %s" % res)
>
> def console_init(self, timeout = None):
> if timeout == None:
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio
2026-06-25 21:19 ` [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
@ 2026-08-10 18:01 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:01 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:15AM +0400, Marc-André Lureau wrote:
> The pnv-xive2-test and pnv-host-i2c-test pass "-serial mon:stdio"
> but never use HMP commands. The "mon:" chardev prefix creates an
> HMP monitor mux, which fails when HMP is disabled. Other pnv tests
> (e.g. pnv-spi-seeprom-test) don't specify -serial at all.
>
> Drop the unnecessary -serial mon:stdio option.
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/pnv-host-i2c-test.c | 2 +-
> tests/qtest/pnv-xive2-test.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command
2026-06-25 21:19 ` [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
@ 2026-08-10 18:03 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:03 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:16AM +0400, Marc-André Lureau wrote:
> The test was using 'human-monitor-command' (which requires HMP) to
> verify that an integer 'id' is echoed back on failure. Replace with
> 'query-name' for the success case and 'block_resize' (missing
> required args) for the failure case, so the test works regardless of
> HMP availability.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/qmp-test.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast
2026-06-25 21:19 ` [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
@ 2026-08-10 18:04 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:04 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:17AM +0400, Marc-André Lureau wrote:
> Convert the three test functions that relied on HMP "info numa" to use
> QMP "query-cpus-fast" instead, verifying each CPU's node-id through the
> structured response. Add a check_cpu_node() helper for the per-CPU
> assertions.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/numa-test.c | 63 +++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 51 insertions(+), 12 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block
2026-06-25 21:19 ` [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
@ 2026-08-10 18:05 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:05 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:18AM +0400, Marc-André Lureau wrote:
> The test_cdrom_param() function uses qtest_hmp() to run "info block",
> which depends on the human-monitor-command QMP endpoint. Replace it
> with the QMP query-block command so the test works when HMP is
> disabled (-Dhmp=disabled).
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/cdrom-test.c | 29 ++++++++++++++++++++++++-----
> 1 file changed, 24 insertions(+), 5 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound
2026-06-25 21:19 ` [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
@ 2026-08-10 18:15 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:15 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:20AM +0400, Marc-André Lureau wrote:
> After nbd-server-remove with mode=hard and an active client, the
> export is removed from the NBD export list synchronously but remains
> in the block export list until async cleanup completes (via
> blk_exp_delete_bh bottom-half). A subsequent nbd-server-remove call
> may find the export still in the block list with user_owned=false,
> returning "already shutting down" instead of "not found".
>
> Accept both error messages in assertExportNotFound, since both
> indicate the export is no longer usable.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qemu-iotests/205 | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf
2026-06-25 21:19 ` [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
@ 2026-08-10 18:19 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:19 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:23AM +0400, Marc-André Lureau wrote:
> Convert the qemu-io command infrastructure to use QEMU's Error API
> (Error **errp) for error propagation instead of printing directly to
> stdout/stderr via printf/fprintf.
>
> The cfunc_t typedef, all ~35 command functions, the dispatcher chain
> (command/init_check_command/qemuio_command), and helper functions
> (parse_pattern, create_iovec, qemu_io_alloc_from_file) all gain an
> Error **errp parameter. Async completion callbacks (aio_read_done,
> aio_write_done, aio_discard_done) use error_report() since they have
> no Error path back to the caller.
>
> Update tests:
> - error_report_err() prepends qemu-io: prefix
> - copy-before-write: check the HMP return value, rather than stdio
> - other tests: update to check JSON {"return": "Error: error text"}
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qemu-io.h | 4 +-
> block/monitor/block-hmp-cmds.c | 2 +-
> qemu-io-cmds.c | 414 +++++++++++++------------
> qemu-io.c | 17 +-
> tests/qemu-iotests/004.out | 20 +-
> tests/qemu-iotests/021.out | 60 ++--
> tests/qemu-iotests/026.out | 228 +++++++-------
> tests/qemu-iotests/060.out | 44 ++-
> tests/qemu-iotests/071.out | 10 +-
> tests/qemu-iotests/072.out | 2 +-
> tests/qemu-iotests/080.out | 4 +-
> tests/qemu-iotests/081.out | 2 +-
> tests/qemu-iotests/083.out | 36 +--
> tests/qemu-iotests/089.out | 4 +-
> tests/qemu-iotests/114.out | 2 +-
> tests/qemu-iotests/134.out | 2 +-
> tests/qemu-iotests/137.out | 2 +-
> tests/qemu-iotests/153.out | 12 +-
> tests/qemu-iotests/171 | 2 +-
> tests/qemu-iotests/171.out | 68 ++--
> tests/qemu-iotests/205 | 2 +-
> tests/qemu-iotests/214.out | 2 +-
> tests/qemu-iotests/220.out | 2 +-
> tests/qemu-iotests/225.out | 4 +-
> tests/qemu-iotests/244.out | 12 +-
> tests/qemu-iotests/249.out | 6 +-
> tests/qemu-iotests/271.out | 14 +-
> tests/qemu-iotests/289.out | 2 +-
> tests/qemu-iotests/305.out | 2 +-
> tests/qemu-iotests/307.out | 2 +-
> tests/qemu-iotests/tests/backup-discard-source | 4 +-
> tests/qemu-iotests/tests/copy-before-write | 66 ++--
> tests/qemu-iotests/tests/file-io-error.out | 2 +-
> tests/qemu-iotests/tests/image-fleecing.out | 12 +-
> tests/qemu-iotests/tests/inactive-node-nbd.out | 8 +-
> 35 files changed, 552 insertions(+), 523 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol
2026-06-25 21:19 ` [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol Marc-André Lureau
@ 2026-08-10 18:22 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:22 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:24AM +0400, Marc-André Lureau wrote:
> Add a "qemu-io" command to the qtest protocol so that tests can issue
> block layer I/O commands without going through the HMP monitor's
> "human-monitor-command" QMP, or use QMP at all.
>
> Unfortunately, many tests will prefer to use QMP as they also monitor
> and log other events. It's easier if it is pipelined in the same stream.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/libqtest.h | 11 +++++++++++
> system/qtest.c | 14 ++++++++++++++
> tests/qtest/libqtest.c | 14 ++++++++++++++
> 3 files changed, 39 insertions(+)
>
> diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
> index 45217fb8dc0..58491ca53ab 100644
> --- a/tests/qtest/libqtest.h
> +++ b/tests/qtest/libqtest.h
> @@ -424,6 +424,17 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
> char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
> G_GNUC_PRINTF(2, 0);
>
> +/**
> + * qtest_qemu_io:
> + * @s: #QTestState instance to operate on.
> + * @device: block device node-name or BlockBackend name.
> + * @fmt: qemu-io command to send, formats arguments like sprintf().
> + *
> + * Send a qemu-io command via the qtest protocol.
> + */
> +void qtest_qemu_io(QTestState *s, const char *device,
> + const char *fmt, ...) G_GNUC_PRINTF(3, 4);
> +
> void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
>
> /**
> diff --git a/system/qtest.c b/system/qtest.c
> index fd37bcbfaab..f7f2636854b 100644
> --- a/system/qtest.c
> +++ b/system/qtest.c
> @@ -33,6 +33,7 @@
> #include "qom/object_interfaces.h"
> #include "qom/qom-qobject.h"
> #include "qobject/qobject.h"
> +#include "qapi-commands-block.h"
>
> #define MAX_IRQ 256
>
> @@ -800,6 +801,19 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
> }
> g_slist_free(list);
> qtest_send(chr, "OK\n");
> + } else if (strcmp(words[0], "qemu-io") == 0) {
> + const char *io_dev;
> + g_autofree char *io_cmd = NULL;
> + Error *err = NULL;
> +
> + g_assert(words[1] && words[2]);
> + io_dev = words[1];
> + io_cmd = g_strjoinv(" ", &words[2]);
> +
> + qmp_x_qemu_io(io_dev, NULL, io_cmd, &err);
This function isn't defined until patch 25 AFAICT, so need to re-order.
> + qtest_sendf(chr, err ? "FAIL %s\n" : "OK\n",
> + err ? error_get_pretty(err) : NULL);
> + error_free(err);
> } else if (process_command_cb && process_command_cb(chr, words)) {
> /* Command got consumed by the callback handler */
> } else {
> diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
> index 4e22c66b754..eccffd3a0c2 100644
> --- a/tests/qtest/libqtest.c
> +++ b/tests/qtest/libqtest.c
> @@ -1012,6 +1012,20 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
> return ret;
> }
>
> +void qtest_qemu_io(QTestState *s, const char *device,
> + const char *fmt, ...)
> +{
> + va_list ap;
> + g_autofree char *cmd = NULL;
> +
> + va_start(ap, fmt);
> + cmd = g_strdup_vprintf(fmt, ap);
> + va_end(ap);
> +
> + qtest_sendf(s, "qemu-io %s %s\n", device, cmd);
> + qtest_rsp(s);
> +}
> +
> const char *qtest_get_arch(void)
> {
> /*
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command
2026-06-25 21:19 ` [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
@ 2026-08-10 18:22 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:22 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:25AM +0400, Marc-André Lureau wrote:
> Depend on the previous commit to be accepted.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/ide-test.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io()
2026-06-25 21:19 ` [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
@ 2026-08-10 18:24 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:24 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:27AM +0400, Marc-André Lureau wrote:
> Add qmp_qemu_io() method as a QMP counterpart to hmp_qemu_io(),
> using the x-qemu-io QMP command instead of human-monitor-command.
> The x-qemu-io command takes separate 'device' (or 'qdev') and
> 'command' arguments, and returns the error string.
>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qemu-iotests/iotests.py | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 25/39] block: add x-qemu-io QMP command
2026-06-25 21:19 ` [PATCH v2 25/39] block: add x-qemu-io QMP command Marc-André Lureau
@ 2026-08-10 18:26 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:26 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:26AM +0400, Marc-André Lureau wrote:
> Add an x-qemu-io QMP command that runs qemu-io commands on block
> devices. The command accepts a device name (block backend name,
> node-name, or qdev ID) and a qemu-io command string.
>
> Refactor hmp_qemu_io() to be a thin wrapper around the new QMP
> command, following the standard HMP-over-QMP pattern used by other
> block commands.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/block.json | 34 ++++++++++++++++++
> block/monitor/block-hmp-cmds.c | 60 ++------------------------------
> block/monitor/qmp-cmds.c | 79 ++++++++++++++++++++++++++++++++++++++++++
> block/monitor/meson.build | 1 +
> 4 files changed, 117 insertions(+), 57 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP
2026-06-25 21:19 ` [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
@ 2026-08-10 18:26 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:26 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:28AM +0400, Marc-André Lureau wrote:
> Convert pause_drive() and resume_drive() to use x-qemu-io directly
> instead of routing through hmp().
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qemu-iotests/iotests.py | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 28/39] build-sys: add 'hmp' option
2026-06-25 21:19 ` [PATCH v2 28/39] build-sys: add 'hmp' option Marc-André Lureau
@ 2026-08-10 18:27 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:27 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:29AM +0400, Marc-André Lureau wrote:
> Add an option to enable/disable HMP support, default to true. The
> following commits are going to make --disable-hmp gradually working.
s/working/work/
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> meson.build | 4 ++++
> meson_options.txt | 2 ++
> scripts/meson-buildoptions.sh | 3 +++
> 3 files changed, 9 insertions(+)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled
2026-06-25 21:19 ` [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
@ 2026-08-10 18:28 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:28 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:30AM +0400, Marc-André Lureau wrote:
> When QEMU is built without HMP support, reject '-monitor' (which
> requests readline/HMP mode) early in monitor_init_opts() with a
> clear error message directing users to '-qmp' instead.
>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
> monitor/monitor.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
This will need rewriting from scratch as the code all changed
with the introduction of QOM classes for monitors
>
> diff --git a/monitor/monitor.c b/monitor/monitor.c
> index 2dec0e299af..f443f406b4c 100644
> --- a/monitor/monitor.c
> +++ b/monitor/monitor.c
> @@ -764,6 +764,16 @@ int monitor_init_opts(QemuOpts *opts, Error **errp)
> MonitorOptions *options;
> int ret;
>
> +#ifndef CONFIG_HMP
> + const char *mode = qemu_opt_get(opts, "mode");
> + /* readline is HMP.. */
> + if (mode && g_str_equal(mode, "readline")) {
> + error_setg(errp, "HMP monitor is not available,"
> + " use '-qmp' instead of '-monitor'");
> + return -1;
> + }
> +#endif
> +
> v = opts_visitor_new(opts);
> visit_type_MonitorOptions(v, NULL, &options, errp);
> visit_free(v);
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 30/39] tests: skip HMP-dependent tests when HMP is disabled
2026-06-25 21:19 ` [PATCH v2 30/39] tests: skip HMP-dependent tests " Marc-André Lureau
@ 2026-08-10 18:29 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:29 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:31AM +0400, Marc-André Lureau wrote:
> Add runtime detection of HMP availability so tests gracefully skip
> instead of failing when QEMU is built without HMP support.
>
> For qtests (drive_del-test), use compile-time #ifndef CONFIG_HMP guards.
>
> For bash iotests, add _require_hmp() to common.rc that probes QEMU.
>
> For Python iotests, add _verify_hmp() and a require_hmp parameter
> threaded through execute_setup_common()/main()/script_initialize()/
> script_main().
>
> An earlier version of this series did an almost-complete conversion of
> the tests to QMP. However, this made the series even longer. I decided
> to post-pone it for now.
Makese sense as a tradeoff.
>
> Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qtest/drive_del-test.c | 25 ++++++++++++++++++++++
> tests/qemu-iotests/028 | 1 +
> tests/qemu-iotests/045 | 3 ++-
> tests/qemu-iotests/051 | 1 +
> tests/qemu-iotests/056 | 3 ++-
> tests/qemu-iotests/060 | 1 +
> tests/qemu-iotests/068 | 1 +
> tests/qemu-iotests/071 | 1 +
> tests/qemu-iotests/081 | 1 +
> tests/qemu-iotests/091 | 1 +
> tests/qemu-iotests/093 | 3 ++-
> tests/qemu-iotests/102 | 1 +
> tests/qemu-iotests/117 | 1 +
> tests/qemu-iotests/119 | 1 +
> tests/qemu-iotests/120 | 1 +
> tests/qemu-iotests/124 | 3 ++-
> tests/qemu-iotests/130 | 1 +
> tests/qemu-iotests/132 | 3 ++-
> tests/qemu-iotests/136 | 3 ++-
> tests/qemu-iotests/142 | 1 +
> tests/qemu-iotests/145 | 1 +
> tests/qemu-iotests/146 | 1 +
> tests/qemu-iotests/148 | 3 ++-
> tests/qemu-iotests/151 | 3 ++-
> tests/qemu-iotests/152 | 3 ++-
> tests/qemu-iotests/153 | 1 +
> tests/qemu-iotests/156 | 1 +
> tests/qemu-iotests/157 | 1 +
> tests/qemu-iotests/161 | 1 +
> tests/qemu-iotests/165 | 3 ++-
> tests/qemu-iotests/172 | 1 +
> tests/qemu-iotests/181 | 1 +
> tests/qemu-iotests/185 | 1 +
> tests/qemu-iotests/186 | 1 +
> tests/qemu-iotests/192 | 1 +
> tests/qemu-iotests/201 | 1 +
> tests/qemu-iotests/216 | 3 ++-
> tests/qemu-iotests/225 | 1 +
> tests/qemu-iotests/232 | 1 +
> tests/qemu-iotests/236 | 3 ++-
> tests/qemu-iotests/245 | 3 ++-
> tests/qemu-iotests/246 | 3 ++-
> tests/qemu-iotests/249 | 1 +
> tests/qemu-iotests/254 | 3 ++-
> tests/qemu-iotests/255 | 3 ++-
> tests/qemu-iotests/257 | 3 ++-
> tests/qemu-iotests/260 | 3 ++-
> tests/qemu-iotests/264 | 3 ++-
> tests/qemu-iotests/267 | 1 +
> tests/qemu-iotests/274 | 3 ++-
> tests/qemu-iotests/280 | 1 +
> tests/qemu-iotests/281 | 3 ++-
> tests/qemu-iotests/283 | 1 +
> tests/qemu-iotests/286 | 1 +
> tests/qemu-iotests/298 | 3 ++-
> tests/qemu-iotests/300 | 3 ++-
> tests/qemu-iotests/304 | 3 ++-
> tests/qemu-iotests/310 | 3 ++-
> tests/qemu-iotests/common.rc | 8 +++++++
> tests/qemu-iotests/iotests.py | 14 +++++++++++-
> tests/qemu-iotests/tests/backup-discard-source | 3 ++-
> tests/qemu-iotests/tests/copy-before-write | 3 ++-
> tests/qemu-iotests/tests/image-fleecing | 3 ++-
> tests/qemu-iotests/tests/iothreads-create | 3 ++-
> tests/qemu-iotests/tests/luks-detached-header | 3 ++-
> .../tests/migrate-bitmaps-postcopy-test | 3 ++-
> tests/qemu-iotests/tests/migrate-bitmaps-test | 3 ++-
> tests/qemu-iotests/tests/mirror-change-copy-mode | 3 ++-
> tests/qemu-iotests/tests/mirror-ready-cancel-error | 3 ++-
> tests/qemu-iotests/tests/qcow2-internal-snapshots | 1 +
> tests/qemu-iotests/tests/qsd-migrate | 3 ++-
> tests/qemu-iotests/tests/reopen-file | 3 ++-
> tests/qemu-iotests/tests/write-zeroes-unmap | 1 +
> 73 files changed, 152 insertions(+), 37 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP
2026-06-25 21:19 ` [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP Marc-André Lureau
@ 2026-08-10 18:34 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:34 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:32AM +0400, Marc-André Lureau wrote:
> Guard calls to monitor_vprintf in error-report and qemu-print so
> they compile without HMP. When CONFIG_HMP is not set,
> error_vprintf_mon falls back directly to stderr and qemu_vfprintf
> returns -1 for NULL streams.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/unit/test-util-sockets.c | 4 +++-
> tools/qemu-vnc/stubs.c | 2 ++
> util/error-report.c | 8 +++++---
> util/qemu-print.c | 6 ++++++
> 4 files changed, 16 insertions(+), 4 deletions(-)
This patch probably isn't required any more.
With the QOM classes for montior, monitor_vprintf calls to a 'vprintf'
class virtual method, or returns -1.
So simply by virtue of HMP being compiled out, monitor_vprintf should
do the right thing.
>
> diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
> index b9f2453e299..23ebe1e26b5 100644
> --- a/tests/unit/test-util-sockets.c
> +++ b/tests/unit/test-util-sockets.c
> @@ -73,8 +73,10 @@ int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
> */
> Monitor *monitor_cur(void) { return cur_mon; }
> Monitor *monitor_set_cur(Coroutine *co, Monitor *mon) { abort(); }
> -int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
> bool monitor_cur_is_qmp(void) { abort(); };
> +#ifdef CONFIG_HMP
> +int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { abort(); }
> +#endif
>
> #ifndef _WIN32
> static void test_socket_fd_pass_name_good(void)
> diff --git a/tools/qemu-vnc/stubs.c b/tools/qemu-vnc/stubs.c
> index a865ce85f04..f476dd6d956 100644
> --- a/tools/qemu-vnc/stubs.c
> +++ b/tools/qemu-vnc/stubs.c
> @@ -46,10 +46,12 @@ Monitor *monitor_set_cur(Coroutine *co, Monitor *mon)
> return NULL;
> }
>
> +#ifdef CONFIG_HMP
> int monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
> {
> return -1;
> }
> +#endif
>
> /*
> * Link-time stubs for VMState symbols referenced by VNC code.
> diff --git a/util/error-report.c b/util/error-report.c
> index f832ad9b6b6..e2e46281455 100644
> --- a/util/error-report.c
> +++ b/util/error-report.c
> @@ -40,11 +40,13 @@ error_vprintf_mon(Monitor *cur_mon, const char *fmt, va_list ap)
> * IOW this will only print if in HMP, otherwise we
> * fallback to stderr for QMP / no-monitor scenarios.
> */
> +#ifdef CONFIG_HMP
> int ret = monitor_vprintf(cur_mon, fmt, ap);
> - if (ret == -1) {
> - ret = vfprintf(stderr, fmt, ap);
> + if (ret != -1) {
> + return ret;
> }
> - return ret;
> +#endif
> + return vfprintf(stderr, fmt, ap);
> }
>
> /*
> diff --git a/util/qemu-print.c b/util/qemu-print.c
> index 7b9591035e5..ee80000722b 100644
> --- a/util/qemu-print.c
> +++ b/util/qemu-print.c
> @@ -20,10 +20,12 @@
> */
> int qemu_vprintf(const char *fmt, va_list ap)
> {
> +#ifdef CONFIG_HMP
> Monitor *cur_mon = monitor_cur();
> if (cur_mon) {
> return monitor_vprintf(cur_mon, fmt, ap);
> }
> +#endif
> return vprintf(fmt, ap);
> }
>
> @@ -52,7 +54,11 @@ int qemu_printf(const char *fmt, ...)
> int qemu_vfprintf(FILE *stream, const char *fmt, va_list ap)
> {
> if (!stream) {
> +#ifdef CONFIG_HMP
> return monitor_vprintf(monitor_cur(), fmt, ap);
> +#else
> + return -1;
> +#endif
> }
> return vfprintf(stream, fmt, ap);
> }
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP
2026-06-25 21:19 ` [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
@ 2026-08-10 18:35 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:35 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:33AM +0400, Marc-André Lureau wrote:
> Make the 'readline' value of MonitorMode and the
> 'human-monitor-command' command conditional on CONFIG_HMP, so
> they are only available when HMP support is compiled in.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/control.json | 4 +++-
> qapi/misc.json | 3 ++-
> monitor/monitor.c | 8 +++++++-
> monitor/qmp-cmds.c | 2 ++
> 4 files changed, 14 insertions(+), 3 deletions(-)
this will need a bunch of conflict resolution with the QOM
work I'm afraid.
>
> diff --git a/qapi/control.json b/qapi/control.json
> index 9a5302193d6..9898552814b 100644
> --- a/qapi/control.json
> +++ b/qapi/control.json
> @@ -186,7 +186,9 @@
> #
> # Since: 5.0
> ##
> -{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
> +{ 'enum': 'MonitorMode', 'data': [
> + { 'name': 'readline', 'if': 'CONFIG_HMP' },
> + 'control' ] }
>
> ##
> # @MonitorOptions:
> diff --git a/qapi/misc.json b/qapi/misc.json
> index 22b7afed9f6..a21ba61b96e 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -247,7 +247,8 @@
> { 'command': 'human-monitor-command',
> 'data': {'command-line': 'str', '*cpu-index': 'int'},
> 'returns': 'str',
> - 'features': [ 'savevm-monitor-nodes' ] }
> + 'features': [ 'savevm-monitor-nodes' ],
> + 'if': 'CONFIG_HMP' }
>
> ##
> # @getfd:
> diff --git a/monitor/monitor.c b/monitor/monitor.c
> index f443f406b4c..50f1fe77c33 100644
> --- a/monitor/monitor.c
> +++ b/monitor/monitor.c
> @@ -733,13 +733,18 @@ int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
> }
>
> if (!opts->has_mode) {
> - opts->mode = allow_hmp ? MONITOR_MODE_READLINE : MONITOR_MODE_CONTROL;
> + opts->mode =
> +#ifdef CONFIG_HMP
> + allow_hmp ? MONITOR_MODE_READLINE :
> +#endif
> + MONITOR_MODE_CONTROL;
> }
>
> switch (opts->mode) {
> case MONITOR_MODE_CONTROL:
> monitor_init_qmp(chr, opts->pretty, errp);
> break;
> +#ifdef CONFIG_HMP
> case MONITOR_MODE_READLINE:
> if (!allow_hmp) {
> error_setg(errp, "Only QMP is supported");
> @@ -751,6 +756,7 @@ int monitor_init(MonitorOptions *opts, bool allow_hmp, Error **errp)
> }
> monitor_init_hmp(chr, true, errp);
> break;
> +#endif /* CONFIG_HMP */
> default:
> g_assert_not_reached();
> }
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index 0c409c27dc3..5e642a2b14d 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -162,6 +162,7 @@ void qmp_add_client(const char *protocol, const char *fdname,
> }
> }
>
> +#ifdef CONFIG_HMP
> char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
> int64_t cpu_index, Error **errp)
> {
> @@ -189,6 +190,7 @@ out:
> monitor_data_destroy(&hmp.common);
> return output;
> }
> +#endif /* CONFIG_HMP */
>
> static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
> {
>
> --
> 2.54.0
>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 34/39] Guard HMP command implementations with CONFIG_HMP
2026-06-25 21:19 ` [PATCH v2 34/39] Guard HMP command implementations " Marc-André Lureau
@ 2026-08-10 18:36 ` Daniel P. Berrangé
0 siblings, 0 replies; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-10 18:36 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On Fri, Jun 26, 2026 at 01:19:35AM +0400, Marc-André Lureau wrote:
> Add #ifdef CONFIG_HMP around all hmp_* function implementations and
> their HMP-only helpers across subsystems.
>
> This covers monitor_register_hmp* callers, hmp_info_* handlers, and
> HMP-only helper functions like slirp_lookup.
>
> To link succesfully, use empty cmds tables in hmp-cmds.c (to be removed
> once meson build-sys is updated with !hmp support later in the series)
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> accel/accel-system.c | 2 ++
> accel/tcg/monitor.c | 2 ++
> hw/i386/kvm/xen-stubs.c | 2 ++
> hw/i386/kvm/xen_evtchn.c | 3 ++-
> hw/i386/sgx.c | 2 ++
> hw/misc/mos6522-stub.c | 2 ++
> hw/misc/mos6522.c | 2 ++
> hw/pci/pci-stub.c | 2 ++
> hw/s390x/s390-skeys.c | 2 ++
> hw/s390x/s390-stattrib.c | 4 ++++
> hw/uefi/ovmf-log.c | 2 ++
> hw/usb/host-libusb.c | 6 ++++++
> migration/dirtyrate.c | 2 ++
> monitor/hmp-cmds.c | 5 +++++
> net/slirp.c | 7 ++++++-
> replay/replay-debugging.c | 8 ++++++++
> replay/stubs-system.c | 6 ++++++
> system/dirtylimit.c | 6 ++++++
> system/qdev-monitor.c | 4 ++++
> target/i386/cpu-apic.c | 2 ++
> target/i386/monitor.c | 3 +++
> target/i386/sev.c | 2 ++
> target/m68k/monitor.c | 2 ++
> target/ppc/monitor.c | 2 ++
> target/riscv/monitor.c | 3 +++
> target/sh4/monitor.c | 2 ++
> target/sparc/monitor.c | 2 ++
> target/xtensa/monitor.c | 2 ++
> 28 files changed, 87 insertions(+), 2 deletions(-)
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce()
2026-06-25 21:19 ` [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
2026-08-10 17:42 ` Daniel P. Berrangé
@ 2026-08-10 20:16 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-10 20:16 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel
Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
Markus Armbruster
On 25/6/26 23:19, Marc-André Lureau wrote:
> Rather than silently doing nothing.
>
> Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> target/i386/monitor.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 07/39] s390x: prevent crash if given invalid CPU#
2026-06-25 21:19 ` [PATCH v2 07/39] s390x: prevent crash if given invalid CPU# Marc-André Lureau
2026-08-10 17:44 ` Daniel P. Berrangé
@ 2026-08-10 21:01 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-10 21:01 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel
Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
Markus Armbruster, Eric Farman, Corey Minyard
On 25/6/26 23:19, Marc-André Lureau wrote:
> Reviewed-by: Eric Farman <farman@linux.ibm.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> hw/s390x/s390-virtio-ccw.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 25a9fa49554..d0fd894eb67 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -729,6 +729,11 @@ static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
> {
> CPUState *cs = qemu_get_cpu(cpu_index);
>
> + if (!cs) {
> + error_setg(errp, "CPU %d does not exist", cpu_index);
> + return;
> + }
> +
> s390_cpu_restart(S390_CPU(cs));
Looking at commit 6af94767daf ("ipmi: Fix watchdog NMI handling"),
I suppose we can trigger this crash with IPMI on s390x target, is
that right?
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> }
>
>
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 35/39] target: guard MonitorDef tables with CONFIG_HMP
2026-06-25 21:19 ` [PATCH v2 35/39] target: guard MonitorDef tables " Marc-André Lureau
@ 2026-08-10 21:44 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-10 21:44 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel
Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
Markus Armbruster
On 25/6/26 23:19, Marc-André Lureau wrote:
> Guard SysemuCPUOps::monitor_defs field and the per-target MonitorDef
> arrays with CONFIG_HMP. These tables are only used by HMP 'print' and
> 'info registers' commands.
Per the cover "info registers (medium) - plus $reg expression handling"
is still listed as undone.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/hw/core/sysemu-cpu-ops.h | 2 ++
> monitor/hmp.c | 4 +++-
> target/i386/cpu.c | 4 ++++
> target/m68k/cpu.c | 4 ++++
> target/sparc/cpu.c | 5 +++--
> 5 files changed, 16 insertions(+), 3 deletions(-)
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 00/39] Make HMP optional (and later standalone)
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
` (38 preceding siblings ...)
2026-06-25 21:19 ` [PATCH v2 39/39] monitor: guard HMP monitor API " Marc-André Lureau
@ 2026-08-10 21:49 ` Philippe Mathieu-Daudé
2026-08-11 8:07 ` Daniel P. Berrangé
39 siblings, 1 reply; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-10 21:49 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel
Cc: Philippe Mathieu-Daudé, Daniel P. Berrangé,
Markus Armbruster, Eric Farman
Hi Marc-André,
On 25/6/26 23:19, Marc-André Lureau wrote:
> Hi,
>
> This series makes HMP compile-time optional via --disable-hmp. The
> resulting binary speaks only QMP - reducing the attack surface, binary
> size and enforcing a separation between machine-readable interface and
> interactive debugging console.
>
> QMP offers almost all the functionality HMP could provide, so a separate
> standalone "HMP-like" console could be implemented on top of it.
I'm in favor of the overall goal, but am reluctant to the amount of
CONFIG_HMP #ifdef'ry added. During the last years we changed our style
to link unreachable stubs, allowing easier code maintenance. Are we OK
to deviate in this case?
Regards,
Phil.
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor
2026-08-10 17:40 ` Daniel P. Berrangé
@ 2026-08-11 7:56 ` Marc-André Lureau
0 siblings, 0 replies; 79+ messages in thread
From: Marc-André Lureau @ 2026-08-11 7:56 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
Hi
On Mon, Aug 10, 2026 at 9:40 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Fri, Jun 26, 2026 at 01:19:05AM +0400, Marc-André Lureau wrote:
> > Replace monitor_printf() error reporting with the standard **errp
> > pattern. Drop the Monitor *mon parameter and return bool to indicate
> > success, improving the function usage from non-HMP contexts. Update the
> > KVM MCE injection path and hmp_mce() accordingly.
> >
> > Notes:
> > - we may want to print the error in KVM path too
> > - multiple error prints are now accumulated with error hints
> >
> > Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > target/i386/cpu.h | 4 ++--
> > target/i386/helper.c | 49 ++++++++++++++++++++++++++++---------------------
> > target/i386/kvm/kvm.c | 4 ++--
> > target/i386/monitor.c | 6 ++++--
> > 4 files changed, 36 insertions(+), 27 deletions(-)
>
>
> > typedef struct MCEInjectionParams {
> > - Monitor *mon;
> > + GString *err;
>
> Why not have "Error **errp"
>
> > int bank;
> > uint64_t status;
> > uint64_t mcg_status;
> > @@ -428,9 +428,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> > * reporting is disabled
> > */
> > if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
> > - monitor_printf(params->mon,
> > - "CPU %d: Uncorrected error reporting disabled\n",
> > - cs->cpu_index);
> > + g_string_append_printf(params->err,
> > + "CPU %d: Uncorrected error reporting disabled\n",
> > + cs->cpu_index);
>
> and use error_setg here and the other two places below.
>
> > return;
> > }
> >
> > @@ -439,10 +439,9 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> > * reporting is disabled for the bank
> > */
> > if (banks[0] != ~(uint64_t)0) {
> > - monitor_printf(params->mon,
> > - "CPU %d: Uncorrected error reporting disabled for"
> > - " bank %d\n",
> > - cs->cpu_index, params->bank);
> > + g_string_append_printf(params->err,
> > + "CPU %d: Uncorrected error reporting disabled for bank %d\n",
> > + cs->cpu_index, params->bank);
> > return;
> > }
> >
> > @@ -459,7 +458,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> > if (need_reset) {
> > emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
> > recursive);
> > - monitor_printf(params->mon, "%s", msg);
> > + g_string_append_printf(params->err, "%s\n", msg);
> > qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
> > qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> > return;
> > @@ -488,14 +487,16 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
> > emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
> > }
> >
> > -void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> > +bool cpu_x86_inject_mce(X86CPU *cpu, int bank,
> > uint64_t status, uint64_t mcg_status, uint64_t addr,
> > - uint64_t misc, int flags)
> > + uint64_t misc, int flags, Error **errp)
> > {
> > + ERRP_GUARD();
> > CPUState *cs = CPU(cpu);
> > CPUX86State *cenv = &cpu->env;
> > + g_autoptr(GString) err = g_string_new(NULL);
> > MCEInjectionParams params = {
> > - .mon = mon,
> > + .err = err,
>
> This indirection via GString feels overkill when we could
> use directly pass 'errp', given the ERRP_GUARD we have
>
> > .bank = bank,
> > .status = status,
> > .mcg_status = mcg_status,
> > @@ -506,21 +507,21 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> > unsigned bank_num = cenv->mcg_cap & 0xff;
> >
> > if (!cenv->mcg_cap) {
> > - monitor_printf(mon, "MCE injection not supported\n");
> > - return;
> > + error_setg(errp, "MCE injection not supported");
> > + return false;
> > }
> > if (bank >= bank_num) {
> > - monitor_printf(mon, "Invalid MCE bank number\n");
> > - return;
> > + error_setg(errp, "Invalid MCE bank number");
> > + return false;
> > }
> > if (!(status & MCI_STATUS_VAL)) {
> > - monitor_printf(mon, "Invalid MCE status code\n");
> > - return;
> > + error_setg(errp, "Invalid MCE status code");
> > + return false;
> > }
> > if ((flags & MCE_INJECT_BROADCAST)
> > && !cpu_x86_support_mca_broadcast(cenv)) {
> > - monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
> > - return;
> > + error_setg(errp, "Guest CPU does not support MCA broadcast");
> > + return false;
> > }
> >
> > run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
> > @@ -539,6 +540,12 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
> > run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms));
> > }
> > }
> > + if (params.err->len) {
> > + error_setg(errp, "Failed to inject MCE");
> > + error_append_hint(errp, "%s", params.err->str);
> > + return false;
> > + }
>
> This could be just
>
> if (*params.errp) {
> return false;
> }
>
Good ideas, I'll do those changes
> > + return true;
> > }
> >
> > static inline target_ulong get_memio_eip(CPUX86State *env)
>
> With regards,
> Daniel
> --
> |: https://berrange.com ~~ https://hachyderm.io/@berrange :|
> |: https://libvirt.org ~~ https://entangle-photo.org :|
> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
>
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 00/39] Make HMP optional (and later standalone)
2026-08-10 21:49 ` [PATCH v2 00/39] Make HMP optional (and later standalone) Philippe Mathieu-Daudé
@ 2026-08-11 8:07 ` Daniel P. Berrangé
2026-08-11 8:40 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 79+ messages in thread
From: Daniel P. Berrangé @ 2026-08-11 8:07 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Marc-André Lureau, qemu-devel, Philippe Mathieu-Daudé,
Markus Armbruster, Eric Farman
On Mon, Aug 10, 2026 at 11:49:08PM +0200, Philippe Mathieu-Daudé wrote:
> Hi Marc-André,
>
> On 25/6/26 23:19, Marc-André Lureau wrote:
> > Hi,
> >
> > This series makes HMP compile-time optional via --disable-hmp. The
> > resulting binary speaks only QMP - reducing the attack surface, binary
> > size and enforcing a separation between machine-readable interface and
> > interactive debugging console.
> >
> > QMP offers almost all the functionality HMP could provide, so a separate
> > standalone "HMP-like" console could be implemented on top of it.
>
> I'm in favor of the overall goal, but am reluctant to the amount of
> CONFIG_HMP #ifdef'ry added. During the last years we changed our style
> to link unreachable stubs, allowing easier code maintenance. Are we OK
> to deviate in this case?
IMHO the right long term solution is for every HMP command impl to be
moved into a separate file - many are already in separate files, just
need to finish the job. Then the condition just becomes a meson.build
rule instead of an #ifdef for everything except some code in monitor/
directory. Until that's done, I think the #ifdef's are bearable as
is.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor
2026-08-10 17:48 ` Daniel P. Berrangé
@ 2026-08-11 8:18 ` Marc-André Lureau
2026-08-11 8:43 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 79+ messages in thread
From: Marc-André Lureau @ 2026-08-11 8:18 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
Hi
On Mon, Aug 10, 2026 at 9:48 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>
> On Fri, Jun 26, 2026 at 01:19:09AM +0400, Marc-André Lureau wrote:
> > Use first_cpu directly instead of going through monitor_get_cpu_index(),
> > as this is HMP-territory. QMP doesn't have a `cpu` command, we should
> > add arguments instead when needed.
> >
> > Update the inject-nmi doc to accurately describe per-architecture NMI
> > delivery.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > qapi/machine.json | 5 +++--
> > system/cpus.c | 7 +++++--
> > 2 files changed, 8 insertions(+), 4 deletions(-)
>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
I realize the patch is wrong, HMP calls qmp_inject_nmi(), we need to
pass the current cpu or not use QMP.
>
> >
> > diff --git a/qapi/machine.json b/qapi/machine.json
> > index 685e4e29b87..03461f5f723 100644
> > --- a/qapi/machine.json
> > +++ b/qapi/machine.json
> > @@ -432,8 +432,9 @@
> > ##
> > # @inject-nmi:
> > #
> > -# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
> > -# all CPUs (ppc64). The command fails when the guest doesn't support
> > +# Injects a Non-Maskable Interrupt into the virtual machine. The NMI
> > +# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
> > +# (s390). The command fails when the guest doesn't support
> > # injecting.
> > #
> > # Since: 0.14
>
>
>
> > diff --git a/system/cpus.c b/system/cpus.c
> > index 49f6daec3cd..6e3ef0afeca 100644
> > --- a/system/cpus.c
> > +++ b/system/cpus.c
> > @@ -915,6 +915,9 @@ exit:
> >
> > void qmp_inject_nmi(Error **errp)
> > {
> > - nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
> > + int cpu_index = UNASSIGNED_CPU_INDEX;
> > + if (first_cpu) {
> > + cpu_index = first_cpu->cpu_index;
> > + }
>
> I'm wondering how this "if" logic turns into the behaviour documented
> for x86/hppa/pc64 vs s390 ? Don't all those arches have 'first_cpu'
> defined, such that this changes semantics to 'first vCPU' instead of
> 'all vCPUs' ?
All the nmi handlers implement cpu_index differently.. I have to review this.
>
> > + nmi_monitor_handle(cpu_index, errp);
> > }
> > -
> >
> > --
> > 2.54.0
> >
>
> With regards,
> Daniel
> --
> |: https://berrange.com ~~ https://hachyderm.io/@berrange :|
> |: https://libvirt.org ~~ https://entangle-photo.org :|
> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
>
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 00/39] Make HMP optional (and later standalone)
2026-08-11 8:07 ` Daniel P. Berrangé
@ 2026-08-11 8:40 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 8:40 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Marc-André Lureau, qemu-devel, Philippe Mathieu-Daudé,
Markus Armbruster, Eric Farman
On 11/8/26 10:07, Daniel P. Berrangé wrote:
> On Mon, Aug 10, 2026 at 11:49:08PM +0200, Philippe Mathieu-Daudé wrote:
>> Hi Marc-André,
>>
>> On 25/6/26 23:19, Marc-André Lureau wrote:
>>> Hi,
>>>
>>> This series makes HMP compile-time optional via --disable-hmp. The
>>> resulting binary speaks only QMP - reducing the attack surface, binary
>>> size and enforcing a separation between machine-readable interface and
>>> interactive debugging console.
>>>
>>> QMP offers almost all the functionality HMP could provide, so a separate
>>> standalone "HMP-like" console could be implemented on top of it.
>>
>> I'm in favor of the overall goal, but am reluctant to the amount of
>> CONFIG_HMP #ifdef'ry added. During the last years we changed our style
>> to link unreachable stubs, allowing easier code maintenance. Are we OK
>> to deviate in this case?
>
> IMHO the right long term solution is for every HMP command impl to be
> moved into a separate file - many are already in separate files, just
> need to finish the job. Then the condition just becomes a meson.build
> rule instead of an #ifdef for everything except some code in monitor/
> directory. Until that's done, I think the #ifdef's are bearable as
> is.
We know the precedents of the QEMU project, "just need to finish the
job", as long as nobody commit to, well describes our usual half-way
unfinished conversions.
Again I'm not opposing to this series. At least we have a consensus
of what we expect at the end (long-term).
^ permalink raw reply [flat|nested] 79+ messages in thread
* Re: [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor
2026-08-11 8:18 ` Marc-André Lureau
@ 2026-08-11 8:43 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 79+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 8:43 UTC (permalink / raw)
To: Marc-André Lureau, Daniel P. Berrangé
Cc: qemu-devel, Philippe Mathieu-Daudé, Markus Armbruster
On 11/8/26 10:18, Marc-André Lureau wrote:
> Hi
>
> On Mon, Aug 10, 2026 at 9:48 PM Daniel P. Berrangé <berrange@redhat.com> wrote:
>>
>> On Fri, Jun 26, 2026 at 01:19:09AM +0400, Marc-André Lureau wrote:
>>> Use first_cpu directly instead of going through monitor_get_cpu_index(),
>>> as this is HMP-territory. QMP doesn't have a `cpu` command, we should
>>> add arguments instead when needed.
>>>
>>> Update the inject-nmi doc to accurately describe per-architecture NMI
>>> delivery.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> qapi/machine.json | 5 +++--
>>> system/cpus.c | 7 +++++--
>>> 2 files changed, 8 insertions(+), 4 deletions(-)
>>
>> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
>
> I realize the patch is wrong, HMP calls qmp_inject_nmi(), we need to
> pass the current cpu or not use QMP.
See
https://lore.kernel.org/qemu-devel/20260810213723.58467-1-philmd@oss.qualcomm.com/
which disentangle monitor from NMI class.
>
>>
>>>
>>> diff --git a/qapi/machine.json b/qapi/machine.json
>>> index 685e4e29b87..03461f5f723 100644
>>> --- a/qapi/machine.json
>>> +++ b/qapi/machine.json
>>> @@ -432,8 +432,9 @@
>>> ##
>>> # @inject-nmi:
>>> #
>>> -# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
>>> -# all CPUs (ppc64). The command fails when the guest doesn't support
>>> +# Injects a Non-Maskable Interrupt into the virtual machine. The NMI
>>> +# is delivered to all vCPUs (x86, hppa, ppc64) or to the first vCPU
>>> +# (s390). The command fails when the guest doesn't support
>>> # injecting.
>>> #
>>> # Since: 0.14
>>
>>
>>
>>> diff --git a/system/cpus.c b/system/cpus.c
>>> index 49f6daec3cd..6e3ef0afeca 100644
>>> --- a/system/cpus.c
>>> +++ b/system/cpus.c
>>> @@ -915,6 +915,9 @@ exit:
>>>
>>> void qmp_inject_nmi(Error **errp)
>>> {
>>> - nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
>>> + int cpu_index = UNASSIGNED_CPU_INDEX;
>>> + if (first_cpu) {
>>> + cpu_index = first_cpu->cpu_index;
>>> + }
>>
>> I'm wondering how this "if" logic turns into the behaviour documented
>> for x86/hppa/pc64 vs s390 ? Don't all those arches have 'first_cpu'
>> defined, such that this changes semantics to 'first vCPU' instead of
>> 'all vCPUs' ?
>
> All the nmi handlers implement cpu_index differently.. I have to review this.
(ditto)
>
>>
>>> + nmi_monitor_handle(cpu_index, errp);
>>> }
>>> -
>>>
>>> --
>>> 2.54.0
>>>
>>
>> With regards,
>> Daniel
>> --
>> |: https://berrange.com ~~ https://hachyderm.io/@berrange :|
>> |: https://libvirt.org ~~ https://entangle-photo.org :|
>> |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|
>>
>
>
^ permalink raw reply [flat|nested] 79+ messages in thread
end of thread, other threads:[~2026-08-11 8:43 UTC | newest]
Thread overview: 79+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-25 21:19 [PATCH v2 00/39] Make HMP optional (and later standalone) Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 01/39] vl: fix -monitor none prefix matching Marc-André Lureau
2026-08-10 17:30 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 02/39] hmp: remove 'vcpu' argument from trace-event help Marc-André Lureau
2026-08-10 17:31 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 03/39] hmp: fix snapshot_blkdev argument type Marc-André Lureau
2026-08-10 17:35 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 04/39] target/i386: decouple cpu_x86_inject_mce() from Monitor Marc-André Lureau
2026-08-10 17:40 ` Daniel P. Berrangé
2026-08-11 7:56 ` Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 05/39] target/i386: return an error for invalid CPU in hmp_mce() Marc-André Lureau
2026-08-10 17:42 ` Daniel P. Berrangé
2026-08-10 20:16 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 06/39] system: move gpa2hva() to system memory unit Marc-André Lureau
2026-08-10 17:44 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 07/39] s390x: prevent crash if given invalid CPU# Marc-André Lureau
2026-08-10 17:44 ` Daniel P. Berrangé
2026-08-10 21:01 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 08/39] system: decouple qmp_inject_nmi() from Monitor Marc-André Lureau
2026-08-10 17:48 ` Daniel P. Berrangé
2026-08-11 8:18 ` Marc-André Lureau
2026-08-11 8:43 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 09/39] hmp: correct the nmi documentation Marc-André Lureau
2026-08-10 17:51 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 10/39] monitor: move HMP-only fields from Monitor to MonitorHMP Marc-André Lureau
2026-08-10 17:54 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 11/39] tests/functional: use query-version QMP command instead of HMP Marc-André Lureau
2026-08-10 17:54 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 12/39] net/qapi: add x-query-usernet command Marc-André Lureau
2026-08-10 17:56 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 13/39] python, tests: switch usernet queries from HMP to QMP Marc-André Lureau
2026-08-10 18:00 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 14/39] tests/qtest/pnv: drop unnecessary -serial mon:stdio Marc-André Lureau
2026-08-10 18:01 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 15/39] tests/qtest/qmp-test: don't depend on human-monitor-command Marc-André Lureau
2026-08-10 18:03 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 16/39] tests/qtest/numa-test: replace HMP "info numa" with QMP query-cpus-fast Marc-André Lureau
2026-08-10 18:04 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 17/39] tests/qtest/cdrom-test: replace HMP "info block" with QMP query-block Marc-André Lureau
2026-08-10 18:05 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 18/39] tests/qtest/device-introspect-test: fix test without HMP Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 19/39] tests/qemu-iotests/205: fix race in assertExportNotFound Marc-André Lureau
2026-08-10 18:15 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 20/39] net: add x-query-network QMP command Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 21/39] tests/qtest/netdev-socket: replace HMP with x-query-network QMP Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 22/39] qemu-io: propagate errors through Error API instead of printf Marc-André Lureau
2026-08-10 18:19 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 23/39] RFC: qtest: add qemu-io command to the qtest protocol Marc-André Lureau
2026-08-10 18:22 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 24/39] RFC: qtest/ide-test: convert to use qtest qemu-io command Marc-André Lureau
2026-08-10 18:22 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 25/39] block: add x-qemu-io QMP command Marc-André Lureau
2026-08-10 18:26 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 26/39] tests/qemu-iotests: add qmp_qemu_io() Marc-André Lureau
2026-08-10 18:24 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 27/39] tests/qemu-iotests: convert pause/resume_drive() to QMP Marc-André Lureau
2026-08-10 18:26 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 28/39] build-sys: add 'hmp' option Marc-André Lureau
2026-08-10 18:27 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 29/39] monitor: reject readline monitor when HMP is disabled Marc-André Lureau
2026-08-10 18:28 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 30/39] tests: skip HMP-dependent tests " Marc-André Lureau
2026-08-10 18:29 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 31/39] util: guard monitor_vprintf callers with CONFIG_HMP Marc-André Lureau
2026-08-10 18:34 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 32/39] qapi: make HMP-specific schema entries conditional on CONFIG_HMP Marc-André Lureau
2026-08-10 18:35 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 33/39] system: guard HMP initialization paths with CONFIG_HMP Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 34/39] Guard HMP command implementations " Marc-André Lureau
2026-08-10 18:36 ` Daniel P. Berrangé
2026-06-25 21:19 ` [PATCH v2 35/39] target: guard MonitorDef tables " Marc-André Lureau
2026-08-10 21:44 ` Philippe Mathieu-Daudé
2026-06-25 21:19 ` [PATCH v2 36/39] hw: guard BusClass::print_dev " Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 37/39] build-sys: make HMP source files conditional on have_hmp Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 38/39] monitor: guard HMP internal helpers with CONFIG_HMP Marc-André Lureau
2026-06-25 21:19 ` [PATCH v2 39/39] monitor: guard HMP monitor API " Marc-André Lureau
2026-08-10 21:49 ` [PATCH v2 00/39] Make HMP optional (and later standalone) Philippe Mathieu-Daudé
2026-08-11 8:07 ` Daniel P. Berrangé
2026-08-11 8:40 ` Philippe Mathieu-Daudé
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.