The QMP version is flagged with a __org.qemu.debug- prefix in order to reinforce the statement that qemu-io is for testing and debugging only, with no API guarantees.
The HMP version is simply called 'qemu-io' for convenience. Signed-off-by: Kevin Wolf <kw...@redhat.com> --- Makefile | 2 +- Makefile.objs | 1 + blockdev.c | 15 +++++++++++++++ hmp-commands.hx | 16 ++++++++++++++++ hmp.c | 10 ++++++++++ hmp.h | 1 + qapi-schema.json | 16 ++++++++++++++++ qmp-commands.hx | 28 ++++++++++++++++++++++++++++ 8 files changed, 88 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 581150f..2b85af8 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ qemu-img.o: qemu-img-cmds.h qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a -qemu-io$(EXESUF): qemu-io.o qemu-io-cmds.o $(block-obj-y) libqemuutil.a libqemustub.a +qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o diff --git a/Makefile.objs b/Makefile.objs index 286ce06..5b288ba 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -13,6 +13,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o block-obj-$(CONFIG_WIN32) += aio-win32.o block-obj-y += block/ block-obj-y += qapi-types.o qapi-visit.o +block-obj-y += qemu-io-cmds.o block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o block-obj-y += qemu-coroutine-sleep.o diff --git a/blockdev.c b/blockdev.c index 789ad9f..9f9f920 100644 --- a/blockdev.c +++ b/blockdev.c @@ -43,6 +43,7 @@ #include "qmp-commands.h" #include "trace.h" #include "sysemu/arch_init.h" +#include "qemu-io.h" static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); extern QemuOptsList qemu_common_drive_opts; @@ -1604,6 +1605,20 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp) return dummy.next; } +void qmp___org_qemu_debug_qemu_io_command(const char *device, const char *cmd, + Error **errp) +{ + BlockDriverState *bs; + + bs = bdrv_find(device); + if (!bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; + } + + qemuio_command(bs, cmd); +} + QemuOptsList qemu_common_drive_opts = { .name = "drive", .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head), diff --git a/hmp-commands.hx b/hmp-commands.hx index 9cea415..9d4c04f 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1551,6 +1551,22 @@ Removes the chardev @var{id}. ETEXI { + .name = "qemu-io", + .args_type = "device:B,command:s", + .params = "[device] \"[command]\"", + .help = "run a qemu-io command on a block device", + .mhandler.cmd = hmp_qemu_io, + }, + +STEXI +@item chardev_remove id +@findex chardev_remove + +Removes the chardev @var{id}. + +ETEXI + + { .name = "info", .args_type = "item:s?", .params = "[subcommand]", diff --git a/hmp.c b/hmp.c index 4fb76ec..9cea8d8 100644 --- a/hmp.c +++ b/hmp.c @@ -1425,3 +1425,13 @@ void hmp_chardev_remove(Monitor *mon, const QDict *qdict) qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err); hmp_handle_error(mon, &local_err); } + +void hmp_qemu_io(Monitor *mon, const QDict *qdict) +{ + Error *local_err = NULL; + const char* device = qdict_get_str(qdict, "device"); + const char* command = qdict_get_str(qdict, "command"); + + qmp___org_qemu_debug_qemu_io_command(device, command, &local_err); + hmp_handle_error(mon, &local_err); +} diff --git a/hmp.h b/hmp.h index 95fe76e..56d2e92 100644 --- a/hmp.h +++ b/hmp.h @@ -85,5 +85,6 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); void hmp_chardev_add(Monitor *mon, const QDict *qdict); void hmp_chardev_remove(Monitor *mon, const QDict *qdict); +void hmp_qemu_io(Monitor *mon, const QDict *qdict); #endif diff --git a/qapi-schema.json b/qapi-schema.json index ef1f657..cc4a083 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3618,3 +3618,19 @@ '*cpuid-input-ecx': 'int', 'cpuid-register': 'X86CPURegister32', 'features': 'int' } } + +## +# @__org.qemu.debug-qemu-io-command +# +# Execute a qemu-io command +# +# @device: The block device on which the command should be executed +# +# @command: The command to execute +# +# Returns: Nothing on success +# +# Since: 1.6 (testing and debugging use only, no API stability) +## +{ 'command': '__org.qemu.debug-qemu-io-command', + 'data': {'device': 'str', 'command': 'str'} } diff --git a/qmp-commands.hx b/qmp-commands.hx index ffd130e..8682bea 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2932,3 +2932,31 @@ Example: <- { "return": {} } EQMP + + { + .name = "__org.qemu.debug-qemu-io-command", + .args_type = "device:s,command:s", + .mhandler.cmd_new = qmp_marshal_input___org_qemu_debug_qemu_io_command, + }, + + +SQMP +__org.qemu.debug-qemu-io-command +-------------------------------- + +Execute a qemu-io command. Debugging and testing use only. This API is not +stable. + +Arguments: + +- "device": The block device on which the command should be executed + (json-string) +- "command": The command to execute (json-string) + +Example: + +-> { "execute": "__org.qemu.debug-qemu-io-command", + "arguments": { "device" : "ide0-hd0", "command" : "flush" } } +<- { "return": {} } + +EQMP -- 1.8.1.4