qtest: add qemu-io command to the qtest protocol
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. Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260828-qemu-no-hmp-v5-23-9227de146347@redhat.com>
Marc-André Lureau committed
Aug 28, 2026 at 16:04 UTC
4440cc2fe9d3318780d9c5988ca5d3282d3f0326
3 files changed
+39
system/qtest.c
+14
@@ -33,6 +33,7 @@
33
#include "qom/object_interfaces.h"
34
#include "qom/qom-qobject.h"
35
#include "qobject/qobject.h"
36
+#include "qapi-commands-block.h"
37
38
#define MAX_IRQ 256
39
@@ -797,6 +798,19 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
798
}
799
g_slist_free(list);
800
qtest_send(chr, "OK\n");
801
+ } else if (strcmp(words[0], "qemu-io") == 0) {
802
+ const char *io_dev;
803
+ g_autofree char *io_cmd = NULL;
804
+ Error *err = NULL;
805
+
806
+ g_assert(words[1] && words[2]);
807
+ io_dev = words[1];
808
+ io_cmd = g_strjoinv(" ", &words[2]);
809
+
810
+ qmp_x_qemu_io(io_dev, NULL, io_cmd, &err);
811
+ qtest_sendf(chr, err ? "FAIL %s\n" : "OK\n",
812
+ err ? error_get_pretty(err) : NULL);
813
+ error_free(err);
814
} else if (process_command_cb && process_command_cb(chr, words)) {
815
/* Command got consumed by the callback handler */
816
} else {
tests/qtest/libqtest.c
+14
@@ -1012,6 +1012,20 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
1012
return ret;
1013
}
1014
1015
+void qtest_qemu_io(QTestState *s, const char *device,
1016
+ const char *fmt, ...)
1017
+{
1018
+ va_list ap;
1019
+ g_autofree char *cmd = NULL;
1020
+
1021
+ va_start(ap, fmt);
1022
+ cmd = g_strdup_vprintf(fmt, ap);
1023
+ va_end(ap);
1024
+
1025
+ qtest_sendf(s, "qemu-io %s %s\n", device, cmd);
1026
+ qtest_rsp(s);
1027
+}
1028
+
1029
const char *qtest_get_arch(void)
1030
{
1031
/*
tests/qtest/libqtest.h
+11
@@ -424,6 +424,17 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
424
char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
425
G_GNUC_PRINTF(2, 0);
426
427
+/**
428
+ * qtest_qemu_io:
429
+ * @s: #QTestState instance to operate on.
430
+ * @device: block device node-name or BlockBackend name.
431
+ * @fmt: qemu-io command to send, formats arguments like sprintf().
432
+ *
433
+ * Send a qemu-io command via the qtest protocol.
434
+ */
435
+void qtest_qemu_io(QTestState *s, const char *device,
436
+ const char *fmt, ...) G_GNUC_PRINTF(3, 4);
437
+
438
void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
439
440
/**