@samitouri / QOSamiQemu / commits / 4440cc2fe9

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 /**