diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-09-04 13:28:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-09-04 13:28:09 +0100 |
commit | 98bfaac788be0ca63d7d010c8d4ba100ff1d8278 (patch) | |
tree | a6adc21256f54beb05f428440b0ed0e69bdddc45 | |
parent | 32f0f68bb77289b75a82925f712bb52e16eac3ba (diff) | |
parent | ebf677c8497ee81537f7ce57b165c978511ccde5 (diff) |
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2017-09-01-v3' into staging
QAPI patches for 2017-09-01
# gpg: Signature made Mon 04 Sep 2017 12:30:31 BST
# gpg: using RSA key 0x3870B400EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg: aka "Markus Armbruster <armbru@pond.sub.org>"
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653
* remotes/armbru/tags/pull-qapi-2017-09-01-v3: (47 commits)
qapi: drop the sentinel in enum array
qapi: Change data type of the FOO_lookup generated for enum FOO
qapi: Convert indirect uses of FOO_lookup[...] to qapi_enum_lookup()
qapi: Mechanically convert FOO_lookup[...] to FOO_str(...)
qapi: Generate FOO_str() macro for QAPI enum FOO
qapi: Avoid unnecessary use of enum lookup table's sentinel
qapi: Use qapi_enum_parse() in input_type_enum()
crypto: Use qapi_enum_parse() in qcrypto_block_luks_name_lookup()
quorum: Use qapi_enum_parse() in quorum_open()
block: Use qemu_enum_parse() in blkdebug_debug_breakpoint()
hmp: Use qapi_enum_parse() in hmp_migrate_set_parameter()
hmp: Use qapi_enum_parse() in hmp_migrate_set_capability()
tpm: Clean up model registration & lookup
tpm: Clean up driver registration & lookup
qapi: Drop superfluous qapi_enum_parse() parameter max
qapi: Update qapi-code-gen.txt examples to match current code
qapi-schema: Improve section headings
qapi-schema: Move queries from common.json to qapi-schema.json
qapi-schema: Make block-core.json self-contained
qapi-schema: Fold event.json back into qapi-schema.json
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
108 files changed, 5362 insertions, 4984 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ccee28b12d..5ec945c9af 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1231,6 +1231,7 @@ S: Supported F: blockdev.c F: block/qapi.c F: qapi/block*.json +F: qapi/transaction.json T: git git://repo.or.cz/qemu/armbru.git block-next Dirty Bitmaps @@ -1253,6 +1254,7 @@ M: Marc-André Lureau <marcandre.lureau@redhat.com> S: Maintained F: chardev/ F: include/chardev/ +F: qapi/char.json Character Devices (Braille) M: Samuel Thibault <samuel.thibault@ens-lyon.org> @@ -1319,12 +1321,14 @@ F: include/ui/spice-display.h F: ui/spice-*.c F: audio/spiceaudio.c F: hw/display/qxl* +F: qapi/ui.json Graphics M: Gerd Hoffmann <kraxel@redhat.com> S: Odd Fixes F: ui/ F: include/ui/ +F: qapi/ui.json Cocoa graphics M: Peter Maydell <peter.maydell@linaro.org> @@ -1338,6 +1342,7 @@ F: cpus.c F: util/main-loop.c F: util/qemu-timer.c F: vl.c +F: qapi/run-state.json Human Monitor (HMP) M: Dr. David Alan Gilbert <dgilbert@redhat.com> @@ -1354,6 +1359,7 @@ S: Maintained F: net/ F: include/net/ T: git git://github.com/jasowang/qemu.git net +F: qapi/net.json Netmap network backend M: Luigi Rizzo <rizzo@iet.unipi.it> @@ -1480,6 +1486,14 @@ F: scripts/tracetool/ F: docs/tracing.txt T: git git://github.com/stefanha/qemu.git tracing +TPM +S: Orphan +F: tpm.c +F: hw/tpm/* +F: include/hw/acpi/tpm.h +F: include/sysemu/tpm* +F: qapi/tpm.json + Checkpatch S: Odd Fixes F: scripts/checkpatch.pl @@ -1493,6 +1507,7 @@ F: migration/ F: scripts/vmstate-static-checker.py F: tests/vmstate-static-checker-data/ F: docs/migration.txt +F: qapi/migration.json Seccomp M: Eduardo Otubo <otubo@redhat.com> @@ -1535,6 +1550,7 @@ M: Paolo Bonzini <pbonzini@redhat.com> S: Maintained F: include/qemu/sockets.h F: util/qemu-sockets.c +F: qapi/sockets.json Throttling infrastructure M: Alberto Garcia <berto@igalia.com> @@ -410,9 +410,18 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py) qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \ $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \ - $(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json \ - $(SRC_PATH)/qapi/crypto.json $(SRC_PATH)/qapi/rocker.json \ - $(SRC_PATH)/qapi/trace.json + $(SRC_PATH)/qapi/char.json \ + $(SRC_PATH)/qapi/crypto.json \ + $(SRC_PATH)/qapi/introspect.json \ + $(SRC_PATH)/qapi/migration.json \ + $(SRC_PATH)/qapi/net.json \ + $(SRC_PATH)/qapi/rocker.json \ + $(SRC_PATH)/qapi/run-state.json \ + $(SRC_PATH)/qapi/sockets.json \ + $(SRC_PATH)/qapi/tpm.json \ + $(SRC_PATH)/qapi/trace.json \ + $(SRC_PATH)/qapi/transaction.json \ + $(SRC_PATH)/qapi/ui.json qapi-types.c qapi-types.h :\ $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py) diff --git a/backends/hostmem.c b/backends/hostmem.c index 34550b9067..ee2c2d5bfd 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -304,7 +304,7 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) return; } else if (maxnode == 0 && backend->policy != MPOL_DEFAULT) { error_setg(errp, "host-nodes must be set for policy %s", - HostMemPolicy_lookup[backend->policy]); + HostMemPolicy_str(backend->policy)); return; } @@ -395,7 +395,7 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) host_memory_backend_set_host_nodes, NULL, NULL, &error_abort); object_class_property_add_enum(oc, "policy", "HostMemPolicy", - HostMemPolicy_lookup, + &HostMemPolicy_lookup, host_memory_backend_get_policy, host_memory_backend_set_policy, &error_abort); object_class_property_add_str(oc, "id", get_id, set_id, &error_abort); @@ -42,7 +42,6 @@ #include "qapi-event.h" #include "qemu/cutils.h" #include "qemu/id.h" -#include "qapi/util.h" #ifdef CONFIG_BSD #include <sys/ioctl.h> @@ -1333,9 +1332,8 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, detect_zeroes = qemu_opt_get(opts, "detect-zeroes"); if (detect_zeroes) { BlockdevDetectZeroesOptions value = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, detect_zeroes, - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { diff --git a/block/backup.c b/block/backup.c index 504a089150..517c300a49 100644 --- a/block/backup.c +++ b/block/backup.c @@ -596,7 +596,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs, error_setg(errp, "a sync_bitmap was provided to backup_run, " "but received an incompatible sync_mode (%s)", - MirrorSyncMode_lookup[sync_mode]); + MirrorSyncMode_str(sync_mode)); return NULL; } diff --git a/block/blkdebug.c b/block/blkdebug.c index c19ab28f07..8e385acf54 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -149,20 +149,6 @@ static QemuOptsList *config_groups[] = { NULL }; -static int get_event_by_name(const char *name, BlkdebugEvent *event) -{ - int i; - - for (i = 0; i < BLKDBG__MAX; i++) { - if (!strcmp(BlkdebugEvent_lookup[i], name)) { - *event = i; - return 0; - } - } - - return -1; -} - struct add_rule_data { BDRVBlkdebugState *s; int action; @@ -173,7 +159,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp) struct add_rule_data *d = opaque; BDRVBlkdebugState *s = d->s; const char* event_name; - BlkdebugEvent event; + int event; struct BlkdebugRule *rule; int64_t sector; @@ -182,8 +168,9 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp) if (!event_name) { error_setg(errp, "Missing event name for rule"); return -1; - } else if (get_event_by_name(event_name, &event) < 0) { - error_setg(errp, "Invalid event name \"%s\"", event_name); + } + event = qapi_enum_parse(&BlkdebugEvent_lookup, event_name, -1, errp); + if (event < 0) { return -1; } @@ -743,13 +730,13 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event, { BDRVBlkdebugState *s = bs->opaque; struct BlkdebugRule *rule; - BlkdebugEvent blkdebug_event; + int blkdebug_event; - if (get_event_by_name(event, &blkdebug_event) < 0) { + blkdebug_event = qapi_enum_parse(&BlkdebugEvent_lookup, event, -1, NULL); + if (blkdebug_event < 0) { return -ENOENT; } - rule = g_malloc(sizeof(*rule)); *rule = (struct BlkdebugRule) { .event = blkdebug_event, diff --git a/block/file-posix.c b/block/file-posix.c index cb3bfce147..6acbd56238 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -31,7 +31,6 @@ #include "block/thread-pool.h" #include "qemu/iov.h" #include "block/raw-aio.h" -#include "qapi/util.h" #include "qapi/qmp/qstring.h" #if defined(__APPLE__) && (__MACH__) @@ -438,8 +437,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, aio_default = (bdrv_flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; - aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), - BLOCKDEV_AIO_OPTIONS__MAX, aio_default, &local_err); + aio = qapi_enum_parse(&BlockdevAioOptions_lookup, + qemu_opt_get(opts, "aio"), + aio_default, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -447,8 +447,9 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, } s->use_linux_aio = (aio == BLOCKDEV_AIO_OPTIONS_NATIVE); - locking = qapi_enum_parse(OnOffAuto_lookup, qemu_opt_get(opts, "locking"), - ON_OFF_AUTO__MAX, ON_OFF_AUTO_AUTO, &local_err); + locking = qapi_enum_parse(&OnOffAuto_lookup, + qemu_opt_get(opts, "locking"), + ON_OFF_AUTO_AUTO, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -1725,7 +1726,7 @@ static int raw_regular_truncate(int fd, int64_t offset, PreallocMode prealloc, default: result = -ENOTSUP; error_setg(errp, "Unsupported preallocation mode: %s", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return result; } @@ -1760,7 +1761,7 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Preallocation mode '%s' unsupported for this " - "non-regular file", PreallocMode_lookup[prealloc]); + "non-regular file", PreallocMode_str(prealloc)); return -ENOTSUP; } @@ -1974,9 +1975,8 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) BDRV_SECTOR_SIZE); nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + prealloc = qapi_enum_parse(&PreallocMode_lookup, buf, + PREALLOC_MODE_OFF, &local_err); g_free(buf); if (local_err) { error_propagate(errp, local_err); diff --git a/block/file-win32.c b/block/file-win32.c index 4706335cff..9e02214a69 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -31,7 +31,6 @@ #include "block/thread-pool.h" #include "qemu/iov.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include <windows.h> #include <winioctl.h> @@ -303,8 +302,8 @@ static bool get_aio_option(QemuOpts *opts, int flags, Error **errp) aio_default = (flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE : BLOCKDEV_AIO_OPTIONS_THREADS; - aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), - BLOCKDEV_AIO_OPTIONS__MAX, aio_default, errp); + aio = qapi_enum_parse(&BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"), + aio_default, errp); switch (aio) { case BLOCKDEV_AIO_OPTIONS_NATIVE: @@ -470,7 +469,7 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/gluster.c b/block/gluster.c index 3064a45047..0f4265a3a4 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -12,7 +12,6 @@ #include "block/block_int.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" -#include "qapi/util.h" #include "qemu/uri.h" #include "qemu/error-report.h" #include "qemu/cutils.h" @@ -544,8 +543,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, if (!strcmp(ptr, "tcp")) { ptr = "inet"; /* accept legacy "tcp" */ } - type = qapi_enum_parse(SocketAddressType_lookup, ptr, - SOCKET_ADDRESS_TYPE__MAX, -1, NULL); + type = qapi_enum_parse(&SocketAddressType_lookup, ptr, -1, NULL); if (type != SOCKET_ADDRESS_TYPE_INET && type != SOCKET_ADDRESS_TYPE_UNIX) { error_setg(&local_err, @@ -1002,8 +1000,7 @@ static int qemu_gluster_create(const char *filename, BDRV_SECTOR_SIZE); tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, tmp, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, + prealloc = qapi_enum_parse(&PreallocMode_lookup, tmp, PREALLOC_MODE_OFF, &local_err); g_free(tmp); if (local_err) { @@ -1050,7 +1047,7 @@ static int qemu_gluster_create(const char *filename, default: ret = -EINVAL; error_setg(errp, "Unsupported preallocation mode: %s", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); break; } @@ -1102,7 +1099,7 @@ static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/iscsi.c b/block/iscsi.c index d557c99668..8b47d30dcc 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -2087,7 +2087,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/nfs.c b/block/nfs.c index bec16b72a6..337fcd9c84 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -772,7 +772,7 @@ static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/parallels.c b/block/parallels.c index e1e06d23cc..2b6c6e5709 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -35,7 +35,6 @@ #include "qemu/module.h" #include "qemu/bswap.h" #include "qemu/bitmap.h" -#include "qapi/util.h" /**************************************************************/ @@ -69,13 +68,14 @@ typedef enum ParallelsPreallocMode { PRL_PREALLOC_MODE__MAX = 2, } ParallelsPreallocMode; -static const char *prealloc_mode_lookup[] = { - "falloc", - "truncate", - NULL, +static QEnumLookup prealloc_mode_lookup = { + .array = (const char *const[]) { + "falloc", + "truncate", + }, + .size = PRL_PREALLOC_MODE__MAX }; - typedef struct BDRVParallelsState { /** Locking is conservative, the lock protects * - image file extending (truncate, fallocate) @@ -696,8 +696,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, qemu_opt_get_size_del(opts, PARALLELS_OPT_PREALLOC_SIZE, 0); s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS); buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE); - s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf, - PRL_PREALLOC_MODE__MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err); + s->prealloc_mode = qapi_enum_parse(&prealloc_mode_lookup, buf, + PRL_PREALLOC_MODE_FALLOCATE, + &local_err); g_free(buf); if (local_err != NULL) { goto fail_options; diff --git a/block/qcow2.c b/block/qcow2.c index a3679c69e8..2ec399663e 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -30,7 +30,6 @@ #include "qemu/error-report.h" #include "qapi/qmp/qerror.h" #include "qapi/qmp/qbool.h" -#include "qapi/util.h" #include "qapi/qmp/types.h" #include "qapi-event.h" #include "trace.h" @@ -2716,7 +2715,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, int64_t prealloc_size = qcow2_calc_prealloc_size(total_size, cluster_size, refcount_order); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort); - qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc], + qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc), &error_abort); } @@ -2916,9 +2915,8 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) goto finish; } buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + prealloc = qapi_enum_parse(&PreallocMode_lookup, buf, + PREALLOC_MODE_OFF, &local_err); if (local_err) { error_propagate(errp, local_err); ret = -EINVAL; @@ -3082,7 +3080,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset, prealloc != PREALLOC_MODE_FALLOC && prealloc != PREALLOC_MODE_FULL) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } @@ -3607,9 +3605,8 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, } optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc = qapi_enum_parse(PreallocMode_lookup, optstr, - PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, - &local_err); + prealloc = qapi_enum_parse(&PreallocMode_lookup, optstr, + PREALLOC_MODE_OFF, &local_err); g_free(optstr); if (local_err) { goto err; diff --git a/block/qed.c b/block/qed.c index dc54bf4a93..28e2ec89e8 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1399,7 +1399,7 @@ static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/quorum.c b/block/quorum.c index d04da4f430..272f9a5b77 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -867,30 +867,13 @@ static QemuOptsList quorum_runtime_opts = { }, }; -static int parse_read_pattern(const char *opt) -{ - int i; - - if (!opt) { - /* Set quorum as default */ - return QUORUM_READ_PATTERN_QUORUM; - } - - for (i = 0; i < QUORUM_READ_PATTERN__MAX; i++) { - if (!strcmp(opt, QuorumReadPattern_lookup[i])) { - return i; - } - } - - return -EINVAL; -} - static int quorum_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVQuorumState *s = bs->opaque; Error *local_err = NULL; QemuOpts *opts = NULL; + const char *pattern_str; bool *opened; int i; int ret = 0; @@ -925,7 +908,13 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, goto exit; } - ret = parse_read_pattern(qemu_opt_get(opts, QUORUM_OPT_READ_PATTERN)); + pattern_str = qemu_opt_get(opts, QUORUM_OPT_READ_PATTERN); + if (!pattern_str) { + ret = QUORUM_READ_PATTERN_QUORUM; + } else { + ret = qapi_enum_parse(&QuorumReadPattern_lookup, pattern_str, + -EINVAL, NULL); + } if (ret < 0) { error_setg(&local_err, "Please set read-pattern as fifo or quorum"); goto exit; diff --git a/block/rbd.c b/block/rbd.c index 9c3aa638e7..144f350e1f 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -944,7 +944,7 @@ static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/block/sheepdog.c b/block/sheepdog.c index abb2e79065..1052098ec5 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2176,7 +2176,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset, if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", - PreallocMode_lookup[prealloc]); + PreallocMode_str(prealloc)); return -ENOTSUP; } diff --git a/blockdev.c b/blockdev.c index 02cd69bc21..796beaed94 100644 --- a/blockdev.c +++ b/blockdev.c @@ -44,7 +44,6 @@ #include "qapi-visit.h" #include "qapi/qmp/qerror.h" #include "qapi/qobject-output-visitor.h" -#include "qapi/util.h" #include "sysemu/sysemu.h" #include "block/block_int.h" #include "qmp-commands.h" @@ -438,9 +437,8 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags, if (detect_zeroes) { *detect_zeroes = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, qemu_opt_get(opts, "detect-zeroes"), - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_error); if (local_error) { @@ -1468,8 +1466,8 @@ static int action_check_completion_mode(BlkActionState *s, Error **errp) error_setg(errp, "Action '%s' does not support Transaction property " "completion-mode = %s", - TransactionActionKind_lookup[s->action->type], - ActionCompletionMode_lookup[s->txn_props->completion_mode]); + TransactionActionKind_str(s->action->type), + ActionCompletionMode_str(s->txn_props->completion_mode)); return -1; } return 0; diff --git a/blockjob.c b/blockjob.c index 70a78188b7..3a0c49137e 100644 --- a/blockjob.c +++ b/blockjob.c @@ -208,7 +208,7 @@ static char *child_job_get_parent_desc(BdrvChild *c) { BlockJob *job = c->opaque; return g_strdup_printf("%s job '%s'", - BlockJobType_lookup[job->driver->job_type], + BlockJobType_str(job->driver->job_type), job->id); } @@ -553,7 +553,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp) return NULL; } info = g_new0(BlockJobInfo, 1); - info->type = g_strdup(BlockJobType_lookup[job->driver->job_type]); + info->type = g_strdup(BlockJobType_str(job->driver->job_type)); info->device = g_strdup(job->id); info->len = job->len; info->busy = job->busy; @@ -666,7 +666,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, job->refcnt = 1; error_setg(&job->blocker, "block device is in use by block job: %s", - BlockJobType_lookup[driver->job_type]); + BlockJobType_str(driver->job_type)); block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort); bs->job = job; diff --git a/chardev/char.c b/chardev/char.c index 5d283b90d3..b6fd5eb6a6 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -931,7 +931,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend, ChardevReturn *ret; Chardev *chr; - cc = char_get_class(ChardevBackendKind_lookup[backend->type], errp); + cc = char_get_class(ChardevBackendKind_str(backend->type), errp); if (!cc) { return NULL; } @@ -989,7 +989,7 @@ ChardevReturn *qmp_chardev_change(const char *id, ChardevBackend *backend, return NULL; } - cc = char_get_class(ChardevBackendKind_lookup[backend->type], errp); + cc = char_get_class(ChardevBackendKind_str(backend->type), errp); if (!cc) { return NULL; } diff --git a/crypto/block-luks.c b/crypto/block-luks.c index afb8543108..36bc856084 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -257,47 +257,41 @@ qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, } error_setg(errp, "Algorithm '%s' not supported", - QCryptoCipherAlgorithm_lookup[alg]); + QCryptoCipherAlgorithm_str(alg)); return NULL; } /* XXX replace with qapi_enum_parse() in future, when we can * make that function emit a more friendly error message */ static int qcrypto_block_luks_name_lookup(const char *name, - const char *const *map, - size_t maplen, + const QEnumLookup *map, const char *type, Error **errp) { - size_t i; - for (i = 0; i < maplen; i++) { - if (g_str_equal(map[i], name)) { - return i; - } - } + int ret = qapi_enum_parse(map, name, -1, NULL); - error_setg(errp, "%s %s not supported", type, name); - return 0; + if (ret < 0) { + error_setg(errp, "%s %s not supported", type, name); + return 0; + } + return ret; } #define qcrypto_block_luks_cipher_mode_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoCipherMode_lookup, \ - QCRYPTO_CIPHER_MODE__MAX, \ + &QCryptoCipherMode_lookup, \ "Cipher mode", \ errp) #define qcrypto_block_luks_hash_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoHashAlgorithm_lookup, \ - QCRYPTO_HASH_ALG__MAX, \ + &QCryptoHashAlgorithm_lookup, \ "Hash algorithm", \ errp) #define qcrypto_block_luks_ivgen_name_lookup(name, errp) \ qcrypto_block_luks_name_lookup(name, \ - QCryptoIVGenAlgorithm_lookup, \ - QCRYPTO_IVGEN_ALG__MAX, \ + &QCryptoIVGenAlgorithm_lookup, \ "IV generator", \ errp) @@ -398,7 +392,7 @@ qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, break; default: error_setg(errp, "Cipher %s not supported with essiv", - QCryptoCipherAlgorithm_lookup[cipher]); + QCryptoCipherAlgorithm_str(cipher)); return 0; } } @@ -968,16 +962,16 @@ qcrypto_block_luks_create(QCryptoBlock *block, goto error; } - cipher_mode = QCryptoCipherMode_lookup[luks_opts.cipher_mode]; - ivgen_alg = QCryptoIVGenAlgorithm_lookup[luks_opts.ivgen_alg]; + cipher_mode = QCryptoCipherMode_str(luks_opts.cipher_mode); + ivgen_alg = QCryptoIVGenAlgorithm_str(luks_opts.ivgen_alg); if (luks_opts.has_ivgen_hash_alg) { - ivgen_hash_alg = QCryptoHashAlgorithm_lookup[luks_opts.ivgen_hash_alg]; + ivgen_hash_alg = QCryptoHashAlgorithm_str(luks_opts.ivgen_hash_alg); cipher_mode_spec = g_strdup_printf("%s-%s:%s", cipher_mode, ivgen_alg, ivgen_hash_alg); } else { cipher_mode_spec = g_strdup_printf("%s-%s", cipher_mode, ivgen_alg); } - hash_alg = QCryptoHashAlgorithm_lookup[luks_opts.hash_alg]; + hash_alg = QCryptoHashAlgorithm_str(luks_opts.hash_alg); if (strlen(cipher_alg) >= QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN) { diff --git a/crypto/block.c b/crypto/block.c index b097d451af..c382393d9a 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -61,7 +61,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || !qcrypto_block_drivers[options->format]) { error_setg(errp, "Unsupported block driver %s", - QCryptoBlockFormat_lookup[options->format]); + QCryptoBlockFormat_str(options->format)); g_free(block); return NULL; } @@ -92,7 +92,7 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || !qcrypto_block_drivers[options->format]) { error_setg(errp, "Unsupported block driver %s", - QCryptoBlockFormat_lookup[options->format]); + QCryptoBlockFormat_str(options->format)); g_free(block); return NULL; } diff --git a/crypto/cipher-afalg.c b/crypto/cipher-afalg.c index 01343b2b7c..cd72284690 100644 --- a/crypto/cipher-afalg.c +++ b/crypto/cipher-afalg.c @@ -52,7 +52,7 @@ qcrypto_afalg_cipher_format_name(QCryptoCipherAlgorithm alg, return NULL; } - mode_name = QCryptoCipherMode_lookup[mode]; + mode_name = QCryptoCipherMode_str(mode); name = g_strdup_printf("%s(%s)", mode_name, alg_name); return name; diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c index 16a36d4532..d8c811fd33 100644 --- a/crypto/cipher-builtin.c +++ b/crypto/cipher-builtin.c @@ -247,7 +247,7 @@ qcrypto_cipher_init_aes(QCryptoCipherMode mode, mode != QCRYPTO_CIPHER_MODE_ECB && mode != QCRYPTO_CIPHER_MODE_XTS) { error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[mode]); + QCryptoCipherMode_str(mode)); return NULL; } @@ -379,7 +379,7 @@ qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode, if (mode != QCRYPTO_CIPHER_MODE_ECB) { error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[mode]); + QCryptoCipherMode_str(mode)); return NULL; } @@ -440,7 +440,7 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, break; default: error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[mode]); + QCryptoCipherMode_str(mode)); return NULL; } @@ -460,7 +460,7 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, default: error_setg(errp, "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_lookup[alg]); + QCryptoCipherAlgorithm_str(alg)); return NULL; } diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c index 0489147398..10d75da75d 100644 --- a/crypto/cipher-gcrypt.c +++ b/crypto/cipher-gcrypt.c @@ -105,7 +105,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, break; default: error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[mode]); + QCryptoCipherMode_str(mode)); return NULL; } @@ -160,7 +160,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, default: error_setg(errp, "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_lookup[alg]); + QCryptoCipherAlgorithm_str(alg)); return NULL; } diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c index c51f119cbc..3848cb3b3a 100644 --- a/crypto/cipher-nettle.c +++ b/crypto/cipher-nettle.c @@ -281,7 +281,7 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, break; default: error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[mode]); + QCryptoCipherMode_str(mode)); return NULL; } @@ -420,7 +420,7 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, default: error_setg(errp, "Unsupported cipher algorithm %s", - QCryptoCipherAlgorithm_lookup[alg]); + QCryptoCipherAlgorithm_str(alg)); goto error; } @@ -491,7 +491,7 @@ qcrypto_nettle_cipher_encrypt(QCryptoCipher *cipher, default: error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[cipher->mode]); + QCryptoCipherMode_str(cipher->mode)); return -1; } return 0; @@ -537,7 +537,7 @@ qcrypto_nettle_cipher_decrypt(QCryptoCipher *cipher, default: error_setg(errp, "Unsupported cipher mode %s", - QCryptoCipherMode_lookup[cipher->mode]); + QCryptoCipherMode_str(cipher->mode)); return -1; } return 0; diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c index 76ca61ba24..0c6f979711 100644 --- a/crypto/hmac-gcrypt.c +++ b/crypto/hmac-gcrypt.c @@ -52,7 +52,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_lookup[alg]); + QCryptoHashAlgorithm_str(alg)); return NULL; } diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c index 8cf6b221ed..a6c1730291 100644 --- a/crypto/hmac-glib.c +++ b/crypto/hmac-glib.c @@ -58,7 +58,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_lookup[alg]); + QCryptoHashAlgorithm_str(alg)); return NULL; } diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c index 1d5a915f03..ec2d61bdde 100644 --- a/crypto/hmac-nettle.c +++ b/crypto/hmac-nettle.c @@ -106,7 +106,7 @@ void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg, if (!qcrypto_hmac_supports(alg)) { error_setg(errp, "Unsupported hmac algorithm %s", - QCryptoHashAlgorithm_lookup[alg]); + QCryptoHashAlgorithm_str(alg)); return NULL; } diff --git a/crypto/pbkdf-gcrypt.c b/crypto/pbkdf-gcrypt.c index 40289858bf..54ca0d9c75 100644 --- a/crypto/pbkdf-gcrypt.c +++ b/crypto/pbkdf-gcrypt.c @@ -68,7 +68,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, hash_map[hash] == GCRY_MD_NONE) { error_setg_errno(errp, ENOSYS, "PBKDF does not support hash algorithm %s", - QCryptoHashAlgorithm_lookup[hash]); + QCryptoHashAlgorithm_str(hash)); return -1; } diff --git a/crypto/pbkdf-nettle.c b/crypto/pbkdf-nettle.c index 6fb2671656..212b3e816b 100644 --- a/crypto/pbkdf-nettle.c +++ b/crypto/pbkdf-nettle.c @@ -110,7 +110,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, default: error_setg_errno(errp, ENOSYS, "PBKDF does not support hash algorithm %s", - QCryptoHashAlgorithm_lookup[hash]); + QCryptoHashAlgorithm_str(hash)); return -1; } return 0; diff --git a/crypto/secret.c b/crypto/secret.c index 285ab7a63c..388abd7df5 100644 --- a/crypto/secret.c +++ b/crypto/secret.c @@ -378,7 +378,7 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data) NULL); object_class_property_add_enum(oc, "format", "QCryptoSecretFormat", - QCryptoSecretFormat_lookup, + &QCryptoSecretFormat_lookup, qcrypto_secret_prop_get_format, qcrypto_secret_prop_set_format, NULL); diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c index a8965531b6..3cd41035bb 100644 --- a/crypto/tlscreds.c +++ b/crypto/tlscreds.c @@ -233,7 +233,7 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, void *data) NULL); object_class_property_add_enum(oc, "endpoint", "QCryptoTLSCredsEndpoint", - QCryptoTLSCredsEndpoint_lookup, + &QCryptoTLSCredsEndpoint_lookup, qcrypto_tls_creds_prop_get_endpoint, qcrypto_tls_creds_prop_set_endpoint, NULL); diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 9903ac4c19..f04c63fe82 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -957,6 +957,8 @@ Example: typedef struct UserDefOneList UserDefOneList; + typedef struct q_obj_my_command_arg q_obj_my_command_arg; + struct UserDefOne { int64_t integer; bool has_string; @@ -972,6 +974,10 @@ Example: void qapi_free_UserDefOneList(UserDefOneList *obj); + struct q_obj_my_command_arg { + UserDefOneList *arg1; + }; + #endif $ cat qapi-generated/example-qapi-types.c [Uninteresting stuff omitted...] @@ -1036,6 +1042,8 @@ Example: void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp); void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp); + void visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp); + #endif $ cat qapi-generated/example-qapi-visit.c [Uninteresting stuff omitted...] @@ -1104,6 +1112,9 @@ Example: } } + if (!err) { + visit_check_list(v, &err); + } visit_end_list(v, (void **)obj); if (err && visit_is_input(v)) { qapi_free_UserDefOneList(*obj); @@ -1113,6 +1124,19 @@ Example: error_propagate(errp, err); } + void visit_type_q_obj_my_command_arg_members(Visitor *v, q_obj_my_command_arg *obj, Error **errp) + { + Error *err = NULL; + + visit_type_UserDefOneList(v, "arg1", &obj->arg1, &err); + if (err) { + goto out; + } + + out: + error_propagate(errp, err); + } + === scripts/qapi-commands.py === Used to generate the marshaling/dispatch functions for the commands @@ -1145,9 +1169,12 @@ Example: #include "example-qapi-types.h" #include "qapi/qmp/qdict.h" + #include "qapi/qmp/dispatch.h" #include "qapi/error.h" + void example_qmp_init_marshal(QmpCommandList *cmds); UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp); + void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp); #endif $ cat qapi-generated/example-qmp-marshal.c @@ -1170,19 +1197,19 @@ Example: visit_free(v); } - static void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp) + void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp) { Error *err = NULL; UserDefOne *retval; Visitor *v; - UserDefOneList *arg1 = NULL; + q_obj_my_command_arg arg = {0}; v = qobject_input_visitor_new(QOBJECT(args)); visit_start_struct(v, NULL, NULL, 0, &err); if (err) { goto out; } - visit_type_UserDefOneList(v, "arg1", &arg1, &err); + visit_type_q_obj_my_command_arg_members(v, &arg, &err); if (!err) { visit_check_struct(v, &err); } @@ -1191,7 +1218,7 @@ Example: goto out; } - retval = qmp_my_command(arg1, &err); + retval = qmp_my_command(arg.arg1, &err); if (err) { goto out; } @@ -1203,17 +1230,18 @@ Example: visit_free(v); v = qapi_dealloc_visitor_new(); visit_start_struct(v, NULL, NULL, 0, NULL); - visit_type_UserDefOneList(v, "arg1", &arg1, NULL); + visit_type_q_obj_my_command_arg_members(v, &arg, NULL); visit_end_struct(v, NULL); visit_free(v); } - static void qmp_init_marshal(void) + void example_qmp_init_marshal(QmpCommandList *cmds) { - qmp_register_command("my-command", qmp_marshal_my_command, QCO_NO_OPTIONS); - } + QTAILQ_INIT(cmds); - qapi_init(qmp_init_marshal); + qmp_register_command(cmds, "my-command", + qmp_marshal_my_command, QCO_NO_OPTIONS); + } === scripts/qapi-event.py === @@ -1247,6 +1275,9 @@ Example: EXAMPLE_QAPI_EVENT__MAX = 1, } example_QAPIEvent; + #define example_QAPIEvent_str(val) \ + qapi_enum_lookup(example_QAPIEvent_lookup, (val)) + extern const char *const example_QAPIEvent_lookup[]; #endif @@ -1258,6 +1289,7 @@ Example: QDict *qmp; Error *err = NULL; QMPEventFuncEmit emit; + emit = qmp_event_get_func_emit(); if (!emit) { return; @@ -31,7 +31,6 @@ #include "qapi/qmp/qerror.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" -#include "qapi/util.h" #include "qapi-visit.h" #include "qom/object_interfaces.h" #include "ui/console.h" @@ -107,7 +106,7 @@ void hmp_info_status(Monitor *mon, const QDict *qdict) info->singlestep ? " (single step mode)" : ""); if (!info->running && info->status != RUN_STATE_PAUSED) { - monitor_printf(mon, " (%s)", RunState_lookup[info->status]); + monitor_printf(mon, " (%s)", RunState_str(info->status)); } monitor_printf(mon, "\n"); @@ -172,7 +171,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) monitor_printf(mon, "capabilities: "); for (cap = caps; cap; cap = cap->next) { monitor_printf(mon, "%s: %s ", - MigrationCapability_lookup[cap->value->capability], + MigrationCapability_str(cap->value->capability), cap->value->state ? "on" : "off"); } monitor_printf(mon, "\n"); @@ -180,7 +179,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) if (info->has_status) { monitor_printf(mon, "Migration status: %s", - MigrationStatus_lookup[info->status]); + MigrationStatus_str(info->status)); if (info->status == MIGRATION_STATUS_FAILED && info->has_error_desc) { monitor_printf(mon, " (%s)\n", info->error_desc); @@ -278,7 +277,7 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict) if (caps) { for (cap = caps; cap; cap = cap->next) { monitor_printf(mon, "%s: %s\n", - MigrationCapability_lookup[cap->value->capability], + MigrationCapability_str(cap->value->capability), cap->value->state ? "on" : "off"); } } @@ -295,48 +294,48 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) if (params) { assert(params->has_compress_level); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_LEVEL], + MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_LEVEL), params->compress_level); assert(params->has_compress_threads); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_COMPRESS_THREADS], + MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_THREADS), params->compress_threads); assert(params->has_decompress_threads); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_DECOMPRESS_THREADS], + MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), params->decompress_threads); assert(params->has_cpu_throttle_initial); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL], + MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL), params->cpu_throttle_initial); assert(params->has_cpu_throttle_increment); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT], + MigrationParameter_str(MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT), params->cpu_throttle_increment); assert(params->has_tls_creds); monitor_printf(mon, "%s: '%s'\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_CREDS], + MigrationParameter_str(MIGRATION_PARAMETER_TLS_CREDS), params->tls_creds); assert(params->has_tls_hostname); monitor_printf(mon, "%s: '%s'\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME], + MigrationParameter_str(MIGRATION_PARAMETER_TLS_HOSTNAME), params->tls_hostname); assert(params->has_max_bandwidth); monitor_printf(mon, "%s: %" PRId64 " bytes/second\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_MAX_BANDWIDTH], + MigrationParameter_str(MIGRATION_PARAMETER_MAX_BANDWIDTH), params->max_bandwidth); assert(params->has_downtime_limit); monitor_printf(mon, "%s: %" PRId64 " milliseconds\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_DOWNTIME_LIMIT], + MigrationParameter_str(MIGRATION_PARAMETER_DOWNTIME_LIMIT), params->downtime_limit); assert(params->has_x_checkpoint_delay); monitor_printf(mon, "%s: %" PRId64 "\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY], + MigrationParameter_str(MIGRATION_PARAMETER_X_CHECKPOINT_DELAY), params->x_checkpoint_delay); assert(params->has_block_incremental); monitor_printf(mon, "%s: %s\n", - MigrationParameter_lookup[MIGRATION_PARAMETER_BLOCK_INCREMENTAL], - params->block_incremental ? "on" : "off"); + MigrationParameter_str(MIGRATION_PARAMETER_BLOCK_INCREMENTAL), + params->block_incremental ? "on" : "off"); } qapi_free_MigrationParameters(params); @@ -432,7 +431,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info, } if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) { monitor_printf(mon, " I/O status: %s\n", - BlockDeviceIoStatus_lookup[info->io_status]); + BlockDeviceIoStatus_str(info->io_status)); } if (info->removable) { @@ -462,7 +461,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info, if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { monitor_printf(mon, " Detect zeroes: %s\n", - BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]); + BlockdevDetectZeroesOptions_str(inserted->detect_zeroes)); } if (inserted->bps || inserted->bps_rd || inserted->bps_wr || @@ -613,7 +612,7 @@ static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info, name, info->host, info->service, - NetworkAddressFamily_lookup[info->family], + NetworkAddressFamily_str(info->family), info->websocket ? " (Websocket)" : ""); } @@ -623,8 +622,8 @@ static void hmp_info_vnc_authcrypt(Monitor *mon, const char *indent, VncVencryptSubAuth *vencrypt) { monitor_printf(mon, "%sAuth: %s (Sub: %s)\n", indent, - VncPrimaryAuth_lookup[auth], - vencrypt ? VncVencryptSubAuth_lookup[*vencrypt] : "none"); + VncPrimaryAuth_str(auth), + vencrypt ? VncVencryptSubAuth_str(*vencrypt) : "none"); } static void hmp_info_vnc_clients(Monitor *mon, VncClientInfoList *client) @@ -739,7 +738,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) monitor_printf(mon, " auth: %s\n", info->auth); monitor_printf(mon, " compiled: %s\n", info->compiled_version); monitor_printf(mon, " mouse-mode: %s\n", - SpiceQueryMouseMode_lookup[info->mouse_mode]); + SpiceQueryMouseMode_str(info->mouse_mode)); if (!info->has_channels || info->channels == NULL) { monitor_printf(mon, "Channels: none\n"); @@ -1010,10 +1009,10 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) for (info = info_list; info; info = info->next) { TPMInfo *ti = info->value; monitor_printf(mon, " tpm%d: model=%s\n", - c, TpmModel_lookup[ti->model]); + c, TpmModel_str(ti->model)); monitor_printf(mon, " \\ %s: type=%s", - ti->id, TpmTypeOptionsKind_lookup[ti->options->type]); + ti->id, TpmTypeOptionsKind_str(ti->options->type)); switch (ti->options->type) { case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH: @@ -1527,23 +1526,20 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) bool state = qdict_get_bool(qdict, "state"); Error *err = NULL; MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); - int i; + int val; - for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { - if (strcmp(cap, MigrationCapability_lookup[i]) == 0) { - caps->value = g_malloc0(sizeof(*caps->value)); - caps->value->capability = i; - caps->value->state = state; - caps->next = NULL; - qmp_migrate_set_capabilities(caps, &err); - break; - } + val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err); + if (val < 0) { + goto end; } - if (i == MIGRATION_CAPABILITY__MAX) { - error_setg(&err, QERR_INVALID_PARAMETER, cap); - } + caps->value = g_malloc0(sizeof(*caps->value)); + caps->value->capability = val; + caps->value->state = state; + caps->next = NULL; + qmp_migrate_set_capabilities(caps, &err); +end: qapi_free_MigrationCapabilityStatusList(caps); if (err) { @@ -1559,84 +1555,82 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); uint64_t valuebw = 0; Error *err = NULL; - int i, ret; - - for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { - if (strcmp(param, MigrationParameter_lookup[i]) == 0) { - switch (i) { - case MIGRATION_PARAMETER_COMPRESS_LEVEL: - p->has_compress_level = true; - visit_type_int(v, param, &p->compress_level, &err); - break; - case MIGRATION_PARAMETER_COMPRESS_THREADS: - p->has_compress_threads = true; - visit_type_int(v, param, &p->compress_threads, &err); - break; - case MIGRATION_PARAMETER_DECOMPRESS_THREADS: - p->has_decompress_threads = true; - visit_type_int(v, param, &p->decompress_threads, &err); - break; - case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: - p->has_cpu_throttle_initial = true; - visit_type_int(v, param, &p->cpu_throttle_initial, &err); - break; - case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: - p->has_cpu_throttle_increment = true; - visit_type_int(v, param, &p->cpu_throttle_increment, &err); - break; - case MIGRATION_PARAMETER_TLS_CREDS: - p->has_tls_creds = true; - p->tls_creds = g_new0(StrOrNull, 1); - p->tls_creds->type = QTYPE_QSTRING; - visit_type_str(v, param, &p->tls_creds->u.s, &err); - break; - case MIGRATION_PARAMETER_TLS_HOSTNAME: - p->has_tls_hostname = true; - p->tls_hostname = g_new0(StrOrNull, 1); - p->tls_hostname->type = QTYPE_QSTRING; - visit_type_str(v, param, &p->tls_hostname->u.s, &err); - break; - case MIGRATION_PARAMETER_MAX_BANDWIDTH: - p->has_max_bandwidth = true; - /* - * Can't use visit_type_size() here, because it - * defaults to Bytes rather than Mebibytes. - */ - ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); - if (ret < 0 || valuebw > INT64_MAX - || (size_t)valuebw != valuebw) { - error_setg(&err, "Invalid size %s", valuestr); - break; - } - p->max_bandwidth = valuebw; - break; - case MIGRATION_PARAMETER_DOWNTIME_LIMIT: - p->has_downtime_limit = true; - visit_type_int(v, param, &p->downtime_limit, &err); - break; - case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: - p->has_x_checkpoint_delay = true; - visit_type_int(v, param, &p->x_checkpoint_delay, &err); - break; - case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: - p->has_block_incremental = true; - visit_type_bool(v, param, &p->block_incremental, &err); - break; - } - - if (err) { - goto cleanup; - } - - qmp_migrate_set_parameters(p, &err); + int val, ret; + + val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err); + if (val < 0) { + goto cleanup; + } + + switch (val) { + case MIGRATION_PARAMETER_COMPRESS_LEVEL: + p->has_compress_level = true; + visit_type_int(v, param, &p->compress_level, &err); + break; + case MIGRATION_PARAMETER_COMPRESS_THREADS: + p->has_compress_threads = true; + visit_type_int(v, param, &p->compress_threads, &err); + break; + case MIGRATION_PARAMETER_DECOMPRESS_THREADS: + p->has_decompress_threads = true; + visit_type_int(v, param, &p->decompress_threads, &err); + break; + case MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL: + p->has_cpu_throttle_initial = true; + visit_type_int(v, param, &p->cpu_throttle_initial, &err); + break; + case MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT: + p->has_cpu_throttle_increment = true; + visit_type_int(v, param, &p->cpu_throttle_increment, &err); + break; + case MIGRATION_PARAMETER_TLS_CREDS: + p->has_tls_creds = true; + p->tls_creds = g_new0(StrOrNull, 1); + p->tls_creds->type = QTYPE_QSTRING; + visit_type_str(v, param, &p->tls_creds->u.s, &err); + break; + case MIGRATION_PARAMETER_TLS_HOSTNAME: + p->has_tls_hostname = true; + p->tls_hostname = g_new0(StrOrNull, 1); + p->tls_hostname->type = QTYPE_QSTRING; + visit_type_str(v, param, &p->tls_hostname->u.s, &err); + break; + case MIGRATION_PARAMETER_MAX_BANDWIDTH: + p->has_max_bandwidth = true; + /* + * Can't use visit_type_size() here, because it + * defaults to Bytes rather than Mebibytes. + */ + ret = qemu_strtosz_MiB(valuestr, NULL, &valuebw); + if (ret < 0 || valuebw > INT64_MAX + || (size_t)valuebw != valuebw) { + error_setg(&err, "Invalid size %s", valuestr); break; } + p->max_bandwidth = valuebw; + break; + case MIGRATION_PARAMETER_DOWNTIME_LIMIT: + p->has_downtime_limit = true; + visit_type_int(v, param, &p->downtime_limit, &err); + break; + case MIGRATION_PARAMETER_X_CHECKPOINT_DELAY: + p->has_x_checkpoint_delay = true; + visit_type_int(v, param, &p->x_checkpoint_delay, &err); + break; + case MIGRATION_PARAMETER_BLOCK_INCREMENTAL: + p->has_block_incremental = true; + visit_type_bool(v, param, &p->block_incremental, &err); + break; + default: + assert(0); } - if (i == MIGRATION_PARAMETER__MAX) { - error_setg(&err, QERR_INVALID_PARAMETER, param); + if (err) { + goto cleanup; } + qmp_migrate_set_parameters(p, &err); + cleanup: qapi_free_MigrateSetParameters(p); visit_free(v); @@ -1741,8 +1735,8 @@ void hmp_change(Monitor *mon, const QDict *qdict) } else { if (read_only) { read_only_mode = - qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, - read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX, + qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup, + read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); if (err) { hmp_handle_error(mon, &err); @@ -2374,7 +2368,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict) monitor_printf(mon, " prealloc: %s\n", m->value->prealloc ? "true" : "false"); monitor_printf(mon, " policy: %s\n", - HostMemPolicy_lookup[m->value->policy]); + HostMemPolicy_str(m->value->policy)); visit_complete(v, &str); monitor_printf(mon, " host nodes: %s\n", str); @@ -2405,7 +2399,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) di = value->u.dimm.data; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", - MemoryDeviceInfoKind_lookup[value->type], + MemoryDeviceInfoKind_str(value->type), di->id ? di->id : ""); monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); @@ -2799,7 +2793,7 @@ void hmp_info_dump(Monitor *mon, const QDict *qdict) DumpQueryResult *result = qmp_query_dump(NULL); assert(result && result->status < DUMP_STATUS__MAX); - monitor_printf(mon, "Status: %s\n", DumpStatus_lookup[result->status]); + monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); if (result->status == DUMP_STATUS_ACTIVE) { float percent = 0; diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 401129073b..db40e174c9 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -392,9 +392,9 @@ static int pick_geometry(FDrive *drv) FLOPPY_DPRINTF("User requested floppy drive type '%s', " "but inserted medium appears to be a " "%"PRId64" sector '%s' type\n", - FloppyDriveType_lookup[drv->drive], + FloppyDriveType_str(drv->drive), nb_sectors, - FloppyDriveType_lookup[parse->drive]); + FloppyDriveType_str(parse->drive)); } match = type_match; } @@ -403,7 +403,7 @@ static int pick_geometry(FDrive *drv) if (match == -1) { error_setg(&error_abort, "No candidate geometries present in table " " for floppy drive type '%s'", - FloppyDriveType_lookup[drv->drive]); + FloppyDriveType_str(drv->drive)); } parse = &(fd_formats[match]); diff --git a/hw/char/escc.c b/hw/char/escc.c index 1aca564e33..3ab831a6a7 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -848,7 +848,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src, assert(evt->type == INPUT_EVENT_KIND_KEY); key = evt->u.key.data; qcode = qemu_input_key_value_to_qcode(key->key); - trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode], + trace_escc_sunkbd_event_in(qcode, QKeyCode_str(qcode), key->down); if (qcode == Q_KEY_CODE_CAPS_LOCK) { diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 078fc5d239..1dc80fcea2 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -72,7 +72,9 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque, static void set_default_value_enum(Object *obj, const Property *prop) { - object_property_set_str(obj, prop->info->enum_table[prop->defval.i], + object_property_set_str(obj, + qapi_enum_lookup(prop->info->enum_table, + prop->defval.i), prop->name, &error_abort); } @@ -585,7 +587,7 @@ const PropertyInfo qdev_prop_macaddr = { const PropertyInfo qdev_prop_on_off_auto = { .name = "OnOffAuto", .description = "on/off/auto", - .enum_table = OnOffAuto_lookup, + .enum_table = &OnOffAuto_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -597,7 +599,7 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); const PropertyInfo qdev_prop_losttickpolicy = { .name = "LostTickPolicy", - .enum_table = LostTickPolicy_lookup, + .enum_table = &LostTickPolicy_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -611,7 +613,7 @@ const PropertyInfo qdev_prop_blockdev_on_error = { .name = "BlockdevOnError", .description = "Error handling policy, " "report/ignore/enospc/stop/auto", - .enum_table = BlockdevOnError_lookup, + .enum_table = &BlockdevOnError_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -625,7 +627,7 @@ const PropertyInfo qdev_prop_bios_chs_trans = { .name = "BiosAtaTranslation", .description = "Logical CHS translation algorithm, " "auto/none/lba/large/rechs", - .enum_table = BiosAtaTranslation_lookup, + .enum_table = &BiosAtaTranslation_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -637,7 +639,7 @@ const PropertyInfo qdev_prop_fdc_drive_type = { .name = "FdcDriveType", .description = "FDC drive type, " "144/288/120/none/auto", - .enum_table = FloppyDriveType_lookup, + .enum_table = &FloppyDriveType_lookup, .get = get_enum, .set = set_enum, .set_default_value = set_default_value_enum, @@ -1095,7 +1097,8 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value) Property *prop; prop = qdev_prop_find(dev, name); - object_property_set_str(OBJECT(dev), prop->info->enum_table[value], + object_property_set_str(OBJECT(dev), + qapi_enum_lookup(prop->info->enum_table, value), name, &error_abort); } diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 46c038110c..4d3afc1b14 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -209,7 +209,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, } else { if (key->down) { fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__, - qcode, QKeyCode_lookup[qcode]); + qcode, QKeyCode_str(qcode)); } } break; @@ -224,7 +224,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, if (btn->down) { fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, btn->button, - InputButton_lookup[btn->button]); + InputButton_str(btn->button)); } } break; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index ae317286a4..089146197f 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -249,7 +249,7 @@ struct Property { struct PropertyInfo { const char *name; const char *description; - const char * const *enum_table; + const QEnumLookup *enum_table; int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); void (*set_default_value)(Object *obj, const Property *prop); void (*create)(Object *obj, Property *prop, Error **errp); diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 363e431106..6588c7f0c8 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -53,13 +53,15 @@ void qdict_destroy_obj(QObject *obj); #define qdict_put(qdict, key, obj) \ qdict_put_obj(qdict, key, QOBJECT(obj)) -/* Helpers for int, bool, and string */ +/* Helpers for int, bool, null, and string */ #define qdict_put_int(qdict, key, value) \ qdict_put(qdict, key, qnum_from_int(value)) #define qdict_put_bool(qdict, key, value) \ qdict_put(qdict, key, qbool_from_bool(value)) #define qdict_put_str(qdict, key, value) \ qdict_put(qdict, key, qstring_from_str(value)) +#define qdict_put_null(qdict, key) \ + qdict_put(qdict, key, qnull()) /* High level helpers */ double qdict_get_double(const QDict *qdict, const char *key); diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h new file mode 100644 index 0000000000..b18406bce9 --- /dev/null +++ b/include/qapi/qmp/qlit.h @@ -0,0 +1,54 @@ +/* + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * Markus Armbruster <armbru@redhat.com> + * Marc-André Lureau <marcandre.lureau@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ +#ifndef QLIT_H +#define QLIT_H + +#include "qapi-types.h" +#include "qobject.h" + +typedef struct QLitDictEntry QLitDictEntry; +typedef struct QLitObject QLitObject; + +struct QLitObject { + int type; + union { + bool qbool; + int64_t qnum; + const char *qstr; + QLitDictEntry *qdict; + QLitObject *qlist; + } value; +}; + +struct QLitDictEntry { + const char *key; + QLitObject value; +}; + +#define QLIT_QNULL \ + { .type = QTYPE_QNULL } +#define QLIT_QBOOL(val) \ + { .type = QTYPE_QBOOL, .value.qbool = (val) } +#define QLIT_QNUM(val) \ + { .type = QTYPE_QNUM, .value.qnum = (val) } +#define QLIT_QSTR(val) \ + { .type = QTYPE_QSTRING, .value.qstr = (val) } +#define QLIT_QDICT(val) \ + { .type = QTYPE_QDICT, .value.qdict = (val) } +#define QLIT_QLIST(val) \ + { .type = QTYPE_QLIST, .value.qlist = (val) } + +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs); + +#endif /* QLIT_H */ diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h index 09d745c490..d6b0791139 100644 --- a/include/qapi/qmp/qnum.h +++ b/include/qapi/qmp/qnum.h @@ -23,6 +23,27 @@ typedef enum { QNUM_DOUBLE } QNumKind; +/* + * QNum encapsulates how our dialect of JSON fills in the blanks left + * by the JSON specification (RFC 7159) regarding numbers. + * + * Conceptually, we treat number as an abstract type with three + * concrete subtypes: floating-point, signed integer, unsigned + * integer. QNum implements this as a discriminated union of double, + * int64_t, uint64_t. + * + * The JSON parser picks the subtype as follows. If the number has a + * decimal point or an exponent, it is floating-point. Else if it + * fits into int64_t, it's signed integer. Else if it fits into + * uint64_t, it's unsigned integer. Else it's floating-point. + * + * Any number can serve as double: qnum_get_double() converts under + * the hood. + * + * An integer can serve as signed / unsigned integer as long as it is + * in range: qnum_get_try_int() / qnum_get_try_uint() check range and + * convert under the hood. + */ typedef struct QNum { QObject base; QNumKind kind; diff --git a/include/qapi/util.h b/include/qapi/util.h index 7436ed815c..a7c3c64148 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -11,8 +11,14 @@ #ifndef QAPI_UTIL_H #define QAPI_UTIL_H -int qapi_enum_parse(const char * const lookup[], const char *buf, - int max, int def, Error **errp); +typedef struct QEnumLookup { + const char *const *array; + int size; +} QEnumLookup; + +const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); +int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, + int def, Error **errp); int parse_qapi_name(const char *name, bool complete); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 0f3b8cb459..62a51a54cb 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -469,7 +469,7 @@ bool visit_optional(Visitor *v, const char *name, bool *present); * that visit_type_str() must have no unwelcome side effects. */ void visit_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp); + const QEnumLookup *lookup, Error **errp); /* * Check if visitor is an input visitor. diff --git a/include/qom/object.h b/include/qom/object.h index 1b828994fa..f3e5cff37a 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1415,14 +1415,14 @@ void object_class_property_add_bool(ObjectClass *klass, const char *name, */ void object_property_add_enum(Object *obj, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp); void object_class_property_add_enum(ObjectClass *klass, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp); diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index b58f52d39f..b0a9731aee 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -226,7 +226,7 @@ TPMVersion tpm_backend_get_tpm_version(TPMBackend *s); TPMBackend *qemu_find_tpm(const char *id); const TPMDriverOps *tpm_get_backend_driver(const char *type); -int tpm_register_model(enum TpmModel model); -int tpm_register_driver(const TPMDriverOps *tdo); +void tpm_register_model(enum TpmModel model); +void tpm_register_driver(const TPMDriverOps *tdo); #endif diff --git a/migration/colo-failover.c b/migration/colo-failover.c index f9914869c5..6563862b36 100644 --- a/migration/colo-failover.c +++ b/migration/colo-failover.c @@ -34,7 +34,7 @@ static void colo_failover_bh(void *opaque) FAILOVER_STATUS_ACTIVE); if (old_state != FAILOVER_STATUS_REQUIRE) { error_report("Unknown error for failover, old_state = %s", - FailoverStatus_lookup[old_state]); + FailoverStatus_str(old_state)); return; } @@ -64,7 +64,7 @@ FailoverStatus failover_set_state(FailoverStatus old_state, old = atomic_cmpxchg(&failover_state, old_state, new_state); if (old == old_state) { - trace_colo_failover_set_state(FailoverStatus_lookup[new_state]); + trace_colo_failover_set_state(FailoverStatus_str(new_state)); } return old; } diff --git a/migration/colo.c b/migration/colo.c index a4255432ac..dee3aa8bf7 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -61,7 +61,7 @@ static void secondary_vm_do_failover(void) FAILOVER_STATUS_RELAUNCH); if (old_state != FAILOVER_STATUS_ACTIVE) { error_report("Unknown error while do failover for secondary VM," - "old_state: %s", FailoverStatus_lookup[old_state]); + "old_state: %s", FailoverStatus_str(old_state)); } return; } @@ -91,7 +91,7 @@ static void secondary_vm_do_failover(void) FAILOVER_STATUS_COMPLETED); if (old_state != FAILOVER_STATUS_ACTIVE) { error_report("Incorrect state (%s) while doing failover for " - "secondary VM", FailoverStatus_lookup[old_state]); + "secondary VM", FailoverStatus_str(old_state)); return; } /* Notify COLO incoming thread that failover work is finished */ @@ -126,7 +126,7 @@ static void primary_vm_do_failover(void) FAILOVER_STATUS_COMPLETED); if (old_state != FAILOVER_STATUS_ACTIVE) { error_report("Incorrect state (%s) while doing failover for Primary VM", - FailoverStatus_lookup[old_state]); + FailoverStatus_str(old_state)); return; } /* Notify COLO thread that failover work is finished */ @@ -222,7 +222,7 @@ static void colo_send_message(QEMUFile *f, COLOMessage msg, if (ret < 0) { error_setg_errno(errp, -ret, "Can't send COLO message"); } - trace_colo_send_message(COLOMessage_lookup[msg]); + trace_colo_send_message(COLOMessage_str(msg)); } static void colo_send_message_value(QEMUFile *f, COLOMessage msg, @@ -242,7 +242,7 @@ static void colo_send_message_value(QEMUFile *f, COLOMessage msg, ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to send value for message:%s", - COLOMessage_lookup[msg]); + COLOMessage_str(msg)); } } @@ -261,7 +261,7 @@ static COLOMessage colo_receive_message(QEMUFile *f, Error **errp) error_setg(errp, "%s: Invalid message", __func__); return msg; } - trace_colo_receive_message(COLOMessage_lookup[msg]); + trace_colo_receive_message(COLOMessage_str(msg)); return msg; } @@ -299,7 +299,7 @@ static uint64_t colo_receive_message_value(QEMUFile *f, uint32_t expect_msg, ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to get value for COLO message: %s", - COLOMessage_lookup[expect_msg]); + COLOMessage_str(expect_msg)); } return value; } diff --git a/migration/global_state.c b/migration/global_state.c index dcbbcb28be..dfdaf63910 100644 --- a/migration/global_state.c +++ b/migration/global_state.c @@ -14,7 +14,6 @@ #include "qemu/cutils.h" #include "qemu/error-report.h" #include "qapi/error.h" -#include "qapi/util.h" #include "migration.h" #include "migration/global_state.h" #include "migration/vmstate.h" @@ -42,7 +41,7 @@ int global_state_store(void) void global_state_store_running(void) { - const char *state = RunState_lookup[RUN_STATE_RUNNING]; + const char *state = RunState_str(RUN_STATE_RUNNING); strncpy((char *)global_state.runstate, state, sizeof(global_state.runstate)); } @@ -89,8 +88,7 @@ static int global_state_post_load(void *opaque, int version_id) s->received = true; trace_migrate_global_state_post_load(runstate); - r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE__MAX, - -1, &local_err); + r = qapi_enum_parse(&RunState_lookup, runstate, -1, &local_err); if (r == -1) { if (local_err) { diff --git a/migration/migration.c b/migration/migration.c index c3fe0ed9ca..1a2b3ebd1a 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -31,7 +31,6 @@ #include "migration/vmstate.h" #include "block/block.h" #include "qapi/qmp/qerror.h" -#include "qapi/util.h" #include "qemu/rcu.h" #include "block.h" #include "postcopy-ram.h" @@ -928,7 +928,7 @@ EventInfoList *qmp_query_events(Error **errp) QAPIEvent e; for (e = 0 ; e < QAPI_EVENT__MAX ; e++) { - const char *event_name = QAPIEvent_lookup[e]; + const char *event_name = QAPIEvent_str(e); assert(event_name != NULL); info = g_malloc0(sizeof(*info)); info->value = g_malloc0(sizeof(*info->value)); @@ -3249,8 +3249,8 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str) } len = strlen(str); readline_set_completion_index(rs, len); - for (i = 0; NetClientDriver_lookup[i]; i++) { - add_completion_option(rs, str, NetClientDriver_lookup[i]); + for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) { + add_completion_option(rs, str, NetClientDriver_str(i)); } } @@ -3434,8 +3434,8 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) len = strlen(str); readline_set_completion_index(rs, len); for (i = 0; i < Q_KEY_CODE__MAX; i++) { - if (!strncmp(str, QKeyCode_lookup[i], len)) { - readline_add_completion(rs, QKeyCode_lookup[i]); + if (!strncmp(str, QKeyCode_str(i), len)) { + readline_add_completion(rs, QKeyCode_str(i)); } } } @@ -3537,8 +3537,8 @@ void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str) return; } readline_set_completion_index(rs, strlen(str)); - for (i = 0; WatchdogExpirationAction_lookup[i]; i++) { - add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]); + for (i = 0; i < WATCHDOG_EXPIRATION_ACTION__MAX; i++) { + add_completion_option(rs, str, WatchdogExpirationAction_str(i)); } } @@ -3552,7 +3552,7 @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args, if (nb_args == 2) { int i; for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { - const char *name = MigrationCapability_lookup[i]; + const char *name = MigrationCapability_str(i); if (!strncmp(str, name, len)) { readline_add_completion(rs, name); } @@ -3573,7 +3573,7 @@ void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, if (nb_args == 2) { int i; for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { - const char *name = MigrationParameter_lookup[i]; + const char *name = MigrationParameter_str(i); if (!strncmp(str, name, len)) { readline_add_completion(rs, name); } @@ -3852,7 +3852,7 @@ static void handle_qmp_command(JSONMessageParser *parser, GQueue *tokens) qdict = qdict_get_qdict(qobject_to_qdict(rsp), "error"); if (qdict && !g_strcmp0(qdict_get_try_str(qdict, "class"), - QapiErrorClass_lookup[ERROR_CLASS_COMMAND_NOT_FOUND])) { + QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND))) { /* Provide a more useful error message */ qdict_del(qdict, "desc"); qdict_put_str(qdict, "desc", "Expecting capabilities negotiation" diff --git a/net/filter.c b/net/filter.c index 1dfd2caa23..2fd7d7d663 100644 --- a/net/filter.c +++ b/net/filter.c @@ -179,7 +179,7 @@ static void netfilter_init(Object *obj) netfilter_get_netdev_id, netfilter_set_netdev_id, NULL); object_property_add_enum(obj, "queue", "NetFilterDirection", - NetFilterDirection_lookup, + &NetFilterDirection_lookup, netfilter_get_direction, netfilter_set_direction, NULL); object_property_add_str(obj, "status", @@ -1064,7 +1064,7 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp) /* FIXME drop when all init functions store an Error */ if (errp && !*errp) { error_setg(errp, QERR_DEVICE_INIT_FAILED, - NetClientDriver_lookup[netdev->type]); + NetClientDriver_str(netdev->type)); } return -1; } @@ -1288,7 +1288,7 @@ void print_net_client(Monitor *mon, NetClientState *nc) monitor_printf(mon, "%s: index=%d,type=%s,%s\n", nc->name, nc->queue_index, - NetClientDriver_lookup[nc->info->type], + NetClientDriver_str(nc->info->type), nc->info_str); if (!QTAILQ_EMPTY(&nc->filters)) { monitor_printf(mon, "filters:\n"); diff --git a/qapi-schema.json b/qapi-schema.json index 802ea53d00..f3af2cb851 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -72,26 +72,29 @@ 'q_obj_CpuInfo-base' # CPU, visible through query-cpu ] } } -# QAPI common definitions -{ 'include': 'qapi/common.json' } +# Documentation generated with qapi2texi.py is in source order, with +# included sub-schemas inserted at the first include directive +# (subsequent include directives have no effect). To get a sane and +# stable order, it's best to include each sub-schema just once, or +# include it first in qapi-schema.json. -# QAPI crypto definitions +{ 'include': 'qapi/common.json' } +{ 'include': 'qapi/sockets.json' } +{ 'include': 'qapi/run-state.json' } { 'include': 'qapi/crypto.json' } - -# QAPI block definitions { 'include': 'qapi/block.json' } - -# QAPI event definitions -{ 'include': 'qapi/event.json' } - -# Tracing commands +{ 'include': 'qapi/char.json' } +{ 'include': 'qapi/net.json' } +{ 'include': 'qapi/rocker.json' } +{ 'include': 'qapi/tpm.json' } +{ 'include': 'qapi/ui.json' } +{ 'include': 'qapi/migration.json' } +{ 'include': 'qapi/transaction.json' } { 'include': 'qapi/trace.json' } - -# QAPI introspection { 'include': 'qapi/introspect.json' } ## -# = QMP commands +# = Miscellanea ## ## @@ -116,20 +119,107 @@ { 'command': 'qmp_capabilities' } ## -# @StrOrNull: +# @VersionTriple: # -# This is a string value or the explicit lack of a string (null -# pointer in C). Intended for cases when 'optional absent' already -# has a different meaning. +# A three-part version number. # -# @s: the string value -# @n: no string value +# @major: The major version number. # -# Since: 2.10 +# @minor: The minor version number. +# +# @micro: The micro version number. +# +# Since: 2.4 +## +{ 'struct': 'VersionTriple', + 'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} } + + ## -{ 'alternate': 'StrOrNull', - 'data': { 's': 'str', - 'n': 'null' } } +# @VersionInfo: +# +# A description of QEMU's version. +# +# @qemu: The version of QEMU. By current convention, a micro +# version of 50 signifies a development branch. A micro version +# greater than or equal to 90 signifies a release candidate for +# the next minor version. A micro version of less than 50 +# signifies a stable release. +# +# @package: QEMU will always set this field to an empty string. Downstream +# versions of QEMU should set this to a non-empty string. The +# exact format depends on the downstream however it highly +# recommended that a unique name is used. +# +# Since: 0.14.0 +## +{ 'struct': 'VersionInfo', + 'data': {'qemu': 'VersionTriple', 'package': 'str'} } + +## +# @query-version: +# +# Returns the current version of QEMU. +# +# Returns: A @VersionInfo object describing the current version of QEMU. +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-version" } +# <- { +# "return":{ +# "qemu":{ +# "major":0, +# "minor":11, +# "micro":5 +# }, +# "package":"" +# } +# } +# +## +{ 'command': 'query-version', 'returns': 'VersionInfo' } + +## +# @CommandInfo: +# +# Information about a QMP command +# +# @name: The command name +# +# Since: 0.14.0 +## +{ 'struct': 'CommandInfo', 'data': {'name': 'str'} } + +## +# @query-commands: +# +# Return a list of supported QMP commands by this server +# +# Returns: A list of @CommandInfo for all supported commands +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-commands" } +# <- { +# "return":[ +# { +# "name":"query-balloon" +# }, +# { +# "name":"system_powerdown" +# } +# ] +# } +# +# Note: This example has been shortened as the real response is too long. +# +## +{ 'command': 'query-commands', 'returns': ['CommandInfo'] } ## # @LostTickPolicy: @@ -246,94 +336,6 @@ { 'command': 'query-kvm', 'returns': 'KvmInfo' } ## -# @RunState: -# -# An enumeration of VM run states. -# -# @debug: QEMU is running on a debugger -# -# @finish-migrate: guest is paused to finish the migration process -# -# @inmigrate: guest is paused waiting for an incoming migration. Note -# that this state does not tell whether the machine will start at the -# end of the migration. This depends on the command-line -S option and -# any invocation of 'stop' or 'cont' that has happened since QEMU was -# started. -# -# @internal-error: An internal error that prevents further guest execution -# has occurred -# -# @io-error: the last IOP has failed and the device is configured to pause -# on I/O errors -# -# @paused: guest has been paused via the 'stop' command -# -# @postmigrate: guest is paused following a successful 'migrate' -# -# @prelaunch: QEMU was started with -S and guest has not started -# -# @restore-vm: guest is paused to restore VM state -# -# @running: guest is actively running -# -# @save-vm: guest is paused to save the VM state -# -# @shutdown: guest is shut down (and -no-shutdown is in use) -# -# @suspended: guest is suspended (ACPI S3) -# -# @watchdog: the watchdog action is configured to pause and has been triggered -# -# @guest-panicked: guest has been panicked as a result of guest OS panic -# -# @colo: guest is paused to save/restore VM state under colo checkpoint, -# VM can not get into this state unless colo capability is enabled -# for migration. (since 2.8) -## -{ 'enum': 'RunState', - 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', - 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', - 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', - 'guest-panicked', 'colo' ] } - -## -# @StatusInfo: -# -# Information about VCPU run state -# -# @running: true if all VCPUs are runnable, false if not runnable -# -# @singlestep: true if VCPUs are in single-step mode -# -# @status: the virtual machine @RunState -# -# Since: 0.14.0 -# -# Notes: @singlestep is enabled through the GDB stub -## -{ 'struct': 'StatusInfo', - 'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} } - -## -# @query-status: -# -# Query the run status of all VCPUs -# -# Returns: @StatusInfo reflecting all VCPUs -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-status" } -# <- { "return": { "running": true, -# "singlestep": false, -# "status": "running" } } -# -## -{ 'command': 'query-status', 'returns': 'StatusInfo' } - -## # @UuidInfo: # # Guest UUID information (Universally Unique Identifier). @@ -364,189 +366,6 @@ { 'command': 'query-uuid', 'returns': 'UuidInfo' } ## -# @ChardevInfo: -# -# Information about a character device. -# -# @label: the label of the character device -# -# @filename: the filename of the character device -# -# @frontend-open: shows whether the frontend device attached to this backend -# (eg. with the chardev=... option) is in open or closed state -# (since 2.1) -# -# Notes: @filename is encoded using the QEMU command line character device -# encoding. See the QEMU man page for details. -# -# Since: 0.14.0 -## -{ 'struct': 'ChardevInfo', 'data': {'label': 'str', - 'filename': 'str', - 'frontend-open': 'bool'} } - -## -# @query-chardev: -# -# Returns information about current character devices. -# -# Returns: a list of @ChardevInfo -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-chardev" } -# <- { -# "return": [ -# { -# "label": "charchannel0", -# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.agent,server", -# "frontend-open": false -# }, -# { -# "label": "charmonitor", -# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.monitor,server", -# "frontend-open": true -# }, -# { -# "label": "charserial0", -# "filename": "pty:/dev/pts/2", -# "frontend-open": true -# } -# ] -# } -# -## -{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] } - -## -# @ChardevBackendInfo: -# -# Information about a character device backend -# -# @name: The backend name -# -# Since: 2.0 -## -{ 'struct': 'ChardevBackendInfo', 'data': {'name': 'str'} } - -## -# @query-chardev-backends: -# -# Returns information about character device backends. -# -# Returns: a list of @ChardevBackendInfo -# -# Since: 2.0 -# -# Example: -# -# -> { "execute": "query-chardev-backends" } -# <- { -# "return":[ -# { -# "name":"udp" -# }, -# { -# "name":"tcp" -# }, -# { -# "name":"unix" -# }, -# { -# "name":"spiceport" -# } -# ] -# } -# -## -{ 'command': 'query-chardev-backends', 'returns': ['ChardevBackendInfo'] } - -## -# @DataFormat: -# -# An enumeration of data format. -# -# @utf8: Data is a UTF-8 string (RFC 3629) -# -# @base64: Data is Base64 encoded binary (RFC 3548) -# -# Since: 1.4 -## -{ 'enum': 'DataFormat', - 'data': [ 'utf8', 'base64' ] } - -## -# @ringbuf-write: -# -# Write to a ring buffer character device. -# -# @device: the ring buffer character device name -# -# @data: data to write -# -# @format: data encoding (default 'utf8'). -# - base64: data must be base64 encoded text. Its binary -# decoding gets written. -# - utf8: data's UTF-8 encoding is written -# - data itself is always Unicode regardless of format, like -# any other string. -# -# Returns: Nothing on success -# -# Since: 1.4 -# -# Example: -# -# -> { "execute": "ringbuf-write", -# "arguments": { "device": "foo", -# "data": "abcdefgh", -# "format": "utf8" } } -# <- { "return": {} } -# -## -{ 'command': 'ringbuf-write', - 'data': {'device': 'str', 'data': 'str', - '*format': 'DataFormat'} } - -## -# @ringbuf-read: -# -# Read from a ring buffer character device. -# -# @device: the ring buffer character device name -# -# @size: how many bytes to read at most -# -# @format: data encoding (default 'utf8'). -# - base64: the data read is returned in base64 encoding. -# - utf8: the data read is interpreted as UTF-8. -# Bug: can screw up when the buffer contains invalid UTF-8 -# sequences, NUL characters, after the ring buffer lost -# data, and when reading stops because the size limit is -# reached. -# - The return value is always Unicode regardless of format, -# like any other string. -# -# Returns: data read from the device -# -# Since: 1.4 -# -# Example: -# -# -> { "execute": "ringbuf-read", -# "arguments": { "device": "foo", -# "size": 1000, -# "format": "utf8" } } -# <- { "return": "abcdefgh" } -# -## -{ 'command': 'ringbuf-read', - 'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'}, - 'returns': 'str' } - -## # @EventInfo: # # Information about a QMP event @@ -586,828 +405,6 @@ { 'command': 'query-events', 'returns': ['EventInfo'] } ## -# @MigrationStats: -# -# Detailed migration status. -# -# @transferred: amount of bytes already transferred to the target VM -# -# @remaining: amount of bytes remaining to be transferred to the target VM -# -# @total: total amount of bytes involved in the migration process -# -# @duplicate: number of duplicate (zero) pages (since 1.2) -# -# @skipped: number of skipped zero pages (since 1.5) -# -# @normal: number of normal pages (since 1.2) -# -# @normal-bytes: number of normal bytes sent (since 1.2) -# -# @dirty-pages-rate: number of pages dirtied by second by the -# guest (since 1.3) -# -# @mbps: throughput in megabits/sec. (since 1.6) -# -# @dirty-sync-count: number of times that dirty ram was synchronized (since 2.1) -# -# @postcopy-requests: The number of page requests received from the destination -# (since 2.7) -# -# @page-size: The number of bytes per page for the various page-based -# statistics (since 2.10) -# -# Since: 0.14.0 -## -{ 'struct': 'MigrationStats', - 'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' , - 'duplicate': 'int', 'skipped': 'int', 'normal': 'int', - 'normal-bytes': 'int', 'dirty-pages-rate' : 'int', - 'mbps' : 'number', 'dirty-sync-count' : 'int', - 'postcopy-requests' : 'int', 'page-size' : 'int' } } - -## -# @XBZRLECacheStats: -# -# Detailed XBZRLE migration cache statistics -# -# @cache-size: XBZRLE cache size -# -# @bytes: amount of bytes already transferred to the target VM -# -# @pages: amount of pages transferred to the target VM -# -# @cache-miss: number of cache miss -# -# @cache-miss-rate: rate of cache miss (since 2.1) -# -# @overflow: number of overflows -# -# Since: 1.2 -## -{ 'struct': 'XBZRLECacheStats', - 'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int', - 'cache-miss': 'int', 'cache-miss-rate': 'number', - 'overflow': 'int' } } - -## -# @MigrationStatus: -# -# An enumeration of migration status. -# -# @none: no migration has ever happened. -# -# @setup: migration process has been initiated. -# -# @cancelling: in the process of cancelling migration. -# -# @cancelled: cancelling migration is finished. -# -# @active: in the process of doing migration. -# -# @postcopy-active: like active, but now in postcopy mode. (since 2.5) -# -# @completed: migration is finished. -# -# @failed: some error occurred during migration process. -# -# @colo: VM is in the process of fault tolerance, VM can not get into this -# state unless colo capability is enabled for migration. (since 2.8) -# -# Since: 2.3 -# -## -{ 'enum': 'MigrationStatus', - 'data': [ 'none', 'setup', 'cancelling', 'cancelled', - 'active', 'postcopy-active', 'completed', 'failed', 'colo' ] } - -## -# @MigrationInfo: -# -# Information about current migration process. -# -# @status: @MigrationStatus describing the current migration status. -# If this field is not returned, no migration process -# has been initiated -# -# @ram: @MigrationStats containing detailed migration -# status, only returned if status is 'active' or -# 'completed'(since 1.2) -# -# @disk: @MigrationStats containing detailed disk migration -# status, only returned if status is 'active' and it is a block -# migration -# -# @xbzrle-cache: @XBZRLECacheStats containing detailed XBZRLE -# migration statistics, only returned if XBZRLE feature is on and -# status is 'active' or 'completed' (since 1.2) -# -# @total-time: total amount of milliseconds since migration started. -# If migration has ended, it returns the total migration -# time. (since 1.2) -# -# @downtime: only present when migration finishes correctly -# total downtime in milliseconds for the guest. -# (since 1.3) -# -# @expected-downtime: only present while migration is active -# expected downtime in milliseconds for the guest in last walk -# of the dirty bitmap. (since 1.3) -# -# @setup-time: amount of setup time in milliseconds _before_ the -# iterations begin but _after_ the QMP command is issued. This is designed -# to provide an accounting of any activities (such as RDMA pinning) which -# may be expensive, but do not actually occur during the iterative -# migration rounds themselves. (since 1.6) -# -# @cpu-throttle-percentage: percentage of time guest cpus are being -# throttled during auto-converge. This is only present when auto-converge -# has started throttling guest cpus. (Since 2.7) -# -# @error-desc: the human readable error description string, when -# @status is 'failed'. Clients should not attempt to parse the -# error strings. (Since 2.7) -# -# Since: 0.14.0 -## -{ 'struct': 'MigrationInfo', - 'data': {'*status': 'MigrationStatus', '*ram': 'MigrationStats', - '*disk': 'MigrationStats', - '*xbzrle-cache': 'XBZRLECacheStats', - '*total-time': 'int', - '*expected-downtime': 'int', - '*downtime': 'int', - '*setup-time': 'int', - '*cpu-throttle-percentage': 'int', - '*error-desc': 'str'} } - -## -# @query-migrate: -# -# Returns information about current migration process. If migration -# is active there will be another json-object with RAM migration -# status and if block migration is active another one with block -# migration status. -# -# Returns: @MigrationInfo -# -# Since: 0.14.0 -# -# Example: -# -# 1. Before the first migration -# -# -> { "execute": "query-migrate" } -# <- { "return": {} } -# -# 2. Migration is done and has succeeded -# -# -> { "execute": "query-migrate" } -# <- { "return": { -# "status": "completed", -# "ram":{ -# "transferred":123, -# "remaining":123, -# "total":246, -# "total-time":12345, -# "setup-time":12345, -# "downtime":12345, -# "duplicate":123, -# "normal":123, -# "normal-bytes":123456, -# "dirty-sync-count":15 -# } -# } -# } -# -# 3. Migration is done and has failed -# -# -> { "execute": "query-migrate" } -# <- { "return": { "status": "failed" } } -# -# 4. Migration is being performed and is not a block migration: -# -# -> { "execute": "query-migrate" } -# <- { -# "return":{ -# "status":"active", -# "ram":{ -# "transferred":123, -# "remaining":123, -# "total":246, -# "total-time":12345, -# "setup-time":12345, -# "expected-downtime":12345, -# "duplicate":123, -# "normal":123, -# "normal-bytes":123456, -# "dirty-sync-count":15 -# } -# } -# } -# -# 5. Migration is being performed and is a block migration: -# -# -> { "execute": "query-migrate" } -# <- { -# "return":{ -# "status":"active", -# "ram":{ -# "total":1057024, -# "remaining":1053304, -# "transferred":3720, -# "total-time":12345, -# "setup-time":12345, -# "expected-downtime":12345, -# "duplicate":123, -# "normal":123, -# "normal-bytes":123456, -# "dirty-sync-count":15 -# }, -# "disk":{ -# "total":20971520, -# "remaining":20880384, -# "transferred":91136 -# } -# } -# } -# -# 6. Migration is being performed and XBZRLE is active: -# -# -> { "execute": "query-migrate" } -# <- { -# "return":{ -# "status":"active", -# "capabilities" : [ { "capability": "xbzrle", "state" : true } ], -# "ram":{ -# "total":1057024, -# "remaining":1053304, -# "transferred":3720, -# "total-time":12345, -# "setup-time":12345, -# "expected-downtime":12345, -# "duplicate":10, -# "normal":3333, -# "normal-bytes":3412992, -# "dirty-sync-count":15 -# }, -# "xbzrle-cache":{ -# "cache-size":67108864, -# "bytes":20971520, -# "pages":2444343, -# "cache-miss":2244, -# "cache-miss-rate":0.123, -# "overflow":34434 -# } -# } -# } -# -## -{ 'command': 'query-migrate', 'returns': 'MigrationInfo' } - -## -# @MigrationCapability: -# -# Migration capabilities enumeration -# -# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length Encoding). -# This feature allows us to minimize migration traffic for certain work -# loads, by sending compressed difference of the pages -# -# @rdma-pin-all: Controls whether or not the entire VM memory footprint is -# mlock()'d on demand or all at once. Refer to docs/rdma.txt for usage. -# Disabled by default. (since 2.0) -# -# @zero-blocks: During storage migration encode blocks of zeroes efficiently. This -# essentially saves 1MB of zeroes per block on the wire. Enabling requires -# source and target VM to support this feature. To enable it is sufficient -# to enable the capability on the source VM. The feature is disabled by -# default. (since 1.6) -# -# @compress: Use multiple compression threads to accelerate live migration. -# This feature can help to reduce the migration traffic, by sending -# compressed pages. Please note that if compress and xbzrle are both -# on, compress only takes effect in the ram bulk stage, after that, -# it will be disabled and only xbzrle takes effect, this can help to -# minimize migration traffic. The feature is disabled by default. -# (since 2.4 ) -# -# @events: generate events for each migration state change -# (since 2.4 ) -# -# @auto-converge: If enabled, QEMU will automatically throttle down the guest -# to speed up convergence of RAM migration. (since 1.6) -# -# @postcopy-ram: Start executing on the migration target before all of RAM has -# been migrated, pulling the remaining pages along as needed. NOTE: If -# the migration fails during postcopy the VM will fail. (since 2.6) -# -# @x-colo: If enabled, migration will never end, and the state of the VM on the -# primary side will be migrated continuously to the VM on secondary -# side, this process is called COarse-Grain LOck Stepping (COLO) for -# Non-stop Service. (since 2.8) -# -# @release-ram: if enabled, qemu will free the migrated ram pages on the source -# during postcopy-ram migration. (since 2.9) -# -# @block: If enabled, QEMU will also migrate the contents of all block -# devices. Default is disabled. A possible alternative uses -# mirror jobs to a builtin NBD server on the destination, which -# offers more flexibility. -# (Since 2.10) -# -# @return-path: If enabled, migration will use the return path even -# for precopy. (since 2.10) -# -# Since: 1.2 -## -{ 'enum': 'MigrationCapability', - 'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks', - 'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram', - 'block', 'return-path' ] } - -## -# @MigrationCapabilityStatus: -# -# Migration capability information -# -# @capability: capability enum -# -# @state: capability state bool -# -# Since: 1.2 -## -{ 'struct': 'MigrationCapabilityStatus', - 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } } - -## -# @migrate-set-capabilities: -# -# Enable/Disable the following migration capabilities (like xbzrle) -# -# @capabilities: json array of capability modifications to make -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "migrate-set-capabilities" , "arguments": -# { "capabilities": [ { "capability": "xbzrle", "state": true } ] } } -# -## -{ 'command': 'migrate-set-capabilities', - 'data': { 'capabilities': ['MigrationCapabilityStatus'] } } - -## -# @query-migrate-capabilities: -# -# Returns information about the current migration capabilities status -# -# Returns: @MigrationCapabilitiesStatus -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "query-migrate-capabilities" } -# <- { "return": [ -# {"state": false, "capability": "xbzrle"}, -# {"state": false, "capability": "rdma-pin-all"}, -# {"state": false, "capability": "auto-converge"}, -# {"state": false, "capability": "zero-blocks"}, -# {"state": false, "capability": "compress"}, -# {"state": true, "capability": "events"}, -# {"state": false, "capability": "postcopy-ram"}, -# {"state": false, "capability": "x-colo"} -# ]} -# -## -{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']} - -## -# @MigrationParameter: -# -# Migration parameters enumeration -# -# @compress-level: Set the compression level to be used in live migration, -# the compression level is an integer between 0 and 9, where 0 means -# no compression, 1 means the best compression speed, and 9 means best -# compression ratio which will consume more CPU. -# -# @compress-threads: Set compression thread count to be used in live migration, -# the compression thread count is an integer between 1 and 255. -# -# @decompress-threads: Set decompression thread count to be used in live -# migration, the decompression thread count is an integer between 1 -# and 255. Usually, decompression is at least 4 times as fast as -# compression, so set the decompress-threads to the number about 1/4 -# of compress-threads is adequate. -# -# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled -# when migration auto-converge is activated. The -# default value is 20. (Since 2.7) -# -# @cpu-throttle-increment: throttle percentage increase each time -# auto-converge detects that migration is not making -# progress. The default value is 10. (Since 2.7) -# -# @tls-creds: ID of the 'tls-creds' object that provides credentials for -# establishing a TLS connection over the migration data channel. -# On the outgoing side of the migration, the credentials must -# be for a 'client' endpoint, while for the incoming side the -# credentials must be for a 'server' endpoint. Setting this -# will enable TLS for all migrations. The default is unset, -# resulting in unsecured migration at the QEMU level. (Since 2.7) -# -# @tls-hostname: hostname of the target host for the migration. This is -# required when using x509 based TLS credentials and the -# migration URI does not already include a hostname. For -# example if using fd: or exec: based migration, the -# hostname must be provided so that the server's x509 -# certificate identity can be validated. (Since 2.7) -# -# @max-bandwidth: to set maximum speed for migration. maximum speed in -# bytes per second. (Since 2.8) -# -# @downtime-limit: set maximum tolerated downtime for migration. maximum -# downtime in milliseconds (Since 2.8) -# -# @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in -# periodic mode. (Since 2.8) -# -# @block-incremental: Affects how much storage is migrated when the -# block migration capability is enabled. When false, the entire -# storage backing chain is migrated into a flattened image at -# the destination; when true, only the active qcow2 layer is -# migrated and the destination must already have access to the -# same backing chain as was used on the source. (since 2.10) -# -# Since: 2.4 -## -{ 'enum': 'MigrationParameter', - 'data': ['compress-level', 'compress-threads', 'decompress-threads', - 'cpu-throttle-initial', 'cpu-throttle-increment', - 'tls-creds', 'tls-hostname', 'max-bandwidth', - 'downtime-limit', 'x-checkpoint-delay', 'block-incremental' ] } - -## -# @MigrateSetParameters: -# -# @compress-level: compression level -# -# @compress-threads: compression thread count -# -# @decompress-threads: decompression thread count -# -# @cpu-throttle-initial: Initial percentage of time guest cpus are -# throttled when migration auto-converge is activated. -# The default value is 20. (Since 2.7) -# -# @cpu-throttle-increment: throttle percentage increase each time -# auto-converge detects that migration is not making -# progress. The default value is 10. (Since 2.7) -# -# @tls-creds: ID of the 'tls-creds' object that provides credentials -# for establishing a TLS connection over the migration data -# channel. On the outgoing side of the migration, the credentials -# must be for a 'client' endpoint, while for the incoming side the -# credentials must be for a 'server' endpoint. Setting this -# to a non-empty string enables TLS for all migrations. -# An empty string means that QEMU will use plain text mode for -# migration, rather than TLS (Since 2.9) -# Previously (since 2.7), this was reported by omitting -# tls-creds instead. -# -# @tls-hostname: hostname of the target host for the migration. This -# is required when using x509 based TLS credentials and the -# migration URI does not already include a hostname. For -# example if using fd: or exec: based migration, the -# hostname must be provided so that the server's x509 -# certificate identity can be validated. (Since 2.7) -# An empty string means that QEMU will use the hostname -# associated with the migration URI, if any. (Since 2.9) -# Previously (since 2.7), this was reported by omitting -# tls-hostname instead. -# -# @max-bandwidth: to set maximum speed for migration. maximum speed in -# bytes per second. (Since 2.8) -# -# @downtime-limit: set maximum tolerated downtime for migration. maximum -# downtime in milliseconds (Since 2.8) -# -# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8) -# -# @block-incremental: Affects how much storage is migrated when the -# block migration capability is enabled. When false, the entire -# storage backing chain is migrated into a flattened image at -# the destination; when true, only the active qcow2 layer is -# migrated and the destination must already have access to the -# same backing chain as was used on the source. (since 2.10) -# -# Since: 2.4 -## -# TODO either fuse back into MigrationParameters, or make -# MigrationParameters members mandatory -{ 'struct': 'MigrateSetParameters', - 'data': { '*compress-level': 'int', - '*compress-threads': 'int', - '*decompress-threads': 'int', - '*cpu-throttle-initial': 'int', - '*cpu-throttle-increment': 'int', - '*tls-creds': 'StrOrNull', - '*tls-hostname': 'StrOrNull', - '*max-bandwidth': 'int', - '*downtime-limit': 'int', - '*x-checkpoint-delay': 'int', - '*block-incremental': 'bool' } } - -## -# @migrate-set-parameters: -# -# Set various migration parameters. -# -# Since: 2.4 -# -# Example: -# -# -> { "execute": "migrate-set-parameters" , -# "arguments": { "compress-level": 1 } } -# -## -{ 'command': 'migrate-set-parameters', 'boxed': true, - 'data': 'MigrateSetParameters' } - -## -# @MigrationParameters: -# -# The optional members aren't actually optional. -# -# @compress-level: compression level -# -# @compress-threads: compression thread count -# -# @decompress-threads: decompression thread count -# -# @cpu-throttle-initial: Initial percentage of time guest cpus are -# throttled when migration auto-converge is activated. -# (Since 2.7) -# -# @cpu-throttle-increment: throttle percentage increase each time -# auto-converge detects that migration is not making -# progress. (Since 2.7) -# -# @tls-creds: ID of the 'tls-creds' object that provides credentials -# for establishing a TLS connection over the migration data -# channel. On the outgoing side of the migration, the credentials -# must be for a 'client' endpoint, while for the incoming side the -# credentials must be for a 'server' endpoint. -# An empty string means that QEMU will use plain text mode for -# migration, rather than TLS (Since 2.7) -# Note: 2.8 reports this by omitting tls-creds instead. -# -# @tls-hostname: hostname of the target host for the migration. This -# is required when using x509 based TLS credentials and the -# migration URI does not already include a hostname. For -# example if using fd: or exec: based migration, the -# hostname must be provided so that the server's x509 -# certificate identity can be validated. (Since 2.7) -# An empty string means that QEMU will use the hostname -# associated with the migration URI, if any. (Since 2.9) -# Note: 2.8 reports this by omitting tls-hostname instead. -# -# @max-bandwidth: to set maximum speed for migration. maximum speed in -# bytes per second. (Since 2.8) -# -# @downtime-limit: set maximum tolerated downtime for migration. maximum -# downtime in milliseconds (Since 2.8) -# -# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8) -# -# @block-incremental: Affects how much storage is migrated when the -# block migration capability is enabled. When false, the entire -# storage backing chain is migrated into a flattened image at -# the destination; when true, only the active qcow2 layer is -# migrated and the destination must already have access to the -# same backing chain as was used on the source. (since 2.10) -# -# Since: 2.4 -## -{ 'struct': 'MigrationParameters', - 'data': { '*compress-level': 'int', - '*compress-threads': 'int', - '*decompress-threads': 'int', - '*cpu-throttle-initial': 'int', - '*cpu-throttle-increment': 'int', - '*tls-creds': 'str', - '*tls-hostname': 'str', - '*max-bandwidth': 'int', - '*downtime-limit': 'int', - '*x-checkpoint-delay': 'int', - '*block-incremental': 'bool' } } - -## -# @query-migrate-parameters: -# -# Returns information about the current migration parameters -# -# Returns: @MigrationParameters -# -# Since: 2.4 -# -# Example: -# -# -> { "execute": "query-migrate-parameters" } -# <- { "return": { -# "decompress-threads": 2, -# "cpu-throttle-increment": 10, -# "compress-threads": 8, -# "compress-level": 1, -# "cpu-throttle-initial": 20, -# "max-bandwidth": 33554432, -# "downtime-limit": 300 -# } -# } -# -## -{ 'command': 'query-migrate-parameters', - 'returns': 'MigrationParameters' } - -## -# @client_migrate_info: -# -# Set migration information for remote display. This makes the server -# ask the client to automatically reconnect using the new parameters -# once migration finished successfully. Only implemented for SPICE. -# -# @protocol: must be "spice" -# @hostname: migration target hostname -# @port: spice tcp port for plaintext channels -# @tls-port: spice tcp port for tls-secured channels -# @cert-subject: server certificate subject -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "client_migrate_info", -# "arguments": { "protocol": "spice", -# "hostname": "virt42.lab.kraxel.org", -# "port": 1234 } } -# <- { "return": {} } -# -## -{ 'command': 'client_migrate_info', - 'data': { 'protocol': 'str', 'hostname': 'str', '*port': 'int', - '*tls-port': 'int', '*cert-subject': 'str' } } - -## -# @migrate-start-postcopy: -# -# Followup to a migration command to switch the migration to postcopy mode. -# The postcopy-ram capability must be set before the original migration -# command. -# -# Since: 2.5 -# -# Example: -# -# -> { "execute": "migrate-start-postcopy" } -# <- { "return": {} } -# -## -{ 'command': 'migrate-start-postcopy' } - -## -# @COLOMessage: -# -# The message transmission between Primary side and Secondary side. -# -# @checkpoint-ready: Secondary VM (SVM) is ready for checkpointing -# -# @checkpoint-request: Primary VM (PVM) tells SVM to prepare for checkpointing -# -# @checkpoint-reply: SVM gets PVM's checkpoint request -# -# @vmstate-send: VM's state will be sent by PVM. -# -# @vmstate-size: The total size of VMstate. -# -# @vmstate-received: VM's state has been received by SVM. -# -# @vmstate-loaded: VM's state has been loaded by SVM. -# -# Since: 2.8 -## -{ 'enum': 'COLOMessage', - 'data': [ 'checkpoint-ready', 'checkpoint-request', 'checkpoint-reply', - 'vmstate-send', 'vmstate-size', 'vmstate-received', - 'vmstate-loaded' ] } - -## -# @COLOMode: -# -# The colo mode -# -# @unknown: unknown mode -# -# @primary: master side -# -# @secondary: slave side -# -# Since: 2.8 -## -{ 'enum': 'COLOMode', - 'data': [ 'unknown', 'primary', 'secondary'] } - -## -# @FailoverStatus: -# -# An enumeration of COLO failover status -# -# @none: no failover has ever happened -# -# @require: got failover requirement but not handled -# -# @active: in the process of doing failover -# -# @completed: finish the process of failover -# -# @relaunch: restart the failover process, from 'none' -> 'completed' (Since 2.9) -# -# Since: 2.8 -## -{ 'enum': 'FailoverStatus', - 'data': [ 'none', 'require', 'active', 'completed', 'relaunch' ] } - -## -# @x-colo-lost-heartbeat: -# -# Tell qemu that heartbeat is lost, request it to do takeover procedures. -# If this command is sent to the PVM, the Primary side will exit COLO mode. -# If sent to the Secondary, the Secondary side will run failover work, -# then takes over server operation to become the service VM. -# -# Since: 2.8 -# -# Example: -# -# -> { "execute": "x-colo-lost-heartbeat" } -# <- { "return": {} } -# -## -{ 'command': 'x-colo-lost-heartbeat' } - -## -# @MouseInfo: -# -# Information about a mouse device. -# -# @name: the name of the mouse device -# -# @index: the index of the mouse device -# -# @current: true if this device is currently receiving mouse events -# -# @absolute: true if this device supports absolute coordinates as input -# -# Since: 0.14.0 -## -{ 'struct': 'MouseInfo', - 'data': {'name': 'str', 'index': 'int', 'current': 'bool', - 'absolute': 'bool'} } - -## -# @query-mice: -# -# Returns information about each active mouse device -# -# Returns: a list of @MouseInfo for each device -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-mice" } -# <- { "return": [ -# { -# "name":"QEMU Microsoft Mouse", -# "index":0, -# "current":false, -# "absolute":false -# }, -# { -# "name":"QEMU PS/2 Mouse", -# "index":1, -# "current":true, -# "absolute":true -# } -# ] -# } -# -## -{ 'command': 'query-mice', 'returns': ['MouseInfo'] } - -## # @CpuInfoArch: # # An enumeration of cpu types that enable additional information during @@ -1620,396 +617,6 @@ { 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] } ## -# @NetworkAddressFamily: -# -# The network address family -# -# @ipv4: IPV4 family -# -# @ipv6: IPV6 family -# -# @unix: unix socket -# -# @vsock: vsock family (since 2.8) -# -# @unknown: otherwise -# -# Since: 2.1 -## -{ 'enum': 'NetworkAddressFamily', - 'data': [ 'ipv4', 'ipv6', 'unix', 'vsock', 'unknown' ] } - -## -# @VncBasicInfo: -# -# The basic information for vnc network connection -# -# @host: IP address -# -# @service: The service name of the vnc port. This may depend on the host -# system's service database so symbolic names should not be relied -# on. -# -# @family: address family -# -# @websocket: true in case the socket is a websocket (since 2.3). -# -# Since: 2.1 -## -{ 'struct': 'VncBasicInfo', - 'data': { 'host': 'str', - 'service': 'str', - 'family': 'NetworkAddressFamily', - 'websocket': 'bool' } } - -## -# @VncServerInfo: -# -# The network connection information for server -# -# @auth: authentication method used for -# the plain (non-websocket) VNC server -# -# Since: 2.1 -## -{ 'struct': 'VncServerInfo', - 'base': 'VncBasicInfo', - 'data': { '*auth': 'str' } } - -## -# @VncClientInfo: -# -# Information about a connected VNC client. -# -# @x509_dname: If x509 authentication is in use, the Distinguished -# Name of the client. -# -# @sasl_username: If SASL authentication is in use, the SASL username -# used for authentication. -# -# Since: 0.14.0 -## -{ 'struct': 'VncClientInfo', - 'base': 'VncBasicInfo', - 'data': { '*x509_dname': 'str', '*sasl_username': 'str' } } - -## -# @VncInfo: -# -# Information about the VNC session. -# -# @enabled: true if the VNC server is enabled, false otherwise -# -# @host: The hostname the VNC server is bound to. This depends on -# the name resolution on the host and may be an IP address. -# -# @family: 'ipv6' if the host is listening for IPv6 connections -# 'ipv4' if the host is listening for IPv4 connections -# 'unix' if the host is listening on a unix domain socket -# 'unknown' otherwise -# -# @service: The service name of the server's port. This may depends -# on the host system's service database so symbolic names should not -# be relied on. -# -# @auth: the current authentication type used by the server -# 'none' if no authentication is being used -# 'vnc' if VNC authentication is being used -# 'vencrypt+plain' if VEncrypt is used with plain text authentication -# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication -# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication -# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth -# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth -# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth -# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth -# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth -# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth -# -# @clients: a list of @VncClientInfo of all currently connected clients -# -# Since: 0.14.0 -## -{ 'struct': 'VncInfo', - 'data': {'enabled': 'bool', '*host': 'str', - '*family': 'NetworkAddressFamily', - '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} } - -## -# @VncPrimaryAuth: -# -# vnc primary authentication method. -# -# Since: 2.3 -## -{ 'enum': 'VncPrimaryAuth', - 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra', - 'tls', 'vencrypt', 'sasl' ] } - -## -# @VncVencryptSubAuth: -# -# vnc sub authentication method with vencrypt. -# -# Since: 2.3 -## -{ 'enum': 'VncVencryptSubAuth', - 'data': [ 'plain', - 'tls-none', 'x509-none', - 'tls-vnc', 'x509-vnc', - 'tls-plain', 'x509-plain', - 'tls-sasl', 'x509-sasl' ] } - - -## -# @VncServerInfo2: -# -# The network connection information for server -# -# @auth: The current authentication type used by the servers -# -# @vencrypt: The vencrypt sub authentication type used by the -# servers, only specified in case auth == vencrypt. -# -# Since: 2.9 -## -{ 'struct': 'VncServerInfo2', - 'base': 'VncBasicInfo', - 'data': { 'auth' : 'VncPrimaryAuth', - '*vencrypt' : 'VncVencryptSubAuth' } } - - -## -# @VncInfo2: -# -# Information about a vnc server -# -# @id: vnc server name. -# -# @server: A list of @VncBasincInfo describing all listening sockets. -# The list can be empty (in case the vnc server is disabled). -# It also may have multiple entries: normal + websocket, -# possibly also ipv4 + ipv6 in the future. -# -# @clients: A list of @VncClientInfo of all currently connected clients. -# The list can be empty, for obvious reasons. -# -# @auth: The current authentication type used by the non-websockets servers -# -# @vencrypt: The vencrypt authentication type used by the servers, -# only specified in case auth == vencrypt. -# -# @display: The display device the vnc server is linked to. -# -# Since: 2.3 -## -{ 'struct': 'VncInfo2', - 'data': { 'id' : 'str', - 'server' : ['VncServerInfo2'], - 'clients' : ['VncClientInfo'], - 'auth' : 'VncPrimaryAuth', - '*vencrypt' : 'VncVencryptSubAuth', - '*display' : 'str' } } - -## -# @query-vnc: -# -# Returns information about the current VNC server -# -# Returns: @VncInfo -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-vnc" } -# <- { "return": { -# "enabled":true, -# "host":"0.0.0.0", -# "service":"50402", -# "auth":"vnc", -# "family":"ipv4", -# "clients":[ -# { -# "host":"127.0.0.1", -# "service":"50401", -# "family":"ipv4" -# } -# ] -# } -# } -# -## -{ 'command': 'query-vnc', 'returns': 'VncInfo' } - -## -# @query-vnc-servers: -# -# Returns a list of vnc servers. The list can be empty. -# -# Returns: a list of @VncInfo2 -# -# Since: 2.3 -## -{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] } - -## -# @SpiceBasicInfo: -# -# The basic information for SPICE network connection -# -# @host: IP address -# -# @port: port number -# -# @family: address family -# -# Since: 2.1 -## -{ 'struct': 'SpiceBasicInfo', - 'data': { 'host': 'str', - 'port': 'str', - 'family': 'NetworkAddressFamily' } } - -## -# @SpiceServerInfo: -# -# Information about a SPICE server -# -# @auth: authentication method -# -# Since: 2.1 -## -{ 'struct': 'SpiceServerInfo', - 'base': 'SpiceBasicInfo', - 'data': { '*auth': 'str' } } - -## -# @SpiceChannel: -# -# Information about a SPICE client channel. -# -# @connection-id: SPICE connection id number. All channels with the same id -# belong to the same SPICE session. -# -# @channel-type: SPICE channel type number. "1" is the main control -# channel, filter for this one if you want to track spice -# sessions only -# -# @channel-id: SPICE channel ID number. Usually "0", might be different when -# multiple channels of the same type exist, such as multiple -# display channels in a multihead setup -# -# @tls: true if the channel is encrypted, false otherwise. -# -# Since: 0.14.0 -## -{ 'struct': 'SpiceChannel', - 'base': 'SpiceBasicInfo', - 'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', - 'tls': 'bool'} } - -## -# @SpiceQueryMouseMode: -# -# An enumeration of Spice mouse states. -# -# @client: Mouse cursor position is determined by the client. -# -# @server: Mouse cursor position is determined by the server. -# -# @unknown: No information is available about mouse mode used by -# the spice server. -# -# Note: spice/enums.h has a SpiceMouseMode already, hence the name. -# -# Since: 1.1 -## -{ 'enum': 'SpiceQueryMouseMode', - 'data': [ 'client', 'server', 'unknown' ] } - -## -# @SpiceInfo: -# -# Information about the SPICE session. -# -# @enabled: true if the SPICE server is enabled, false otherwise -# -# @migrated: true if the last guest migration completed and spice -# migration had completed as well. false otherwise. (since 1.4) -# -# @host: The hostname the SPICE server is bound to. This depends on -# the name resolution on the host and may be an IP address. -# -# @port: The SPICE server's port number. -# -# @compiled-version: SPICE server version. -# -# @tls-port: The SPICE server's TLS port number. -# -# @auth: the current authentication type used by the server -# 'none' if no authentication is being used -# 'spice' uses SASL or direct TLS authentication, depending on command -# line options -# -# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can -# be determined by the client or the server, or unknown if spice -# server doesn't provide this information. (since: 1.1) -# -# @channels: a list of @SpiceChannel for each active spice channel -# -# Since: 0.14.0 -## -{ 'struct': 'SpiceInfo', - 'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int', - '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str', - 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} } - -## -# @query-spice: -# -# Returns information about the current SPICE server -# -# Returns: @SpiceInfo -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-spice" } -# <- { "return": { -# "enabled": true, -# "auth": "spice", -# "port": 5920, -# "tls-port": 5921, -# "host": "0.0.0.0", -# "channels": [ -# { -# "port": "54924", -# "family": "ipv4", -# "channel-type": 1, -# "connection-id": 1804289383, -# "host": "127.0.0.1", -# "channel-id": 0, -# "tls": true -# }, -# { -# "port": "36710", -# "family": "ipv4", -# "channel-type": 4, -# "connection-id": 1804289383, -# "host": "127.0.0.1", -# "channel-id": 0, -# "tls": false -# }, -# [ ... more channels follow ... ] -# ] -# } -# } -# -## -{ 'command': 'query-spice', 'returns': 'SpiceInfo' } - -## # @BalloonInfo: # # Information about the guest balloon device. @@ -2047,6 +654,28 @@ { 'command': 'query-balloon', 'returns': 'BalloonInfo' } ## +# @BALLOON_CHANGE: +# +# Emitted when the guest changes the actual BALLOON level. This value is +# equivalent to the @actual field return by the 'query-balloon' command +# +# @actual: actual level of the guest memory balloon in bytes +# +# Note: this event is rate-limited. +# +# Since: 1.2 +# +# Example: +# +# <- { "event": "BALLOON_CHANGE", +# "data": { "actual": 944766976 }, +# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } +# +## +{ 'event': 'BALLOON_CHANGE', + 'data': { 'actual': 'int' } } + +## # @PciMemoryRange: # # A PCI device memory region @@ -2568,33 +1197,6 @@ { 'command': 'inject-nmi' } ## -# @set_link: -# -# Sets the link status of a virtual network adapter. -# -# @name: the device name of the virtual network adapter -# -# @up: true to set the link status to be up -# -# Returns: Nothing on success -# If @name is not a valid network device, DeviceNotFound -# -# Since: 0.14.0 -# -# Notes: Not all network adapters support setting link status. This command -# will succeed even if the network adapter does not support link status -# notification. -# -# Example: -# -# -> { "execute": "set_link", -# "arguments": { "name": "e1000.0", "up": false } } -# <- { "return": {} } -# -## -{ 'command': 'set_link', 'data': {'name': 'str', 'up': 'bool'} } - -## # @balloon: # # Request the balloon driver to change its balloon size. @@ -2621,156 +1223,6 @@ { 'command': 'balloon', 'data': {'value': 'int'} } ## -# @Abort: -# -# This action can be used to test transaction failure. -# -# Since: 1.6 -## -{ 'struct': 'Abort', - 'data': { } } - -## -# @ActionCompletionMode: -# -# An enumeration of Transactional completion modes. -# -# @individual: Do not attempt to cancel any other Actions if any Actions fail -# after the Transaction request succeeds. All Actions that -# can complete successfully will do so without waiting on others. -# This is the default. -# -# @grouped: If any Action fails after the Transaction succeeds, cancel all -# Actions. Actions do not complete until all Actions are ready to -# complete. May be rejected by Actions that do not support this -# completion mode. -# -# Since: 2.5 -## -{ 'enum': 'ActionCompletionMode', - 'data': [ 'individual', 'grouped' ] } - -## -# @TransactionAction: -# -# A discriminated record of operations that can be performed with -# @transaction. Action @type can be: -# -# - @abort: since 1.6 -# - @block-dirty-bitmap-add: since 2.5 -# - @block-dirty-bitmap-clear: since 2.5 -# - @blockdev-backup: since 2.3 -# - @blockdev-snapshot: since 2.5 -# - @blockdev-snapshot-internal-sync: since 1.7 -# - @blockdev-snapshot-sync: since 1.1 -# - @drive-backup: since 1.6 -# -# Since: 1.1 -## -{ 'union': 'TransactionAction', - 'data': { - 'abort': 'Abort', - 'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd', - 'block-dirty-bitmap-clear': 'BlockDirtyBitmap', - 'blockdev-backup': 'BlockdevBackup', - 'blockdev-snapshot': 'BlockdevSnapshot', - 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal', - 'blockdev-snapshot-sync': 'BlockdevSnapshotSync', - 'drive-backup': 'DriveBackup' - } } - -## -# @TransactionProperties: -# -# Optional arguments to modify the behavior of a Transaction. -# -# @completion-mode: Controls how jobs launched asynchronously by -# Actions will complete or fail as a group. -# See @ActionCompletionMode for details. -# -# Since: 2.5 -## -{ 'struct': 'TransactionProperties', - 'data': { - '*completion-mode': 'ActionCompletionMode' - } -} - -## -# @transaction: -# -# Executes a number of transactionable QMP commands atomically. If any -# operation fails, then the entire set of actions will be abandoned and the -# appropriate error returned. -# -# For external snapshots, the dictionary contains the device, the file to use for -# the new snapshot, and the format. The default format, if not specified, is -# qcow2. -# -# Each new snapshot defaults to being created by QEMU (wiping any -# contents if the file already exists), but it is also possible to reuse -# an externally-created file. In the latter case, you should ensure that -# the new image file has the same contents as the current one; QEMU cannot -# perform any meaningful check. Typically this is achieved by using the -# current image file as the backing file for the new image. -# -# On failure, the original disks pre-snapshot attempt will be used. -# -# For internal snapshots, the dictionary contains the device and the snapshot's -# name. If an internal snapshot matching name already exists, the request will -# be rejected. Only some image formats support it, for example, qcow2, rbd, -# and sheepdog. -# -# On failure, qemu will try delete the newly created internal snapshot in the -# transaction. When an I/O error occurs during deletion, the user needs to fix -# it later with qemu-img or other command. -# -# @actions: List of @TransactionAction; -# information needed for the respective operations. -# -# @properties: structure of additional options to control the -# execution of the transaction. See @TransactionProperties -# for additional detail. -# -# Returns: nothing on success -# -# Errors depend on the operations of the transaction -# -# Note: The transaction aborts on the first failure. Therefore, there will be -# information on only one failed operation returned in an error condition, and -# subsequent actions will not have been attempted. -# -# Since: 1.1 -# -# Example: -# -# -> { "execute": "transaction", -# "arguments": { "actions": [ -# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd0", -# "snapshot-file": "/some/place/my-image", -# "format": "qcow2" } }, -# { "type": "blockdev-snapshot-sync", "data" : { "node-name": "myfile", -# "snapshot-file": "/some/place/my-image2", -# "snapshot-node-name": "node3432", -# "mode": "existing", -# "format": "qcow2" } }, -# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd1", -# "snapshot-file": "/some/place/my-image2", -# "mode": "existing", -# "format": "qcow2" } }, -# { "type": "blockdev-snapshot-internal-sync", "data" : { -# "device": "ide-hd2", -# "name": "snapshot0" } } ] } } -# <- { "return": {} } -# -## -{ 'command': 'transaction', - 'data': { 'actions': [ 'TransactionAction' ], - '*properties': 'TransactionProperties' - } -} - -## # @human-monitor-command: # # Execute a command on the human monitor and return the output. @@ -2809,107 +1261,6 @@ 'returns': 'str' } ## -# @migrate_cancel: -# -# Cancel the current executing migration process. -# -# Returns: nothing on success -# -# Notes: This command succeeds even if there is no migration process running. -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "migrate_cancel" } -# <- { "return": {} } -# -## -{ 'command': 'migrate_cancel' } - -## -# @migrate_set_downtime: -# -# Set maximum tolerated downtime for migration. -# -# @value: maximum downtime in seconds -# -# Returns: nothing on success -# -# Notes: This command is deprecated in favor of 'migrate-set-parameters' -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } -# <- { "return": {} } -# -## -{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} } - -## -# @migrate_set_speed: -# -# Set maximum speed for migration. -# -# @value: maximum speed in bytes per second. -# -# Returns: nothing on success -# -# Notes: This command is deprecated in favor of 'migrate-set-parameters' -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } -# <- { "return": {} } -# -## -{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} } - -## -# @migrate-set-cache-size: -# -# Set cache size to be used by XBZRLE migration -# -# @value: cache size in bytes -# -# The size will be rounded down to the nearest power of 2. -# The cache size can be modified before and during ongoing migration -# -# Returns: nothing on success -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "migrate-set-cache-size", -# "arguments": { "value": 536870912 } } -# <- { "return": {} } -# -## -{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} } - -## -# @query-migrate-cache-size: -# -# Query migration XBZRLE cache size -# -# Returns: XBZRLE cache size in bytes -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "query-migrate-cache-size" } -# <- { "return": 67108864 } -# -## -{ 'command': 'query-migrate-cache-size', 'returns': 'int' } - -## # @ObjectPropertyInfo: # # @name: the name of the property @@ -3003,83 +1354,6 @@ 'data': { 'path': 'str', 'property': 'str', 'value': 'any' } } ## -# @set_password: -# -# Sets the password of a remote display session. -# -# @protocol: `vnc' to modify the VNC server password -# `spice' to modify the Spice server password -# -# @password: the new password -# -# @connected: how to handle existing clients when changing the -# password. If nothing is specified, defaults to `keep' -# `fail' to fail the command if clients are connected -# `disconnect' to disconnect existing clients -# `keep' to maintain existing clients -# -# Returns: Nothing on success -# If Spice is not enabled, DeviceNotFound -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "set_password", "arguments": { "protocol": "vnc", -# "password": "secret" } } -# <- { "return": {} } -# -## -{ 'command': 'set_password', - 'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} } - -## -# @expire_password: -# -# Expire the password of a remote display server. -# -# @protocol: the name of the remote display protocol `vnc' or `spice' -# -# @time: when to expire the password. -# `now' to expire the password immediately -# `never' to cancel password expiration -# `+INT' where INT is the number of seconds from now (integer) -# `INT' where INT is the absolute time in seconds -# -# Returns: Nothing on success -# If @protocol is `spice' and Spice is not active, DeviceNotFound -# -# Since: 0.14.0 -# -# Notes: Time is relative to the server and currently there is no way to -# coordinate server time with client time. It is not recommended to -# use the absolute time version of the @time parameter unless you're -# sure you are on the same machine as the QEMU instance. -# -# Example: -# -# -> { "execute": "expire_password", "arguments": { "protocol": "vnc", -# "time": "+60" } } -# <- { "return": {} } -# -## -{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} } - -## -# @change-vnc-password: -# -# Change the VNC server password. -# -# @password: the new password to use with VNC authentication -# -# Since: 1.1 -# -# Notes: An empty password in this command will set the password to the empty -# string. Existing clients are unaffected by executing this command. -## -{ 'command': 'change-vnc-password', 'data': {'password': 'str'} } - -## # @change: # # This command is multiple commands multiplexed together. @@ -3192,99 +1466,6 @@ 'returns': [ 'DevicePropertyInfo' ] } ## -# @migrate: -# -# Migrates the current running guest to another Virtual Machine. -# -# @uri: the Uniform Resource Identifier of the destination VM -# -# @blk: do block migration (full disk copy) -# -# @inc: incremental disk copy migration -# -# @detach: this argument exists only for compatibility reasons and -# is ignored by QEMU -# -# Returns: nothing on success -# -# Since: 0.14.0 -# -# Notes: -# -# 1. The 'query-migrate' command should be used to check migration's progress -# and final result (this information is provided by the 'status' member) -# -# 2. All boolean arguments default to false -# -# 3. The user Monitor's "detach" argument is invalid in QMP and should not -# be used -# -# Example: -# -# -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } } -# <- { "return": {} } -# -## -{ 'command': 'migrate', - 'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } } - -## -# @migrate-incoming: -# -# Start an incoming migration, the qemu must have been started -# with -incoming defer -# -# @uri: The Uniform Resource Identifier identifying the source or -# address to listen on -# -# Returns: nothing on success -# -# Since: 2.3 -# -# Notes: -# -# 1. It's a bad idea to use a string for the uri, but it needs to stay -# compatible with -incoming and the format of the uri is already exposed -# above libvirt. -# -# 2. QEMU must be started with -incoming defer to allow migrate-incoming to -# be used. -# -# 3. The uri format is the same as for -incoming -# -# Example: -# -# -> { "execute": "migrate-incoming", -# "arguments": { "uri": "tcp::4446" } } -# <- { "return": {} } -# -## -{ 'command': 'migrate-incoming', 'data': {'uri': 'str' } } - -## -# @xen-save-devices-state: -# -# Save the state of all devices to file. The RAM and the block devices -# of the VM are not saved by this command. -# -# @filename: the file to save the state of the devices to as binary -# data. See xen-save-devices-state.txt for a description of the binary -# format. -# -# Returns: Nothing on success -# -# Since: 1.1 -# -# Example: -# -# -> { "execute": "xen-save-devices-state", -# "arguments": { "filename": "/tmp/save" } } -# <- { "return": {} } -# -## -{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} } - -## # @xen-set-global-dirty-log: # # Enable or disable the global dirty log mode. @@ -3377,6 +1558,30 @@ { 'command': 'device_del', 'data': {'id': 'str'} } ## +# @DEVICE_DELETED: +# +# Emitted whenever the device removal completion is acknowledged by the guest. +# At this point, it's safe to reuse the specified device ID. Device removal can +# be initiated by the guest or by HMP/QMP commands. +# +# @device: device name +# +# @path: device path +# +# Since: 1.5 +# +# Example: +# +# <- { "event": "DEVICE_DELETED", +# "data": { "device": "virtio-net-pci-0", +# "path": "/machine/peripheral/virtio-net-pci-0" }, +# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } +# +## +{ 'event': 'DEVICE_DELETED', + 'data': { '*device': 'str', 'path': 'str' } } + +## # @DumpGuestMemoryFormat: # # An enumeration of guest-memory-dump's format. @@ -3512,6 +1717,29 @@ { 'command': 'query-dump', 'returns': 'DumpQueryResult' } ## +# @DUMP_COMPLETED: +# +# Emitted when background dump has completed +# +# @result: DumpQueryResult type described in qapi-schema.json. +# +# @error: human-readable error string that provides +# hint on why dump failed. Only presents on failure. The +# user should not try to interpret the error string. +# +# Since: 2.6 +# +# Example: +# +# { "event": "DUMP_COMPLETED", +# "data": {"result": {"total": 1090650112, "status": "completed", +# "completed": 1090650112} } } +# +## +{ 'event': 'DUMP_COMPLETED' , + 'data': { 'result': 'DumpQueryResult', '*error': 'str' } } + +## # @DumpGuestMemoryCapability: # # A list of the available formats for dump-guest-memory @@ -3564,60 +1792,6 @@ 'data': { 'filename': 'str' } } ## -# @netdev_add: -# -# Add a network backend. -# -# @type: the type of network backend. Current valid values are 'user', 'tap', -# 'vde', 'socket', 'dump' and 'bridge' -# -# @id: the name of the new network backend -# -# Additional arguments depend on the type. -# -# TODO: This command effectively bypasses QAPI completely due to its -# "additional arguments" business. It shouldn't have been added to -# the schema in this form. It should be qapified properly, or -# replaced by a properly qapified command. -# -# Since: 0.14.0 -# -# Returns: Nothing on success -# If @type is not a valid network backend, DeviceNotFound -# -# Example: -# -# -> { "execute": "netdev_add", -# "arguments": { "type": "user", "id": "netdev1", -# "dnssearch": "example.org" } } -# <- { "return": {} } -# -## -{ 'command': 'netdev_add', - 'data': {'type': 'str', 'id': 'str'}, - 'gen': false } # so we can get the additional arguments - -## -# @netdev_del: -# -# Remove a network backend. -# -# @id: the name of the network backend to remove -# -# Returns: Nothing on success -# If @id is not a valid network backend, DeviceNotFound -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "netdev_del", "arguments": { "id": "netdev1" } } -# <- { "return": {} } -# -## -{ 'command': 'netdev_del', 'data': {'id': 'str'} } - -## # @object-add: # # Create a QOM object. @@ -3665,622 +1839,6 @@ { 'command': 'object-del', 'data': {'id': 'str'} } ## -# @NetdevNoneOptions: -# -# Use it alone to have zero network devices. -# -# Since: 1.2 -## -{ 'struct': 'NetdevNoneOptions', - 'data': { } } - -## -# @NetLegacyNicOptions: -# -# Create a new Network Interface Card. -# -# @netdev: id of -netdev to connect to -# -# @macaddr: MAC address -# -# @model: device model (e1000, rtl8139, virtio etc.) -# -# @addr: PCI device address -# -# @vectors: number of MSI-x vectors, 0 to disable MSI-X -# -# Since: 1.2 -## -{ 'struct': 'NetLegacyNicOptions', - 'data': { - '*netdev': 'str', - '*macaddr': 'str', - '*model': 'str', - '*addr': 'str', - '*vectors': 'uint32' } } - -## -# @String: -# -# A fat type wrapping 'str', to be embedded in lists. -# -# Since: 1.2 -## -{ 'struct': 'String', - 'data': { - 'str': 'str' } } - -## -# @NetdevUserOptions: -# -# Use the user mode network stack which requires no administrator privilege to -# run. -# -# @hostname: client hostname reported by the builtin DHCP server -# -# @restrict: isolate the guest from the host -# -# @ipv4: whether to support IPv4, default true for enabled -# (since 2.6) -# -# @ipv6: whether to support IPv6, default true for enabled -# (since 2.6) -# -# @ip: legacy parameter, use net= instead -# -# @net: IP network address that the guest will see, in the -# form addr[/netmask] The netmask is optional, and can be -# either in the form a.b.c.d or as a number of valid top-most -# bits. Default is 10.0.2.0/24. -# -# @host: guest-visible address of the host -# -# @tftp: root directory of the built-in TFTP server -# -# @bootfile: BOOTP filename, for use with tftp= -# -# @dhcpstart: the first of the 16 IPs the built-in DHCP server can -# assign -# -# @dns: guest-visible address of the virtual nameserver -# -# @dnssearch: list of DNS suffixes to search, passed as DHCP option -# to the guest -# -# @ipv6-prefix: IPv6 network prefix (default is fec0::) (since -# 2.6). The network prefix is given in the usual -# hexadecimal IPv6 address notation. -# -# @ipv6-prefixlen: IPv6 network prefix length (default is 64) -# (since 2.6) -# -# @ipv6-host: guest-visible IPv6 address of the host (since 2.6) -# -# @ipv6-dns: guest-visible IPv6 address of the virtual -# nameserver (since 2.6) -# -# @smb: root directory of the built-in SMB server -# -# @smbserver: IP address of the built-in SMB server -# -# @hostfwd: redirect incoming TCP or UDP host connections to guest -# endpoints -# -# @guestfwd: forward guest TCP connections -# -# Since: 1.2 -## -{ 'struct': 'NetdevUserOptions', - 'data': { - '*hostname': 'str', - '*restrict': 'bool', - '*ipv4': 'bool', - '*ipv6': 'bool', - '*ip': 'str', - '*net': 'str', - '*host': 'str', - '*tftp': 'str', - '*bootfile': 'str', - '*dhcpstart': 'str', - '*dns': 'str', - '*dnssearch': ['String'], - '*ipv6-prefix': 'str', - '*ipv6-prefixlen': 'int', - '*ipv6-host': 'str', - '*ipv6-dns': 'str', - '*smb': 'str', - '*smbserver': 'str', - '*hostfwd': ['String'], - '*guestfwd': ['String'] } } - -## -# @NetdevTapOptions: -# -# Connect the host TAP network interface name to the VLAN. -# -# @ifname: interface name -# -# @fd: file descriptor of an already opened tap -# -# @fds: multiple file descriptors of already opened multiqueue capable -# tap -# -# @script: script to initialize the interface -# -# @downscript: script to shut down the interface -# -# @br: bridge name (since 2.8) -# -# @helper: command to execute to configure bridge -# -# @sndbuf: send buffer limit. Understands [TGMKkb] suffixes. -# -# @vnet_hdr: enable the IFF_VNET_HDR flag on the tap interface -# -# @vhost: enable vhost-net network accelerator -# -# @vhostfd: file descriptor of an already opened vhost net device -# -# @vhostfds: file descriptors of multiple already opened vhost net -# devices -# -# @vhostforce: vhost on for non-MSIX virtio guests -# -# @queues: number of queues to be created for multiqueue capable tap -# -# @poll-us: maximum number of microseconds that could -# be spent on busy polling for tap (since 2.7) -# -# Since: 1.2 -## -{ 'struct': 'NetdevTapOptions', - 'data': { - '*ifname': 'str', - '*fd': 'str', - '*fds': 'str', - '*script': 'str', - '*downscript': 'str', - '*br': 'str', - '*helper': 'str', - '*sndbuf': 'size', - '*vnet_hdr': 'bool', - '*vhost': 'bool', - '*vhostfd': 'str', - '*vhostfds': 'str', - '*vhostforce': 'bool', - '*queues': 'uint32', - '*poll-us': 'uint32'} } - -## -# @NetdevSocketOptions: -# -# Connect the VLAN to a remote VLAN in another QEMU virtual machine using a TCP -# socket connection. -# -# @fd: file descriptor of an already opened socket -# -# @listen: port number, and optional hostname, to listen on -# -# @connect: port number, and optional hostname, to connect to -# -# @mcast: UDP multicast address and port number -# -# @localaddr: source address and port for multicast and udp packets -# -# @udp: UDP unicast address and port number -# -# Since: 1.2 -## -{ 'struct': 'NetdevSocketOptions', - 'data': { - '*fd': 'str', - '*listen': 'str', - '*connect': 'str', - '*mcast': 'str', - '*localaddr': 'str', - '*udp': 'str' } } - -## -# @NetdevL2TPv3Options: -# -# Connect the VLAN to Ethernet over L2TPv3 Static tunnel -# -# @src: source address -# -# @dst: destination address -# -# @srcport: source port - mandatory for udp, optional for ip -# -# @dstport: destination port - mandatory for udp, optional for ip -# -# @ipv6: force the use of ipv6 -# -# @udp: use the udp version of l2tpv3 encapsulation -# -# @cookie64: use 64 bit coookies -# -# @counter: have sequence counter -# -# @pincounter: pin sequence counter to zero - -# workaround for buggy implementations or -# networks with packet reorder -# -# @txcookie: 32 or 64 bit transmit cookie -# -# @rxcookie: 32 or 64 bit receive cookie -# -# @txsession: 32 bit transmit session -# -# @rxsession: 32 bit receive session - if not specified -# set to the same value as transmit -# -# @offset: additional offset - allows the insertion of -# additional application-specific data before the packet payload -# -# Since: 2.1 -## -{ 'struct': 'NetdevL2TPv3Options', - 'data': { - 'src': 'str', - 'dst': 'str', - '*srcport': 'str', - '*dstport': 'str', - '*ipv6': 'bool', - '*udp': 'bool', - '*cookie64': 'bool', - '*counter': 'bool', - '*pincounter': 'bool', - '*txcookie': 'uint64', - '*rxcookie': 'uint64', - 'txsession': 'uint32', - '*rxsession': 'uint32', - '*offset': 'uint32' } } - -## -# @NetdevVdeOptions: -# -# Connect the VLAN to a vde switch running on the host. -# -# @sock: socket path -# -# @port: port number -# -# @group: group owner of socket -# -# @mode: permissions for socket -# -# Since: 1.2 -## -{ 'struct': 'NetdevVdeOptions', - 'data': { - '*sock': 'str', - '*port': 'uint16', - '*group': 'str', - '*mode': 'uint16' } } - -## -# @NetdevDumpOptions: -# -# Dump VLAN network traffic to a file. -# -# @len: per-packet size limit (64k default). Understands [TGMKkb] -# suffixes. -# -# @file: dump file path (default is qemu-vlan0.pcap) -# -# Since: 1.2 -## -{ 'struct': 'NetdevDumpOptions', - 'data': { - '*len': 'size', - '*file': 'str' } } - -## -# @NetdevBridgeOptions: -# -# Connect a host TAP network interface to a host bridge device. -# -# @br: bridge name -# -# @helper: command to execute to configure bridge -# -# Since: 1.2 -## -{ 'struct': 'NetdevBridgeOptions', - 'data': { - '*br': 'str', - '*helper': 'str' } } - -## -# @NetdevHubPortOptions: -# -# Connect two or more net clients through a software hub. -# -# @hubid: hub identifier number -# -# Since: 1.2 -## -{ 'struct': 'NetdevHubPortOptions', - 'data': { - 'hubid': 'int32' } } - -## -# @NetdevNetmapOptions: -# -# Connect a client to a netmap-enabled NIC or to a VALE switch port -# -# @ifname: Either the name of an existing network interface supported by -# netmap, or the name of a VALE port (created on the fly). -# A VALE port name is in the form 'valeXXX:YYY', where XXX and -# YYY are non-negative integers. XXX identifies a switch and -# YYY identifies a port of the switch. VALE ports having the -# same XXX are therefore connected to the same switch. -# -# @devname: path of the netmap device (default: '/dev/netmap'). -# -# Since: 2.0 -## -{ 'struct': 'NetdevNetmapOptions', - 'data': { - 'ifname': 'str', - '*devname': 'str' } } - -## -# @NetdevVhostUserOptions: -# -# Vhost-user network backend -# -# @chardev: name of a unix socket chardev -# -# @vhostforce: vhost on for non-MSIX virtio guests (default: false). -# -# @queues: number of queues to be created for multiqueue vhost-user -# (default: 1) (Since 2.5) -# -# Since: 2.1 -## -{ 'struct': 'NetdevVhostUserOptions', - 'data': { - 'chardev': 'str', - '*vhostforce': 'bool', - '*queues': 'int' } } - -## -# @NetClientDriver: -# -# Available netdev drivers. -# -# Since: 2.7 -## -{ 'enum': 'NetClientDriver', - 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump', - 'bridge', 'hubport', 'netmap', 'vhost-user' ] } - -## -# @Netdev: -# -# Captures the configuration of a network device. -# -# @id: identifier for monitor commands. -# -# @type: Specify the driver used for interpreting remaining arguments. -# -# Since: 1.2 -# -# 'l2tpv3' - since 2.1 -## -{ 'union': 'Netdev', - 'base': { 'id': 'str', 'type': 'NetClientDriver' }, - 'discriminator': 'type', - 'data': { - 'none': 'NetdevNoneOptions', - 'nic': 'NetLegacyNicOptions', - 'user': 'NetdevUserOptions', - 'tap': 'NetdevTapOptions', - 'l2tpv3': 'NetdevL2TPv3Options', - 'socket': 'NetdevSocketOptions', - 'vde': 'NetdevVdeOptions', - 'dump': 'NetdevDumpOptions', - 'bridge': 'NetdevBridgeOptions', - 'hubport': 'NetdevHubPortOptions', - 'netmap': 'NetdevNetmapOptions', - 'vhost-user': 'NetdevVhostUserOptions' } } - -## -# @NetLegacy: -# -# Captures the configuration of a network device; legacy. -# -# @vlan: vlan number -# -# @id: identifier for monitor commands -# -# @name: identifier for monitor commands, ignored if @id is present -# -# @opts: device type specific properties (legacy) -# -# Since: 1.2 -## -{ 'struct': 'NetLegacy', - 'data': { - '*vlan': 'int32', - '*id': 'str', - '*name': 'str', - 'opts': 'NetLegacyOptions' } } - -## -# @NetLegacyOptionsType: -# -# Since: 1.2 -## -{ 'enum': 'NetLegacyOptionsType', - 'data': ['none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', - 'dump', 'bridge', 'netmap', 'vhost-user'] } - -## -# @NetLegacyOptions: -# -# Like Netdev, but for use only by the legacy command line options -# -# Since: 1.2 -## -{ 'union': 'NetLegacyOptions', - 'base': { 'type': 'NetLegacyOptionsType' }, - 'discriminator': 'type', - 'data': { - 'none': 'NetdevNoneOptions', - 'nic': 'NetLegacyNicOptions', - 'user': 'NetdevUserOptions', - 'tap': 'NetdevTapOptions', - 'l2tpv3': 'NetdevL2TPv3Options', - 'socket': 'NetdevSocketOptions', - 'vde': 'NetdevVdeOptions', - 'dump': 'NetdevDumpOptions', - 'bridge': 'NetdevBridgeOptions', - 'netmap': 'NetdevNetmapOptions', - 'vhost-user': 'NetdevVhostUserOptions' } } - -## -# @NetFilterDirection: -# -# Indicates whether a netfilter is attached to a netdev's transmit queue or -# receive queue or both. -# -# @all: the filter is attached both to the receive and the transmit -# queue of the netdev (default). -# -# @rx: the filter is attached to the receive queue of the netdev, -# where it will receive packets sent to the netdev. -# -# @tx: the filter is attached to the transmit queue of the netdev, -# where it will receive packets sent by the netdev. -# -# Since: 2.5 -## -{ 'enum': 'NetFilterDirection', - 'data': [ 'all', 'rx', 'tx' ] } - -## -# @InetSocketAddressBase: -# -# @host: host part of the address -# @port: port part of the address -## -{ 'struct': 'InetSocketAddressBase', - 'data': { - 'host': 'str', - 'port': 'str' } } - -## -# @InetSocketAddress: -# -# Captures a socket address or address range in the Internet namespace. -# -# @numeric: true if the host/port are guaranteed to be numeric, -# false if name resolution should be attempted. Defaults to false. -# (Since 2.9) -# -# @to: If present, this is range of possible addresses, with port -# between @port and @to. -# -# @ipv4: whether to accept IPv4 addresses, default try both IPv4 and IPv6 -# -# @ipv6: whether to accept IPv6 addresses, default try both IPv4 and IPv6 -# -# Since: 1.3 -## -{ 'struct': 'InetSocketAddress', - 'base': 'InetSocketAddressBase', - 'data': { - '*numeric': 'bool', - '*to': 'uint16', - '*ipv4': 'bool', - '*ipv6': 'bool' } } - -## -# @UnixSocketAddress: -# -# Captures a socket address in the local ("Unix socket") namespace. -# -# @path: filesystem path to use -# -# Since: 1.3 -## -{ 'struct': 'UnixSocketAddress', - 'data': { - 'path': 'str' } } - -## -# @VsockSocketAddress: -# -# Captures a socket address in the vsock namespace. -# -# @cid: unique host identifier -# @port: port -# -# Note: string types are used to allow for possible future hostname or -# service resolution support. -# -# Since: 2.8 -## -{ 'struct': 'VsockSocketAddress', - 'data': { - 'cid': 'str', - 'port': 'str' } } - -## -# @SocketAddressLegacy: -# -# Captures the address of a socket, which could also be a named file descriptor -# -# Note: This type is deprecated in favor of SocketAddress. The -# difference between SocketAddressLegacy and SocketAddress is that the -# latter is a flat union rather than a simple union. Flat is nicer -# because it avoids nesting on the wire, i.e. that form has fewer {}. - -# -# Since: 1.3 -## -{ 'union': 'SocketAddressLegacy', - 'data': { - 'inet': 'InetSocketAddress', - 'unix': 'UnixSocketAddress', - 'vsock': 'VsockSocketAddress', - 'fd': 'String' } } - -## -# @SocketAddressType: -# -# Available SocketAddress types -# -# @inet: Internet address -# -# @unix: Unix domain socket -# -# Since: 2.9 -## -{ 'enum': 'SocketAddressType', - 'data': [ 'inet', 'unix', 'vsock', 'fd' ] } - -## -# @SocketAddress: -# -# Captures the address of a socket, which could also be a named file -# descriptor -# -# @type: Transport type -# -# Since: 2.9 -## -{ 'union': 'SocketAddress', - 'base': { 'type': 'SocketAddressType' }, - 'discriminator': 'type', - 'data': { 'inet': 'InetSocketAddress', - 'unix': 'UnixSocketAddress', - 'vsock': 'VsockSocketAddress', - 'fd': 'String' } } - -## # @getfd: # # Receive a file descriptor via SCM rights and assign it a name @@ -4827,591 +2385,6 @@ { 'command': 'query-target', 'returns': 'TargetInfo' } ## -# @QKeyCode: -# -# An enumeration of key name. -# -# This is used by the @send-key command. -# -# @unmapped: since 2.0 -# @pause: since 2.0 -# @ro: since 2.4 -# @kp_comma: since 2.4 -# @kp_equals: since 2.6 -# @power: since 2.6 -# @hiragana: since 2.9 -# @henkan: since 2.9 -# @yen: since 2.9 -# -# @sleep: since 2.10 -# @wake: since 2.10 -# @audionext: since 2.10 -# @audioprev: since 2.10 -# @audiostop: since 2.10 -# @audioplay: since 2.10 -# @audiomute: since 2.10 -# @volumeup: since 2.10 -# @volumedown: since 2.10 -# @mediaselect: since 2.10 -# @mail: since 2.10 -# @calculator: since 2.10 -# @computer: since 2.10 -# @ac_home: since 2.10 -# @ac_back: since 2.10 -# @ac_forward: since 2.10 -# @ac_refresh: since 2.10 -# @ac_bookmarks: since 2.10 -# altgr, altgr_r: dropped in 2.10 -# -# Since: 1.3.0 -# -## -{ 'enum': 'QKeyCode', - 'data': [ 'unmapped', - 'shift', 'shift_r', 'alt', 'alt_r', 'ctrl', - 'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8', - '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e', - 'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right', - 'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon', - 'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b', - 'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock', - 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', - 'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply', - 'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0', - 'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8', - 'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end', - 'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again', - 'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut', - 'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause', - 'ro', 'hiragana', 'henkan', 'yen', - 'kp_comma', 'kp_equals', 'power', 'sleep', 'wake', - 'audionext', 'audioprev', 'audiostop', 'audioplay', 'audiomute', - 'volumeup', 'volumedown', 'mediaselect', - 'mail', 'calculator', 'computer', - 'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks' ] } - -## -# @KeyValue: -# -# Represents a keyboard key. -# -# Since: 1.3.0 -## -{ 'union': 'KeyValue', - 'data': { - 'number': 'int', - 'qcode': 'QKeyCode' } } - -## -# @send-key: -# -# Send keys to guest. -# -# @keys: An array of @KeyValue elements. All @KeyValues in this array are -# simultaneously sent to the guest. A @KeyValue.number value is sent -# directly to the guest, while @KeyValue.qcode must be a valid -# @QKeyCode value -# -# @hold-time: time to delay key up events, milliseconds. Defaults -# to 100 -# -# Returns: Nothing on success -# If key is unknown or redundant, InvalidParameter -# -# Since: 1.3.0 -# -# Example: -# -# -> { "execute": "send-key", -# "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" }, -# { "type": "qcode", "data": "alt" }, -# { "type": "qcode", "data": "delete" } ] } } -# <- { "return": {} } -# -## -{ 'command': 'send-key', - 'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } } - -## -# @screendump: -# -# Write a PPM of the VGA screen to a file. -# -# @filename: the path of a new PPM file to store the image -# -# Returns: Nothing on success -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "screendump", -# "arguments": { "filename": "/tmp/image" } } -# <- { "return": {} } -# -## -{ 'command': 'screendump', 'data': {'filename': 'str'} } - - -## -# @ChardevCommon: -# -# Configuration shared across all chardev backends -# -# @logfile: The name of a logfile to save output -# @logappend: true to append instead of truncate -# (default to false to truncate) -# -# Since: 2.6 -## -{ 'struct': 'ChardevCommon', 'data': { '*logfile': 'str', - '*logappend': 'bool' } } - -## -# @ChardevFile: -# -# Configuration info for file chardevs. -# -# @in: The name of the input file -# @out: The name of the output file -# @append: Open the file in append mode (default false to -# truncate) (Since 2.6) -# -# Since: 1.4 -## -{ 'struct': 'ChardevFile', 'data': { '*in' : 'str', - 'out' : 'str', - '*append': 'bool' }, - 'base': 'ChardevCommon' } - -## -# @ChardevHostdev: -# -# Configuration info for device and pipe chardevs. -# -# @device: The name of the special file for the device, -# i.e. /dev/ttyS0 on Unix or COM1: on Windows -# -# Since: 1.4 -## -{ 'struct': 'ChardevHostdev', 'data': { 'device' : 'str' }, - 'base': 'ChardevCommon' } - -## -# @ChardevSocket: -# -# Configuration info for (stream) socket chardevs. -# -# @addr: socket address to listen on (server=true) -# or connect to (server=false) -# @tls-creds: the ID of the TLS credentials object (since 2.6) -# @server: create server socket (default: true) -# @wait: wait for incoming connection on server -# sockets (default: false). -# @nodelay: set TCP_NODELAY socket option (default: false) -# @telnet: enable telnet protocol on server -# sockets (default: false) -# @tn3270: enable tn3270 protocol on server -# sockets (default: false) (Since: 2.10) -# @reconnect: For a client socket, if a socket is disconnected, -# then attempt a reconnect after the given number of seconds. -# Setting this to zero disables this function. (default: 0) -# (Since: 2.2) -# -# Since: 1.4 -## -{ 'struct': 'ChardevSocket', 'data': { 'addr' : 'SocketAddressLegacy', - '*tls-creds' : 'str', - '*server' : 'bool', - '*wait' : 'bool', - '*nodelay' : 'bool', - '*telnet' : 'bool', - '*tn3270' : 'bool', - '*reconnect' : 'int' }, - 'base': 'ChardevCommon' } - -## -# @ChardevUdp: -# -# Configuration info for datagram socket chardevs. -# -# @remote: remote address -# @local: local address -# -# Since: 1.5 -## -{ 'struct': 'ChardevUdp', 'data': { 'remote' : 'SocketAddressLegacy', - '*local' : 'SocketAddressLegacy' }, - 'base': 'ChardevCommon' } - -## -# @ChardevMux: -# -# Configuration info for mux chardevs. -# -# @chardev: name of the base chardev. -# -# Since: 1.5 -## -{ 'struct': 'ChardevMux', 'data': { 'chardev' : 'str' }, - 'base': 'ChardevCommon' } - -## -# @ChardevStdio: -# -# Configuration info for stdio chardevs. -# -# @signal: Allow signals (such as SIGINT triggered by ^C) -# be delivered to qemu. Default: true in -nographic mode, -# false otherwise. -# -# Since: 1.5 -## -{ 'struct': 'ChardevStdio', 'data': { '*signal' : 'bool' }, - 'base': 'ChardevCommon' } - - -## -# @ChardevSpiceChannel: -# -# Configuration info for spice vm channel chardevs. -# -# @type: kind of channel (for example vdagent). -# -# Since: 1.5 -## -{ 'struct': 'ChardevSpiceChannel', 'data': { 'type' : 'str' }, - 'base': 'ChardevCommon' } - -## -# @ChardevSpicePort: -# -# Configuration info for spice port chardevs. -# -# @fqdn: name of the channel (see docs/spice-port-fqdn.txt) -# -# Since: 1.5 -## -{ 'struct': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' }, - 'base': 'ChardevCommon' } - -## -# @ChardevVC: -# -# Configuration info for virtual console chardevs. -# -# @width: console width, in pixels -# @height: console height, in pixels -# @cols: console width, in chars -# @rows: console height, in chars -# -# Since: 1.5 -## -{ 'struct': 'ChardevVC', 'data': { '*width' : 'int', - '*height' : 'int', - '*cols' : 'int', - '*rows' : 'int' }, - 'base': 'ChardevCommon' } - -## -# @ChardevRingbuf: -# -# Configuration info for ring buffer chardevs. -# -# @size: ring buffer size, must be power of two, default is 65536 -# -# Since: 1.5 -## -{ 'struct': 'ChardevRingbuf', 'data': { '*size' : 'int' }, - 'base': 'ChardevCommon' } - -## -# @ChardevBackend: -# -# Configuration info for the new chardev backend. -# -# Since: 1.4 (testdev since 2.2, wctablet since 2.9) -## -{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile', - 'serial' : 'ChardevHostdev', - 'parallel': 'ChardevHostdev', - 'pipe' : 'ChardevHostdev', - 'socket' : 'ChardevSocket', - 'udp' : 'ChardevUdp', - 'pty' : 'ChardevCommon', - 'null' : 'ChardevCommon', - 'mux' : 'ChardevMux', - 'msmouse': 'ChardevCommon', - 'wctablet' : 'ChardevCommon', - 'braille': 'ChardevCommon', - 'testdev': 'ChardevCommon', - 'stdio' : 'ChardevStdio', - 'console': 'ChardevCommon', - 'spicevmc' : 'ChardevSpiceChannel', - 'spiceport' : 'ChardevSpicePort', - 'vc' : 'ChardevVC', - 'ringbuf': 'ChardevRingbuf', - # next one is just for compatibility - 'memory' : 'ChardevRingbuf' } } - -## -# @ChardevReturn: -# -# Return info about the chardev backend just created. -# -# @pty: name of the slave pseudoterminal device, present if -# and only if a chardev of type 'pty' was created -# -# Since: 1.4 -## -{ 'struct' : 'ChardevReturn', 'data': { '*pty' : 'str' } } - -## -# @chardev-add: -# -# Add a character device backend -# -# @id: the chardev's ID, must be unique -# @backend: backend type and parameters -# -# Returns: ChardevReturn. -# -# Since: 1.4 -# -# Example: -# -# -> { "execute" : "chardev-add", -# "arguments" : { "id" : "foo", -# "backend" : { "type" : "null", "data" : {} } } } -# <- { "return": {} } -# -# -> { "execute" : "chardev-add", -# "arguments" : { "id" : "bar", -# "backend" : { "type" : "file", -# "data" : { "out" : "/tmp/bar.log" } } } } -# <- { "return": {} } -# -# -> { "execute" : "chardev-add", -# "arguments" : { "id" : "baz", -# "backend" : { "type" : "pty", "data" : {} } } } -# <- { "return": { "pty" : "/dev/pty/42" } } -# -## -{ 'command': 'chardev-add', 'data': {'id' : 'str', - 'backend' : 'ChardevBackend' }, - 'returns': 'ChardevReturn' } - -## -# @chardev-change: -# -# Change a character device backend -# -# @id: the chardev's ID, must exist -# @backend: new backend type and parameters -# -# Returns: ChardevReturn. -# -# Since: 2.10 -# -# Example: -# -# -> { "execute" : "chardev-change", -# "arguments" : { "id" : "baz", -# "backend" : { "type" : "pty", "data" : {} } } } -# <- { "return": { "pty" : "/dev/pty/42" } } -# -# -> {"execute" : "chardev-change", -# "arguments" : { -# "id" : "charchannel2", -# "backend" : { -# "type" : "socket", -# "data" : { -# "addr" : { -# "type" : "unix" , -# "data" : { -# "path" : "/tmp/charchannel2.socket" -# } -# }, -# "server" : true, -# "wait" : false }}}} -# <- {"return": {}} -# -## -{ 'command': 'chardev-change', 'data': {'id' : 'str', - 'backend' : 'ChardevBackend' }, - 'returns': 'ChardevReturn' } - -## -# @chardev-remove: -# -# Remove a character device backend -# -# @id: the chardev's ID, must exist and not be in use -# -# Returns: Nothing on success -# -# Since: 1.4 -# -# Example: -# -# -> { "execute": "chardev-remove", "arguments": { "id" : "foo" } } -# <- { "return": {} } -# -## -{ 'command': 'chardev-remove', 'data': {'id': 'str'} } - -## -# @chardev-send-break: -# -# Send a break to a character device -# -# @id: the chardev's ID, must exist -# -# Returns: Nothing on success -# -# Since: 2.10 -# -# Example: -# -# -> { "execute": "chardev-send-break", "arguments": { "id" : "foo" } } -# <- { "return": {} } -# -## -{ 'command': 'chardev-send-break', 'data': {'id': 'str'} } - - -## -# @TpmModel: -# -# An enumeration of TPM models -# -# @tpm-tis: TPM TIS model -# -# Since: 1.5 -## -{ 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] } - -## -# @query-tpm-models: -# -# Return a list of supported TPM models -# -# Returns: a list of TpmModel -# -# Since: 1.5 -# -# Example: -# -# -> { "execute": "query-tpm-models" } -# <- { "return": [ "tpm-tis" ] } -# -## -{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] } - -## -# @TpmType: -# -# An enumeration of TPM types -# -# @passthrough: TPM passthrough type -# -# Since: 1.5 -## -{ 'enum': 'TpmType', 'data': [ 'passthrough' ] } - -## -# @query-tpm-types: -# -# Return a list of supported TPM types -# -# Returns: a list of TpmType -# -# Since: 1.5 -# -# Example: -# -# -> { "execute": "query-tpm-types" } -# <- { "return": [ "passthrough" ] } -# -## -{ 'command': 'query-tpm-types', 'returns': ['TpmType'] } - -## -# @TPMPassthroughOptions: -# -# Information about the TPM passthrough type -# -# @path: string describing the path used for accessing the TPM device -# -# @cancel-path: string showing the TPM's sysfs cancel file -# for cancellation of TPM commands while they are executing -# -# Since: 1.5 -## -{ 'struct': 'TPMPassthroughOptions', 'data': { '*path' : 'str', - '*cancel-path' : 'str'} } - -## -# @TpmTypeOptions: -# -# A union referencing different TPM backend types' configuration options -# -# @type: 'passthrough' The configuration options for the TPM passthrough type -# -# Since: 1.5 -## -{ 'union': 'TpmTypeOptions', - 'data': { 'passthrough' : 'TPMPassthroughOptions' } } - -## -# @TPMInfo: -# -# Information about the TPM -# -# @id: The Id of the TPM -# -# @model: The TPM frontend model -# -# @options: The TPM (backend) type configuration options -# -# Since: 1.5 -## -{ 'struct': 'TPMInfo', - 'data': {'id': 'str', - 'model': 'TpmModel', - 'options': 'TpmTypeOptions' } } - -## -# @query-tpm: -# -# Return information about the TPM device -# -# Returns: @TPMInfo on success -# -# Since: 1.5 -# -# Example: -# -# -> { "execute": "query-tpm" } -# <- { "return": -# [ -# { "model": "tpm-tis", -# "options": -# { "type": "passthrough", -# "data": -# { "cancel-path": "/sys/class/misc/tpm0/device/cancel", -# "path": "/dev/tpm0" -# } -# }, -# "id": "tpm0" -# } -# ] -# } -# -## -{ 'command': 'query-tpm', 'returns': ['TPMInfo'] } - -## # @AcpiTableOptions: # # Specify an ACPI table on the command line to load. @@ -5604,273 +2577,6 @@ ## -# @RxState: -# -# Packets receiving state -# -# @normal: filter assigned packets according to the mac-table -# -# @none: don't receive any assigned packet -# -# @all: receive all assigned packets -# -# Since: 1.6 -## -{ 'enum': 'RxState', 'data': [ 'normal', 'none', 'all' ] } - -## -# @RxFilterInfo: -# -# Rx-filter information for a NIC. -# -# @name: net client name -# -# @promiscuous: whether promiscuous mode is enabled -# -# @multicast: multicast receive state -# -# @unicast: unicast receive state -# -# @vlan: vlan receive state (Since 2.0) -# -# @broadcast-allowed: whether to receive broadcast -# -# @multicast-overflow: multicast table is overflowed or not -# -# @unicast-overflow: unicast table is overflowed or not -# -# @main-mac: the main macaddr string -# -# @vlan-table: a list of active vlan id -# -# @unicast-table: a list of unicast macaddr string -# -# @multicast-table: a list of multicast macaddr string -# -# Since: 1.6 -## -{ 'struct': 'RxFilterInfo', - 'data': { - 'name': 'str', - 'promiscuous': 'bool', - 'multicast': 'RxState', - 'unicast': 'RxState', - 'vlan': 'RxState', - 'broadcast-allowed': 'bool', - 'multicast-overflow': 'bool', - 'unicast-overflow': 'bool', - 'main-mac': 'str', - 'vlan-table': ['int'], - 'unicast-table': ['str'], - 'multicast-table': ['str'] }} - -## -# @query-rx-filter: -# -# Return rx-filter information for all NICs (or for the given NIC). -# -# @name: net client name -# -# Returns: list of @RxFilterInfo for all NICs (or for the given NIC). -# Returns an error if the given @name doesn't exist, or given -# NIC doesn't support rx-filter querying, or given net client -# isn't a NIC. -# -# Since: 1.6 -# -# Example: -# -# -> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } } -# <- { "return": [ -# { -# "promiscuous": true, -# "name": "vnet0", -# "main-mac": "52:54:00:12:34:56", -# "unicast": "normal", -# "vlan": "normal", -# "vlan-table": [ -# 4, -# 0 -# ], -# "unicast-table": [ -# ], -# "multicast": "normal", -# "multicast-overflow": false, -# "unicast-overflow": false, -# "multicast-table": [ -# "01:00:5e:00:00:01", -# "33:33:00:00:00:01", -# "33:33:ff:12:34:56" -# ], -# "broadcast-allowed": false -# } -# ] -# } -# -## -{ 'command': 'query-rx-filter', 'data': { '*name': 'str' }, - 'returns': ['RxFilterInfo'] } - -## -# @InputButton: -# -# Button of a pointer input device (mouse, tablet). -# -# @side: front side button of a 5-button mouse (since 2.9) -# -# @extra: rear side button of a 5-button mouse (since 2.9) -# -# Since: 2.0 -## -{ 'enum' : 'InputButton', - 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side', - 'extra' ] } - -## -# @InputAxis: -# -# Position axis of a pointer input device (mouse, tablet). -# -# Since: 2.0 -## -{ 'enum' : 'InputAxis', - 'data' : [ 'x', 'y' ] } - -## -# @InputKeyEvent: -# -# Keyboard input event. -# -# @key: Which key this event is for. -# @down: True for key-down and false for key-up events. -# -# Since: 2.0 -## -{ 'struct' : 'InputKeyEvent', - 'data' : { 'key' : 'KeyValue', - 'down' : 'bool' } } - -## -# @InputBtnEvent: -# -# Pointer button input event. -# -# @button: Which button this event is for. -# @down: True for key-down and false for key-up events. -# -# Since: 2.0 -## -{ 'struct' : 'InputBtnEvent', - 'data' : { 'button' : 'InputButton', - 'down' : 'bool' } } - -## -# @InputMoveEvent: -# -# Pointer motion input event. -# -# @axis: Which axis is referenced by @value. -# @value: Pointer position. For absolute coordinates the -# valid range is 0 -> 0x7ffff -# -# Since: 2.0 -## -{ 'struct' : 'InputMoveEvent', - 'data' : { 'axis' : 'InputAxis', - 'value' : 'int' } } - -## -# @InputEvent: -# -# Input event union. -# -# @type: the input type, one of: -# - 'key': Input event of Keyboard -# - 'btn': Input event of pointer buttons -# - 'rel': Input event of relative pointer motion -# - 'abs': Input event of absolute pointer motion -# -# Since: 2.0 -## -{ 'union' : 'InputEvent', - 'data' : { 'key' : 'InputKeyEvent', - 'btn' : 'InputBtnEvent', - 'rel' : 'InputMoveEvent', - 'abs' : 'InputMoveEvent' } } - -## -# @input-send-event: -# -# Send input event(s) to guest. -# -# @device: display device to send event(s) to. -# @head: head to send event(s) to, in case the -# display device supports multiple scanouts. -# @events: List of InputEvent union. -# -# Returns: Nothing on success. -# -# The @device and @head parameters can be used to send the input event -# to specific input devices in case (a) multiple input devices of the -# same kind are added to the virtual machine and (b) you have -# configured input routing (see docs/multiseat.txt) for those input -# devices. The parameters work exactly like the device and head -# properties of input devices. If @device is missing, only devices -# that have no input routing config are admissible. If @device is -# specified, both input devices with and without input routing config -# are admissible, but devices with input routing config take -# precedence. -# -# Since: 2.6 -# -# Note: The consoles are visible in the qom tree, under -# /backend/console[$index]. They have a device link and head property, -# so it is possible to map which console belongs to which device and -# display. -# -# Example: -# -# 1. Press left mouse button. -# -# -> { "execute": "input-send-event", -# "arguments": { "device": "video0", -# "events": [ { "type": "btn", -# "data" : { "down": true, "button": "left" } } ] } } -# <- { "return": {} } -# -# -> { "execute": "input-send-event", -# "arguments": { "device": "video0", -# "events": [ { "type": "btn", -# "data" : { "down": false, "button": "left" } } ] } } -# <- { "return": {} } -# -# 2. Press ctrl-alt-del. -# -# -> { "execute": "input-send-event", -# "arguments": { "events": [ -# { "type": "key", "data" : { "down": true, -# "key": {"type": "qcode", "data": "ctrl" } } }, -# { "type": "key", "data" : { "down": true, -# "key": {"type": "qcode", "data": "alt" } } }, -# { "type": "key", "data" : { "down": true, -# "key": {"type": "qcode", "data": "delete" } } } ] } } -# <- { "return": {} } -# -# 3. Move mouse pointer to absolute coordinates (20000, 400). -# -# -> { "execute": "input-send-event" , -# "arguments": { "events": [ -# { "type": "abs", "data" : { "axis": "x", "value" : 20000 } }, -# { "type": "abs", "data" : { "axis": "y", "value" : 400 } } ] } } -# <- { "return": {} } -# -## -{ 'command': 'input-send-event', - 'data': { '*device': 'str', - '*head' : 'int', - 'events' : [ 'InputEvent' ] } } - -## # @NumaOptionsType: # # @node: NUMA nodes configuration @@ -6117,6 +2823,29 @@ { 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] } ## +# @MEM_UNPLUG_ERROR: +# +# Emitted when memory hot unplug error occurs. +# +# @device: device name +# +# @msg: Informative message +# +# Since: 2.4 +# +# Example: +# +# <- { "event": "MEM_UNPLUG_ERROR" +# "data": { "device": "dimm1", +# "msg": "acpi: device unplug for unsupported device" +# }, +# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } +# +## +{ 'event': 'MEM_UNPLUG_ERROR', + 'data': { 'device': 'str', 'msg': 'str' } } + +## # @ACPISlotType: # # @DIMM: memory slot @@ -6171,94 +2900,23 @@ { 'command': 'query-acpi-ospm-status', 'returns': ['ACPIOSTInfo'] } ## -# @WatchdogExpirationAction: -# -# An enumeration of the actions taken when the watchdog device's timer is -# expired -# -# @reset: system resets -# -# @shutdown: system shutdown, note that it is similar to @powerdown, which -# tries to set to system status and notify guest -# -# @poweroff: system poweroff, the emulator program exits -# -# @pause: system pauses, similar to @stop -# -# @debug: system enters debug state -# -# @none: nothing is done -# -# @inject-nmi: a non-maskable interrupt is injected into the first VCPU (all -# VCPUS on x86) (since 2.4) -# -# Since: 2.1 -## -{ 'enum': 'WatchdogExpirationAction', - 'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none', - 'inject-nmi' ] } - -## -# @IoOperationType: -# -# An enumeration of the I/O operation types +# @ACPI_DEVICE_OST: # -# @read: read operation +# Emitted when guest executes ACPI _OST method. # -# @write: write operation +# @info: ACPIOSTInfo type as described in qapi-schema.json # # Since: 2.1 -## -{ 'enum': 'IoOperationType', - 'data': [ 'read', 'write' ] } - -## -# @GuestPanicAction: -# -# An enumeration of the actions taken when guest OS panic is detected -# -# @pause: system pauses -# -# Since: 2.1 (poweroff since 2.8) -## -{ 'enum': 'GuestPanicAction', - 'data': [ 'pause', 'poweroff' ] } - -## -# @GuestPanicInformationType: -# -# An enumeration of the guest panic information types # -# Since: 2.9 -## -{ 'enum': 'GuestPanicInformationType', - 'data': [ 'hyper-v'] } - -## -# @GuestPanicInformation: -# -# Information about a guest panic -# -# Since: 2.9 -## -{'union': 'GuestPanicInformation', - 'base': {'type': 'GuestPanicInformationType'}, - 'discriminator': 'type', - 'data': { 'hyper-v': 'GuestPanicInformationHyperV' } } - -## -# @GuestPanicInformationHyperV: +# Example: # -# Hyper-V specific guest panic information (HV crash MSRs) +# <- { "event": "ACPI_DEVICE_OST", +# "data": { "device": "d1", "slot": "0", +# "slot-type": "DIMM", "source": 1, "status": 0 } } # -# Since: 2.9 ## -{'struct': 'GuestPanicInformationHyperV', - 'data': { 'arg1': 'uint64', - 'arg2': 'uint64', - 'arg3': 'uint64', - 'arg4': 'uint64', - 'arg5': 'uint64' } } +{ 'event': 'ACPI_DEVICE_OST', + 'data': { 'info': 'ACPIOSTInfo' } } ## # @rtc-reset-reinjection: @@ -6278,8 +2936,27 @@ ## { 'command': 'rtc-reset-reinjection' } -# Rocker ethernet network switch -{ 'include': 'qapi/rocker.json' } +## +# @RTC_CHANGE: +# +# Emitted when the guest changes the RTC time. +# +# @offset: offset between base RTC clock (as specified by -rtc base), and +# new RTC clock value +# +# Note: This event is rate-limited. +# +# Since: 0.13.0 +# +# Example: +# +# <- { "event": "RTC_CHANGE", +# "data": { "offset": 78 }, +# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } +# +## +{ 'event': 'RTC_CHANGE', + 'data': { 'offset': 'int' } } ## # @ReplayMode: @@ -6321,79 +2998,6 @@ { 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} } ## -# @xen-set-replication: -# -# Enable or disable replication. -# -# @enable: true to enable, false to disable. -# -# @primary: true for primary or false for secondary. -# -# @failover: true to do failover, false to stop. but cannot be -# specified if 'enable' is true. default value is false. -# -# Returns: nothing. -# -# Example: -# -# -> { "execute": "xen-set-replication", -# "arguments": {"enable": true, "primary": false} } -# <- { "return": {} } -# -# Since: 2.9 -## -{ 'command': 'xen-set-replication', - 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' } } - -## -# @ReplicationStatus: -# -# The result format for 'query-xen-replication-status'. -# -# @error: true if an error happened, false if replication is normal. -# -# @desc: the human readable error description string, when -# @error is 'true'. -# -# Since: 2.9 -## -{ 'struct': 'ReplicationStatus', - 'data': { 'error': 'bool', '*desc': 'str' } } - -## -# @query-xen-replication-status: -# -# Query replication status while the vm is running. -# -# Returns: A @ReplicationResult object showing the status. -# -# Example: -# -# -> { "execute": "query-xen-replication-status" } -# <- { "return": { "error": false } } -# -# Since: 2.9 -## -{ 'command': 'query-xen-replication-status', - 'returns': 'ReplicationStatus' } - -## -# @xen-colo-do-checkpoint: -# -# Xen uses this command to notify replication to trigger a checkpoint. -# -# Returns: nothing. -# -# Example: -# -# -> { "execute": "xen-colo-do-checkpoint" } -# <- { "return": {} } -# -# Since: 2.9 -## -{ 'command': 'xen-colo-do-checkpoint' } - -## # @GICCapability: # # The struct describes capability for a specific GIC (Generic diff --git a/qapi/block-core.json b/qapi/block-core.json index 833c602150..28abb9e6cf 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1,11 +1,12 @@ # -*- Mode: Python -*- ## -# == QAPI block core definitions (vm unrelated) +# == Block core (VM unrelated) ## -# QAPI common definitions { 'include': 'common.json' } +{ 'include': 'crypto.json' } +{ 'include': 'sockets.json' } ## # @SnapshotInfo: diff --git a/qapi/block.json b/qapi/block.json index 414b61bde7..f093fa3f27 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -1,14 +1,13 @@ # -*- Mode: Python -*- ## -# = QAPI block definitions +# = Block devices ## -# QAPI block core definitions { 'include': 'block-core.json' } ## -# == QAPI block definitions (vm unrelated) +# == Additional block stuff (VM related) ## ## @@ -277,3 +276,71 @@ ## { 'enum': 'QuorumOpType', 'data': [ 'read', 'write', 'flush' ] } + +## +# @QUORUM_FAILURE: +# +# Emitted by the Quorum block driver if it fails to establish a quorum +# +# @reference: device name if defined else node name +# +# @sector-num: number of the first sector of the failed read operation +# +# @sectors-count: failed read operation sector count +# +# Note: This event is rate-limited. +# +# Since: 2.0 +# +# Example: +# +# <- { "event": "QUORUM_FAILURE", +# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 }, +# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } +# +## +{ 'event': 'QUORUM_FAILURE', + 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } } + +## +# @QUORUM_REPORT_BAD: +# +# Emitted to report a corruption of a Quorum file +# +# @type: quorum operation type (Since 2.6) +# +# @error: error message. Only present on failure. This field +# contains a human-readable error message. There are no semantics other +# than that the block layer reported an error and clients should not +# try to interpret the error string. +# +# @node-name: the graph node name of the block driver state +# +# @sector-num: number of the first sector of the failed read operation +# +# @sectors-count: failed read operation sector count +# +# Note: This event is rate-limited. +# +# Since: 2.0 +# +# Example: +# +# 1. Read operation +# +# { "event": "QUORUM_REPORT_BAD", +# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5, +# "type": "read" }, +# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } +# +# 2. Flush operation +# +# { "event": "QUORUM_REPORT_BAD", +# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120, +# "type": "flush", "error": "Broken pipe" }, +# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } } +# +## +{ 'event': 'QUORUM_REPORT_BAD', + 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str', + 'sector-num': 'int', 'sectors-count': 'int' } } diff --git a/qapi/char.json b/qapi/char.json new file mode 100644 index 0000000000..ae19dcd1ed --- /dev/null +++ b/qapi/char.json @@ -0,0 +1,538 @@ +# -*- Mode: Python -*- +# + +## +# = Character devices +## + +{ 'include': 'sockets.json' } + +## +# @ChardevInfo: +# +# Information about a character device. +# +# @label: the label of the character device +# +# @filename: the filename of the character device +# +# @frontend-open: shows whether the frontend device attached to this backend +# (eg. with the chardev=... option) is in open or closed state +# (since 2.1) +# +# Notes: @filename is encoded using the QEMU command line character device +# encoding. See the QEMU man page for details. +# +# Since: 0.14.0 +## +{ 'struct': 'ChardevInfo', 'data': {'label': 'str', + 'filename': 'str', + 'frontend-open': 'bool'} } + +## +# @query-chardev: +# +# Returns information about current character devices. +# +# Returns: a list of @ChardevInfo +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-chardev" } +# <- { +# "return": [ +# { +# "label": "charchannel0", +# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.agent,server", +# "frontend-open": false +# }, +# { +# "label": "charmonitor", +# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.monitor,server", +# "frontend-open": true +# }, +# { +# "label": "charserial0", +# "filename": "pty:/dev/pts/2", +# "frontend-open": true +# } +# ] +# } +# +## +{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] } + +## +# @ChardevBackendInfo: +# +# Information about a character device backend +# +# @name: The backend name +# +# Since: 2.0 +## +{ 'struct': 'ChardevBackendInfo', 'data': {'name': 'str'} } + +## +# @query-chardev-backends: +# +# Returns information about character device backends. +# +# Returns: a list of @ChardevBackendInfo +# +# Since: 2.0 +# +# Example: +# +# -> { "execute": "query-chardev-backends" } +# <- { +# "return":[ +# { +# "name":"udp" +# }, +# { +# "name":"tcp" +# }, +# { +# "name":"unix" +# }, +# { +# "name":"spiceport" +# } +# ] +# } +# +## +{ 'command': 'query-chardev-backends', 'returns': ['ChardevBackendInfo'] } + +## +# @DataFormat: +# +# An enumeration of data format. +# +# @utf8: Data is a UTF-8 string (RFC 3629) +# +# @base64: Data is Base64 encoded binary (RFC 3548) +# +# Since: 1.4 +## +{ 'enum': 'DataFormat', + 'data': [ 'utf8', 'base64' ] } + +## +# @ringbuf-write: +# +# Write to a ring buffer character device. +# +# @device: the ring buffer character device name +# +# @data: data to write +# +# @format: data encoding (default 'utf8'). +# - base64: data must be base64 encoded text. Its binary +# decoding gets written. +# - utf8: data's UTF-8 encoding is written +# - data itself is always Unicode regardless of format, like +# any other string. +# +# Returns: Nothing on success +# +# Since: 1.4 +# +# Example: +# +# -> { "execute": "ringbuf-write", +# "arguments": { "device": "foo", +# "data": "abcdefgh", +# "format": "utf8" } } +# <- { "return": {} } +# +## +{ 'command': 'ringbuf-write', + 'data': {'device': 'str', 'data': 'str', + '*format': 'DataFormat'} } + +## +# @ringbuf-read: +# +# Read from a ring buffer character device. +# +# @device: the ring buffer character device name +# +# @size: how many bytes to read at most +# +# @format: data encoding (default 'utf8'). +# - base64: the data read is returned in base64 encoding. +# - utf8: the data read is interpreted as UTF-8. +# Bug: can screw up when the buffer contains invalid UTF-8 +# sequences, NUL characters, after the ring buffer lost +# data, and when reading stops because the size limit is +# reached. +# - The return value is always Unicode regardless of format, +# like any other string. +# +# Returns: data read from the device +# +# Since: 1.4 +# +# Example: +# +# -> { "execute": "ringbuf-read", +# "arguments": { "device": "foo", +# "size": 1000, +# "format": "utf8" } } +# <- { "return": "abcdefgh" } +# +## +{ 'command': 'ringbuf-read', + 'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'}, + 'returns': 'str' } + +## +# @ChardevCommon: +# +# Configuration shared across all chardev backends +# +# @logfile: The name of a logfile to save output +# @logappend: true to append instead of truncate +# (default to false to truncate) +# +# Since: 2.6 +## +{ 'struct': 'ChardevCommon', 'data': { '*logfile': 'str', + '*logappend': 'bool' } } + +## +# @ChardevFile: +# +# Configuration info for file chardevs. +# +# @in: The name of the input file +# @out: The name of the output file +# @append: Open the file in append mode (default false to +# truncate) (Since 2.6) +# +# Since: 1.4 +## +{ 'struct': 'ChardevFile', 'data': { '*in' : 'str', + 'out' : 'str', + '*append': 'bool' }, + 'base': 'ChardevCommon' } + +## +# @ChardevHostdev: +# +# Configuration info for device and pipe chardevs. +# +# @device: The name of the special file for the device, +# i.e. /dev/ttyS0 on Unix or COM1: on Windows +# +# Since: 1.4 +## +{ 'struct': 'ChardevHostdev', 'data': { 'device' : 'str' }, + 'base': 'ChardevCommon' } + +## +# @ChardevSocket: +# +# Configuration info for (stream) socket chardevs. +# +# @addr: socket address to listen on (server=true) +# or connect to (server=false) +# @tls-creds: the ID of the TLS credentials object (since 2.6) +# @server: create server socket (default: true) +# @wait: wait for incoming connection on server +# sockets (default: false). +# @nodelay: set TCP_NODELAY socket option (default: false) +# @telnet: enable telnet protocol on server +# sockets (default: false) +# @tn3270: enable tn3270 protocol on server +# sockets (default: false) (Since: 2.10) +# @reconnect: For a client socket, if a socket is disconnected, +# then attempt a reconnect after the given number of seconds. +# Setting this to zero disables this function. (default: 0) +# (Since: 2.2) +# +# Since: 1.4 +## +{ 'struct': 'ChardevSocket', 'data': { 'addr' : 'SocketAddressLegacy', + '*tls-creds' : 'str', + '*server' : 'bool', + '*wait' : 'bool', + '*nodelay' : 'bool', + '*telnet' : 'bool', + '*tn3270' : 'bool', + '*reconnect' : 'int' }, + 'base': 'ChardevCommon' } + +## +# @ChardevUdp: +# +# Configuration info for datagram socket chardevs. +# +# @remote: remote address +# @local: local address +# +# Since: 1.5 +## +{ 'struct': 'ChardevUdp', 'data': { 'remote' : 'SocketAddressLegacy', + '*local' : 'SocketAddressLegacy' }, + 'base': 'ChardevCommon' } + +## +# @ChardevMux: +# +# Configuration info for mux chardevs. +# +# @chardev: name of the base chardev. +# +# Since: 1.5 +## +{ 'struct': 'ChardevMux', 'data': { 'chardev' : 'str' }, + 'base': 'ChardevCommon' } + +## +# @ChardevStdio: +# +# Configuration info for stdio chardevs. +# +# @signal: Allow signals (such as SIGINT triggered by ^C) +# be delivered to qemu. Default: true in -nographic mode, +# false otherwise. +# +# Since: 1.5 +## +{ 'struct': 'ChardevStdio', 'data': { '*signal' : 'bool' }, + 'base': 'ChardevCommon' } + + +## +# @ChardevSpiceChannel: +# +# Configuration info for spice vm channel chardevs. +# +# @type: kind of channel (for example vdagent). +# +# Since: 1.5 +## +{ 'struct': 'ChardevSpiceChannel', 'data': { 'type' : 'str' }, + 'base': 'ChardevCommon' } + +## +# @ChardevSpicePort: +# +# Configuration info for spice port chardevs. +# +# @fqdn: name of the channel (see docs/spice-port-fqdn.txt) +# +# Since: 1.5 +## +{ 'struct': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' }, + 'base': 'ChardevCommon' } + +## +# @ChardevVC: +# +# Configuration info for virtual console chardevs. +# +# @width: console width, in pixels +# @height: console height, in pixels +# @cols: console width, in chars +# @rows: console height, in chars +# +# Since: 1.5 +## +{ 'struct': 'ChardevVC', 'data': { '*width' : 'int', + '*height' : 'int', + '*cols' : 'int', + '*rows' : 'int' }, + 'base': 'ChardevCommon' } + +## +# @ChardevRingbuf: +# +# Configuration info for ring buffer chardevs. +# +# @size: ring buffer size, must be power of two, default is 65536 +# +# Since: 1.5 +## +{ 'struct': 'ChardevRingbuf', 'data': { '*size' : 'int' }, + 'base': 'ChardevCommon' } + +## +# @ChardevBackend: +# +# Configuration info for the new chardev backend. +# +# Since: 1.4 (testdev since 2.2, wctablet since 2.9) +## +{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile', + 'serial' : 'ChardevHostdev', + 'parallel': 'ChardevHostdev', + 'pipe' : 'ChardevHostdev', + 'socket' : 'ChardevSocket', + 'udp' : 'ChardevUdp', + 'pty' : 'ChardevCommon', + 'null' : 'ChardevCommon', + 'mux' : 'ChardevMux', + 'msmouse': 'ChardevCommon', + 'wctablet' : 'ChardevCommon', + 'braille': 'ChardevCommon', + 'testdev': 'ChardevCommon', + 'stdio' : 'ChardevStdio', + 'console': 'ChardevCommon', + 'spicevmc' : 'ChardevSpiceChannel', + 'spiceport' : 'ChardevSpicePort', + 'vc' : 'ChardevVC', + 'ringbuf': 'ChardevRingbuf', + # next one is just for compatibility + 'memory' : 'ChardevRingbuf' } } + +## +# @ChardevReturn: +# +# Return info about the chardev backend just created. +# +# @pty: name of the slave pseudoterminal device, present if +# and only if a chardev of type 'pty' was created +# +# Since: 1.4 +## +{ 'struct' : 'ChardevReturn', 'data': { '*pty' : 'str' } } + +## +# @chardev-add: +# +# Add a character device backend +# +# @id: the chardev's ID, must be unique +# @backend: backend type and parameters +# +# Returns: ChardevReturn. +# +# Since: 1.4 +# +# Example: +# +# -> { "execute" : "chardev-add", +# "arguments" : { "id" : "foo", +# "backend" : { "type" : "null", "data" : {} } } } +# <- { "return": {} } +# +# -> { "execute" : "chardev-add", +# "arguments" : { "id" : "bar", +# "backend" : { "type" : "file", +# "data" : { "out" : "/tmp/bar.log" } } } } +# <- { "return": {} } +# +# -> { "execute" : "chardev-add", +# "arguments" : { "id" : "baz", +# "backend" : { "type" : "pty", "data" : {} } } } +# <- { "return": { "pty" : "/dev/pty/42" } } +# +## +{ 'command': 'chardev-add', 'data': {'id' : 'str', + 'backend' : 'ChardevBackend' }, + 'returns': 'ChardevReturn' } + +## +# @chardev-change: +# +# Change a character device backend +# +# @id: the chardev's ID, must exist +# @backend: new backend type and parameters +# +# Returns: ChardevReturn. +# +# Since: 2.10 +# +# Example: +# +# -> { "execute" : "chardev-change", +# "arguments" : { "id" : "baz", +# "backend" : { "type" : "pty", "data" : {} } } } +# <- { "return": { "pty" : "/dev/pty/42" } } +# +# -> {"execute" : "chardev-change", +# "arguments" : { +# "id" : "charchannel2", +# "backend" : { +# "type" : "socket", +# "data" : { +# "addr" : { +# "type" : "unix" , +# "data" : { +# "path" : "/tmp/charchannel2.socket" +# } +# }, +# "server" : true, +# "wait" : false }}}} +# <- {"return": {}} +# +## +{ 'command': 'chardev-change', 'data': {'id' : 'str', + 'backend' : 'ChardevBackend' }, + 'returns': 'ChardevReturn' } + +## +# @chardev-remove: +# +# Remove a character device backend +# +# @id: the chardev's ID, must exist and not be in use +# +# Returns: Nothing on success +# +# Since: 1.4 +# +# Example: +# +# -> { "execute": "chardev-remove", "arguments": { "id" : "foo" } } +# <- { "return": {} } +# +## +{ 'command': 'chardev-remove', 'data': {'id': 'str'} } + +## +# @chardev-send-break: +# +# Send a break to a character device +# +# @id: the chardev's ID, must exist +# +# Returns: Nothing on success +# +# Since: 2.10 +# +# Example: +# +# -> { "execute": "chardev-send-break", "arguments": { "id" : "foo" } } +# <- { "return": {} } +# +## +{ 'command': 'chardev-send-break', 'data': {'id': 'str'} } + +## +# @VSERPORT_CHANGE: +# +# Emitted when the guest opens or closes a virtio-serial port. +# +# @id: device identifier of the virtio-serial port +# +# @open: true if the guest has opened the virtio-serial port +# +# Since: 2.1 +# +# Example: +# +# <- { "event": "VSERPORT_CHANGE", +# "data": { "id": "channel0", "open": true }, +# "timestamp": { "seconds": 1401385907, "microseconds": 422329 } } +# +## +{ 'event': 'VSERPORT_CHANGE', + 'data': { 'id': 'str', 'open': 'bool' } } diff --git a/qapi/common.json b/qapi/common.json index 8355d5a2f3..6eb01821ef 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -1,7 +1,7 @@ # -*- Mode: Python -*- ## -# = QAPI common definitions +# = Common data types ## ## @@ -29,107 +29,18 @@ 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] } ## -# @VersionTriple: +# @IoOperationType: # -# A three-part version number. +# An enumeration of the I/O operation types # -# @major: The major version number. +# @read: read operation # -# @minor: The minor version number. -# -# @micro: The micro version number. -# -# Since: 2.4 -## -{ 'struct': 'VersionTriple', - 'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} } - - -## -# @VersionInfo: -# -# A description of QEMU's version. -# -# @qemu: The version of QEMU. By current convention, a micro -# version of 50 signifies a development branch. A micro version -# greater than or equal to 90 signifies a release candidate for -# the next minor version. A micro version of less than 50 -# signifies a stable release. -# -# @package: QEMU will always set this field to an empty string. Downstream -# versions of QEMU should set this to a non-empty string. The -# exact format depends on the downstream however it highly -# recommended that a unique name is used. -# -# Since: 0.14.0 -## -{ 'struct': 'VersionInfo', - 'data': {'qemu': 'VersionTriple', 'package': 'str'} } - -## -# @query-version: -# -# Returns the current version of QEMU. -# -# Returns: A @VersionInfo object describing the current version of QEMU. -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-version" } -# <- { -# "return":{ -# "qemu":{ -# "major":0, -# "minor":11, -# "micro":5 -# }, -# "package":"" -# } -# } -# -## -{ 'command': 'query-version', 'returns': 'VersionInfo' } - -## -# @CommandInfo: -# -# Information about a QMP command -# -# @name: The command name -# -# Since: 0.14.0 -## -{ 'struct': 'CommandInfo', 'data': {'name': 'str'} } - -## -# @query-commands: -# -# Return a list of supported QMP commands by this server -# -# Returns: A list of @CommandInfo for all supported commands -# -# Since: 0.14.0 -# -# Example: -# -# -> { "execute": "query-commands" } -# <- { -# "return":[ -# { -# "name":"query-balloon" -# }, -# { -# "name":"system_powerdown" -# } -# ] -# } -# -# Note: This example has been shortened as the real response is too long. +# @write: write operation # +# Since: 2.1 ## -{ 'command': 'query-commands', 'returns': ['CommandInfo'] } +{ 'enum': 'IoOperationType', + 'data': [ 'read', 'write' ] } ## # @OnOffAuto: @@ -162,3 +73,30 @@ ## { 'enum': 'OnOffSplit', 'data': [ 'on', 'off', 'split' ] } + +## +# @String: +# +# A fat type wrapping 'str', to be embedded in lists. +# +# Since: 1.2 +## +{ 'struct': 'String', + 'data': { + 'str': 'str' } } + +## +# @StrOrNull: +# +# This is a string value or the explicit lack of a string (null +# pointer in C). Intended for cases when 'optional absent' already +# has a different meaning. +# +# @s: the string value +# @n: no string value +# +# Since: 2.10 +## +{ 'alternate': 'StrOrNull', + 'data': { 's': 'str', + 'n': 'null' } } diff --git a/qapi/crypto.json b/qapi/crypto.json index 6b6fde367a..288bc056ef 100644 --- a/qapi/crypto.json +++ b/qapi/crypto.json @@ -2,7 +2,7 @@ # ## -# = QAPI crypto definitions +# = Cryptography ## ## diff --git a/qapi/event.json b/qapi/event.json deleted file mode 100644 index 6d22b025cc..0000000000 --- a/qapi/event.json +++ /dev/null @@ -1,646 +0,0 @@ -# -*- Mode: Python -*- - -## -# = Other events -## - -## -# @SHUTDOWN: -# -# Emitted when the virtual machine has shut down, indicating that qemu is -# about to exit. -# -# @guest: If true, the shutdown was triggered by a guest request (such as -# a guest-initiated ACPI shutdown request or other hardware-specific action) -# rather than a host request (such as sending qemu a SIGINT). (since 2.10) -# -# Note: If the command-line option "-no-shutdown" has been specified, qemu will -# not exit, and a STOP event will eventually follow the SHUTDOWN event -# -# Since: 0.12.0 -# -# Example: -# -# <- { "event": "SHUTDOWN", "data": { "guest": true }, -# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } -# -## -{ 'event': 'SHUTDOWN', 'data': { 'guest': 'bool' } } - -## -# @POWERDOWN: -# -# Emitted when the virtual machine is powered down through the power control -# system, such as via ACPI. -# -# Since: 0.12.0 -# -# Example: -# -# <- { "event": "POWERDOWN", -# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } -# -## -{ 'event': 'POWERDOWN' } - -## -# @RESET: -# -# Emitted when the virtual machine is reset -# -# @guest: If true, the reset was triggered by a guest request (such as -# a guest-initiated ACPI reboot request or other hardware-specific action) -# rather than a host request (such as the QMP command system_reset). -# (since 2.10) -# -# Since: 0.12.0 -# -# Example: -# -# <- { "event": "RESET", "data": { "guest": false }, -# "timestamp": { "seconds": 1267041653, "microseconds": 9518 } } -# -## -{ 'event': 'RESET', 'data': { 'guest': 'bool' } } - -## -# @STOP: -# -# Emitted when the virtual machine is stopped -# -# Since: 0.12.0 -# -# Example: -# -# <- { "event": "STOP", -# "timestamp": { "seconds": 1267041730, "microseconds": 281295 } } -# -## -{ 'event': 'STOP' } - -## -# @RESUME: -# -# Emitted when the virtual machine resumes execution -# -# Since: 0.12.0 -# -# Example: -# -# <- { "event": "RESUME", -# "timestamp": { "seconds": 1271770767, "microseconds": 582542 } } -# -## -{ 'event': 'RESUME' } - -## -# @SUSPEND: -# -# Emitted when guest enters a hardware suspension state, for example, S3 state, -# which is sometimes called standby state -# -# Since: 1.1 -# -# Example: -# -# <- { "event": "SUSPEND", -# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } -# -## -{ 'event': 'SUSPEND' } - -## -# @SUSPEND_DISK: -# -# Emitted when guest enters a hardware suspension state with data saved on -# disk, for example, S4 state, which is sometimes called hibernate state -# -# Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state -# -# Since: 1.2 -# -# Example: -# -# <- { "event": "SUSPEND_DISK", -# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } -# -## -{ 'event': 'SUSPEND_DISK' } - -## -# @WAKEUP: -# -# Emitted when the guest has woken up from suspend state and is running -# -# Since: 1.1 -# -# Example: -# -# <- { "event": "WAKEUP", -# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } -# -## -{ 'event': 'WAKEUP' } - -## -# @RTC_CHANGE: -# -# Emitted when the guest changes the RTC time. -# -# @offset: offset between base RTC clock (as specified by -rtc base), and -# new RTC clock value -# -# Note: This event is rate-limited. -# -# Since: 0.13.0 -# -# Example: -# -# <- { "event": "RTC_CHANGE", -# "data": { "offset": 78 }, -# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } -# -## -{ 'event': 'RTC_CHANGE', - 'data': { 'offset': 'int' } } - -## -# @WATCHDOG: -# -# Emitted when the watchdog device's timer is expired -# -# @action: action that has been taken -# -# Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is -# followed respectively by the RESET, SHUTDOWN, or STOP events -# -# Note: This event is rate-limited. -# -# Since: 0.13.0 -# -# Example: -# -# <- { "event": "WATCHDOG", -# "data": { "action": "reset" }, -# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } } -# -## -{ 'event': 'WATCHDOG', - 'data': { 'action': 'WatchdogExpirationAction' } } - -## -# @DEVICE_DELETED: -# -# Emitted whenever the device removal completion is acknowledged by the guest. -# At this point, it's safe to reuse the specified device ID. Device removal can -# be initiated by the guest or by HMP/QMP commands. -# -# @device: device name -# -# @path: device path -# -# Since: 1.5 -# -# Example: -# -# <- { "event": "DEVICE_DELETED", -# "data": { "device": "virtio-net-pci-0", -# "path": "/machine/peripheral/virtio-net-pci-0" }, -# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } -# -## -{ 'event': 'DEVICE_DELETED', - 'data': { '*device': 'str', 'path': 'str' } } - -## -# @NIC_RX_FILTER_CHANGED: -# -# Emitted once until the 'query-rx-filter' command is executed, the first event -# will always be emitted -# -# @name: net client name -# -# @path: device path -# -# Since: 1.6 -# -# Example: -# -# <- { "event": "NIC_RX_FILTER_CHANGED", -# "data": { "name": "vnet0", -# "path": "/machine/peripheral/vnet0/virtio-backend" }, -# "timestamp": { "seconds": 1368697518, "microseconds": 326866 } } -# } -# -## -{ 'event': 'NIC_RX_FILTER_CHANGED', - 'data': { '*name': 'str', 'path': 'str' } } - -## -# @VNC_CONNECTED: -# -# Emitted when a VNC client establishes a connection -# -# @server: server information -# -# @client: client information -# -# Note: This event is emitted before any authentication takes place, thus -# the authentication ID is not provided -# -# Since: 0.13.0 -# -# Example: -# -# <- { "event": "VNC_CONNECTED", -# "data": { -# "server": { "auth": "sasl", "family": "ipv4", -# "service": "5901", "host": "0.0.0.0" }, -# "client": { "family": "ipv4", "service": "58425", -# "host": "127.0.0.1" } }, -# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } } -# -## -{ 'event': 'VNC_CONNECTED', - 'data': { 'server': 'VncServerInfo', - 'client': 'VncBasicInfo' } } - -## -# @VNC_INITIALIZED: -# -# Emitted after authentication takes place (if any) and the VNC session is -# made active -# -# @server: server information -# -# @client: client information -# -# Since: 0.13.0 -# -# Example: -# -# <- { "event": "VNC_INITIALIZED", -# "data": { -# "server": { "auth": "sasl", "family": "ipv4", -# "service": "5901", "host": "0.0.0.0"}, -# "client": { "family": "ipv4", "service": "46089", -# "host": "127.0.0.1", "sasl_username": "luiz" } }, -# "timestamp": { "seconds": 1263475302, "microseconds": 150772 } } -# -## -{ 'event': 'VNC_INITIALIZED', - 'data': { 'server': 'VncServerInfo', - 'client': 'VncClientInfo' } } - -## -# @VNC_DISCONNECTED: -# -# Emitted when the connection is closed -# -# @server: server information -# -# @client: client information -# -# Since: 0.13.0 -# -# Example: -# -# <- { "event": "VNC_DISCONNECTED", -# "data": { -# "server": { "auth": "sasl", "family": "ipv4", -# "service": "5901", "host": "0.0.0.0" }, -# "client": { "family": "ipv4", "service": "58425", -# "host": "127.0.0.1", "sasl_username": "luiz" } }, -# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } } -# -## -{ 'event': 'VNC_DISCONNECTED', - 'data': { 'server': 'VncServerInfo', - 'client': 'VncClientInfo' } } - -## -# @SPICE_CONNECTED: -# -# Emitted when a SPICE client establishes a connection -# -# @server: server information -# -# @client: client information -# -# Since: 0.14.0 -# -# Example: -# -# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, -# "event": "SPICE_CONNECTED", -# "data": { -# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"}, -# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"} -# }} -# -## -{ 'event': 'SPICE_CONNECTED', - 'data': { 'server': 'SpiceBasicInfo', - 'client': 'SpiceBasicInfo' } } - -## -# @SPICE_INITIALIZED: -# -# Emitted after initial handshake and authentication takes place (if any) -# and the SPICE channel is up and running -# -# @server: server information -# -# @client: client information -# -# Since: 0.14.0 -# -# Example: -# -# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, -# "event": "SPICE_INITIALIZED", -# "data": {"server": {"auth": "spice", "port": "5921", -# "family": "ipv4", "host": "127.0.0.1"}, -# "client": {"port": "49004", "family": "ipv4", "channel-type": 3, -# "connection-id": 1804289383, "host": "127.0.0.1", -# "channel-id": 0, "tls": true} -# }} -# -## -{ 'event': 'SPICE_INITIALIZED', - 'data': { 'server': 'SpiceServerInfo', - 'client': 'SpiceChannel' } } - -## -# @SPICE_DISCONNECTED: -# -# Emitted when the SPICE connection is closed -# -# @server: server information -# -# @client: client information -# -# Since: 0.14.0 -# -# Example: -# -# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, -# "event": "SPICE_DISCONNECTED", -# "data": { -# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"}, -# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"} -# }} -# -## -{ 'event': 'SPICE_DISCONNECTED', - 'data': { 'server': 'SpiceBasicInfo', - 'client': 'SpiceBasicInfo' } } - -## -# @SPICE_MIGRATE_COMPLETED: -# -# Emitted when SPICE migration has completed -# -# Since: 1.3 -# -# Example: -# -# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, -# "event": "SPICE_MIGRATE_COMPLETED" } -# -## -{ 'event': 'SPICE_MIGRATE_COMPLETED' } - -## -# @MIGRATION: -# -# Emitted when a migration event happens -# -# @status: @MigrationStatus describing the current migration status. -# -# Since: 2.4 -# -# Example: -# -# <- {"timestamp": {"seconds": 1432121972, "microseconds": 744001}, -# "event": "MIGRATION", -# "data": {"status": "completed"} } -# -## -{ 'event': 'MIGRATION', - 'data': {'status': 'MigrationStatus'}} - -## -# @MIGRATION_PASS: -# -# Emitted from the source side of a migration at the start of each pass -# (when it syncs the dirty bitmap) -# -# @pass: An incrementing count (starting at 1 on the first pass) -# -# Since: 2.6 -# -# Example: -# -# { "timestamp": {"seconds": 1449669631, "microseconds": 239225}, -# "event": "MIGRATION_PASS", "data": {"pass": 2} } -# -## -{ 'event': 'MIGRATION_PASS', - 'data': { 'pass': 'int' } } - -## -# @ACPI_DEVICE_OST: -# -# Emitted when guest executes ACPI _OST method. -# -# @info: ACPIOSTInfo type as described in qapi-schema.json -# -# Since: 2.1 -# -# Example: -# -# <- { "event": "ACPI_DEVICE_OST", -# "data": { "device": "d1", "slot": "0", -# "slot-type": "DIMM", "source": 1, "status": 0 } } -# -## -{ 'event': 'ACPI_DEVICE_OST', - 'data': { 'info': 'ACPIOSTInfo' } } - -## -# @BALLOON_CHANGE: -# -# Emitted when the guest changes the actual BALLOON level. This value is -# equivalent to the @actual field return by the 'query-balloon' command -# -# @actual: actual level of the guest memory balloon in bytes -# -# Note: this event is rate-limited. -# -# Since: 1.2 -# -# Example: -# -# <- { "event": "BALLOON_CHANGE", -# "data": { "actual": 944766976 }, -# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } -# -## -{ 'event': 'BALLOON_CHANGE', - 'data': { 'actual': 'int' } } - -## -# @GUEST_PANICKED: -# -# Emitted when guest OS panic is detected -# -# @action: action that has been taken, currently always "pause" -# -# @info: information about a panic (since 2.9) -# -# Since: 1.5 -# -# Example: -# -# <- { "event": "GUEST_PANICKED", -# "data": { "action": "pause" } } -# -## -{ 'event': 'GUEST_PANICKED', - 'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } } - -## -# @QUORUM_FAILURE: -# -# Emitted by the Quorum block driver if it fails to establish a quorum -# -# @reference: device name if defined else node name -# -# @sector-num: number of the first sector of the failed read operation -# -# @sectors-count: failed read operation sector count -# -# Note: This event is rate-limited. -# -# Since: 2.0 -# -# Example: -# -# <- { "event": "QUORUM_FAILURE", -# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 }, -# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } -# -## -{ 'event': 'QUORUM_FAILURE', - 'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } } - -## -# @QUORUM_REPORT_BAD: -# -# Emitted to report a corruption of a Quorum file -# -# @type: quorum operation type (Since 2.6) -# -# @error: error message. Only present on failure. This field -# contains a human-readable error message. There are no semantics other -# than that the block layer reported an error and clients should not -# try to interpret the error string. -# -# @node-name: the graph node name of the block driver state -# -# @sector-num: number of the first sector of the failed read operation -# -# @sectors-count: failed read operation sector count -# -# Note: This event is rate-limited. -# -# Since: 2.0 -# -# Example: -# -# 1. Read operation -# -# { "event": "QUORUM_REPORT_BAD", -# "data": { "node-name": "node0", "sector-num": 345435, "sectors-count": 5, -# "type": "read" }, -# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } -# -# 2. Flush operation -# -# { "event": "QUORUM_REPORT_BAD", -# "data": { "node-name": "node0", "sector-num": 0, "sectors-count": 2097120, -# "type": "flush", "error": "Broken pipe" }, -# "timestamp": { "seconds": 1456406829, "microseconds": 291763 } } -# -## -{ 'event': 'QUORUM_REPORT_BAD', - 'data': { 'type': 'QuorumOpType', '*error': 'str', 'node-name': 'str', - 'sector-num': 'int', 'sectors-count': 'int' } } - -## -# @VSERPORT_CHANGE: -# -# Emitted when the guest opens or closes a virtio-serial port. -# -# @id: device identifier of the virtio-serial port -# -# @open: true if the guest has opened the virtio-serial port -# -# Since: 2.1 -# -# Example: -# -# <- { "event": "VSERPORT_CHANGE", -# "data": { "id": "channel0", "open": true }, -# "timestamp": { "seconds": 1401385907, "microseconds": 422329 } } -# -## -{ 'event': 'VSERPORT_CHANGE', - 'data': { 'id': 'str', 'open': 'bool' } } - -## -# @MEM_UNPLUG_ERROR: -# -# Emitted when memory hot unplug error occurs. -# -# @device: device name -# -# @msg: Informative message -# -# Since: 2.4 -# -# Example: -# -# <- { "event": "MEM_UNPLUG_ERROR" -# "data": { "device": "dimm1", -# "msg": "acpi: device unplug for unsupported device" -# }, -# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } -# -## -{ 'event': 'MEM_UNPLUG_ERROR', - 'data': { 'device': 'str', 'msg': 'str' } } - -## -# @DUMP_COMPLETED: -# -# Emitted when background dump has completed -# -# @result: DumpQueryResult type described in qapi-schema.json. -# -# @error: human-readable error string that provides -# hint on why dump failed. Only presents on failure. The -# user should not try to interpret the error string. -# -# Since: 2.6 -# -# Example: -# -# { "event": "DUMP_COMPLETED", -# "data": {"result": {"total": 1090650112, "status": "completed", -# "completed": 1090650112} } } -# -## -{ 'event': 'DUMP_COMPLETED' , - 'data': { 'result': 'DumpQueryResult', '*error': 'str' } } diff --git a/qapi/introspect.json b/qapi/introspect.json index cf77ff0669..5b3e6e9d78 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -1,7 +1,5 @@ # -*- Mode: Python -*- # -# QAPI/QMP introspection -# # Copyright (C) 2015 Red Hat, Inc. # # Authors: @@ -11,6 +9,10 @@ # See the COPYING file in the top-level directory. ## +# = QMP introspection +## + +## # @query-qmp-schema: # # Command query-qmp-schema exposes the QMP wire ABI as an array of diff --git a/qapi/migration.json b/qapi/migration.json new file mode 100644 index 0000000000..ee2b3b8733 --- /dev/null +++ b/qapi/migration.json @@ -0,0 +1,1085 @@ +# -*- Mode: Python -*- +# + +## +# = Migration +## + +{ 'include': 'common.json' } + +## +# @MigrationStats: +# +# Detailed migration status. +# +# @transferred: amount of bytes already transferred to the target VM +# +# @remaining: amount of bytes remaining to be transferred to the target VM +# +# @total: total amount of bytes involved in the migration process +# +# @duplicate: number of duplicate (zero) pages (since 1.2) +# +# @skipped: number of skipped zero pages (since 1.5) +# +# @normal: number of normal pages (since 1.2) +# +# @normal-bytes: number of normal bytes sent (since 1.2) +# +# @dirty-pages-rate: number of pages dirtied by second by the +# guest (since 1.3) +# +# @mbps: throughput in megabits/sec. (since 1.6) +# +# @dirty-sync-count: number of times that dirty ram was synchronized (since 2.1) +# +# @postcopy-requests: The number of page requests received from the destination +# (since 2.7) +# +# @page-size: The number of bytes per page for the various page-based +# statistics (since 2.10) +# +# Since: 0.14.0 +## +{ 'struct': 'MigrationStats', + 'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' , + 'duplicate': 'int', 'skipped': 'int', 'normal': 'int', + 'normal-bytes': 'int', 'dirty-pages-rate' : 'int', + 'mbps' : 'number', 'dirty-sync-count' : 'int', + 'postcopy-requests' : 'int', 'page-size' : 'int' } } + +## +# @XBZRLECacheStats: +# +# Detailed XBZRLE migration cache statistics +# +# @cache-size: XBZRLE cache size +# +# @bytes: amount of bytes already transferred to the target VM +# +# @pages: amount of pages transferred to the target VM +# +# @cache-miss: number of cache miss +# +# @cache-miss-rate: rate of cache miss (since 2.1) +# +# @overflow: number of overflows +# +# Since: 1.2 +## +{ 'struct': 'XBZRLECacheStats', + 'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int', + 'cache-miss': 'int', 'cache-miss-rate': 'number', + 'overflow': 'int' } } + +## +# @MigrationStatus: +# +# An enumeration of migration status. +# +# @none: no migration has ever happened. +# +# @setup: migration process has been initiated. +# +# @cancelling: in the process of cancelling migration. +# +# @cancelled: cancelling migration is finished. +# +# @active: in the process of doing migration. +# +# @postcopy-active: like active, but now in postcopy mode. (since 2.5) +# +# @completed: migration is finished. +# +# @failed: some error occurred during migration process. +# +# @colo: VM is in the process of fault tolerance, VM can not get into this +# state unless colo capability is enabled for migration. (since 2.8) +# +# Since: 2.3 +# +## +{ 'enum': 'MigrationStatus', + 'data': [ 'none', 'setup', 'cancelling', 'cancelled', + 'active', 'postcopy-active', 'completed', 'failed', 'colo' ] } + +## +# @MigrationInfo: +# +# Information about current migration process. +# +# @status: @MigrationStatus describing the current migration status. +# If this field is not returned, no migration process +# has been initiated +# +# @ram: @MigrationStats containing detailed migration +# status, only returned if status is 'active' or +# 'completed'(since 1.2) +# +# @disk: @MigrationStats containing detailed disk migration +# status, only returned if status is 'active' and it is a block +# migration +# +# @xbzrle-cache: @XBZRLECacheStats containing detailed XBZRLE +# migration statistics, only returned if XBZRLE feature is on and +# status is 'active' or 'completed' (since 1.2) +# +# @total-time: total amount of milliseconds since migration started. +# If migration has ended, it returns the total migration +# time. (since 1.2) +# +# @downtime: only present when migration finishes correctly +# total downtime in milliseconds for the guest. +# (since 1.3) +# +# @expected-downtime: only present while migration is active +# expected downtime in milliseconds for the guest in last walk +# of the dirty bitmap. (since 1.3) +# +# @setup-time: amount of setup time in milliseconds _before_ the +# iterations begin but _after_ the QMP command is issued. This is designed +# to provide an accounting of any activities (such as RDMA pinning) which +# may be expensive, but do not actually occur during the iterative +# migration rounds themselves. (since 1.6) +# +# @cpu-throttle-percentage: percentage of time guest cpus are being +# throttled during auto-converge. This is only present when auto-converge +# has started throttling guest cpus. (Since 2.7) +# +# @error-desc: the human readable error description string, when +# @status is 'failed'. Clients should not attempt to parse the +# error strings. (Since 2.7) +# +# Since: 0.14.0 +## +{ 'struct': 'MigrationInfo', + 'data': {'*status': 'MigrationStatus', '*ram': 'MigrationStats', + '*disk': 'MigrationStats', + '*xbzrle-cache': 'XBZRLECacheStats', + '*total-time': 'int', + '*expected-downtime': 'int', + '*downtime': 'int', + '*setup-time': 'int', + '*cpu-throttle-percentage': 'int', + '*error-desc': 'str'} } + +## +# @query-migrate: +# +# Returns information about current migration process. If migration +# is active there will be another json-object with RAM migration +# status and if block migration is active another one with block +# migration status. +# +# Returns: @MigrationInfo +# +# Since: 0.14.0 +# +# Example: +# +# 1. Before the first migration +# +# -> { "execute": "query-migrate" } +# <- { "return": {} } +# +# 2. Migration is done and has succeeded +# +# -> { "execute": "query-migrate" } +# <- { "return": { +# "status": "completed", +# "ram":{ +# "transferred":123, +# "remaining":123, +# "total":246, +# "total-time":12345, +# "setup-time":12345, +# "downtime":12345, +# "duplicate":123, +# "normal":123, +# "normal-bytes":123456, +# "dirty-sync-count":15 +# } +# } +# } +# +# 3. Migration is done and has failed +# +# -> { "execute": "query-migrate" } +# <- { "return": { "status": "failed" } } +# +# 4. Migration is being performed and is not a block migration: +# +# -> { "execute": "query-migrate" } +# <- { +# "return":{ +# "status":"active", +# "ram":{ +# "transferred":123, +# "remaining":123, +# "total":246, +# "total-time":12345, +# "setup-time":12345, +# "expected-downtime":12345, +# "duplicate":123, +# "normal":123, +# "normal-bytes":123456, +# "dirty-sync-count":15 +# } +# } +# } +# +# 5. Migration is being performed and is a block migration: +# +# -> { "execute": "query-migrate" } +# <- { +# "return":{ +# "status":"active", +# "ram":{ +# "total":1057024, +# "remaining":1053304, +# "transferred":3720, +# "total-time":12345, +# "setup-time":12345, +# "expected-downtime":12345, +# "duplicate":123, +# "normal":123, +# "normal-bytes":123456, +# "dirty-sync-count":15 +# }, +# "disk":{ +# "total":20971520, +# "remaining":20880384, +# "transferred":91136 +# } +# } +# } +# +# 6. Migration is being performed and XBZRLE is active: +# +# -> { "execute": "query-migrate" } +# <- { +# "return":{ +# "status":"active", +# "capabilities" : [ { "capability": "xbzrle", "state" : true } ], +# "ram":{ +# "total":1057024, +# "remaining":1053304, +# "transferred":3720, +# "total-time":12345, +# "setup-time":12345, +# "expected-downtime":12345, +# "duplicate":10, +# "normal":3333, +# "normal-bytes":3412992, +# "dirty-sync-count":15 +# }, +# "xbzrle-cache":{ +# "cache-size":67108864, +# "bytes":20971520, +# "pages":2444343, +# "cache-miss":2244, +# "cache-miss-rate":0.123, +# "overflow":34434 +# } +# } +# } +# +## +{ 'command': 'query-migrate', 'returns': 'MigrationInfo' } + +## +# @MigrationCapability: +# +# Migration capabilities enumeration +# +# @xbzrle: Migration supports xbzrle (Xor Based Zero Run Length Encoding). +# This feature allows us to minimize migration traffic for certain work +# loads, by sending compressed difference of the pages +# +# @rdma-pin-all: Controls whether or not the entire VM memory footprint is +# mlock()'d on demand or all at once. Refer to docs/rdma.txt for usage. +# Disabled by default. (since 2.0) +# +# @zero-blocks: During storage migration encode blocks of zeroes efficiently. This +# essentially saves 1MB of zeroes per block on the wire. Enabling requires +# source and target VM to support this feature. To enable it is sufficient +# to enable the capability on the source VM. The feature is disabled by +# default. (since 1.6) +# +# @compress: Use multiple compression threads to accelerate live migration. +# This feature can help to reduce the migration traffic, by sending +# compressed pages. Please note that if compress and xbzrle are both +# on, compress only takes effect in the ram bulk stage, after that, +# it will be disabled and only xbzrle takes effect, this can help to +# minimize migration traffic. The feature is disabled by default. +# (since 2.4 ) +# +# @events: generate events for each migration state change +# (since 2.4 ) +# +# @auto-converge: If enabled, QEMU will automatically throttle down the guest +# to speed up convergence of RAM migration. (since 1.6) +# +# @postcopy-ram: Start executing on the migration target before all of RAM has +# been migrated, pulling the remaining pages along as needed. NOTE: If +# the migration fails during postcopy the VM will fail. (since 2.6) +# +# @x-colo: If enabled, migration will never end, and the state of the VM on the +# primary side will be migrated continuously to the VM on secondary +# side, this process is called COarse-Grain LOck Stepping (COLO) for +# Non-stop Service. (since 2.8) +# +# @release-ram: if enabled, qemu will free the migrated ram pages on the source +# during postcopy-ram migration. (since 2.9) +# +# @block: If enabled, QEMU will also migrate the contents of all block +# devices. Default is disabled. A possible alternative uses +# mirror jobs to a builtin NBD server on the destination, which +# offers more flexibility. +# (Since 2.10) +# +# @return-path: If enabled, migration will use the return path even +# for precopy. (since 2.10) +# +# Since: 1.2 +## +{ 'enum': 'MigrationCapability', + 'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks', + 'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram', + 'block', 'return-path' ] } + +## +# @MigrationCapabilityStatus: +# +# Migration capability information +# +# @capability: capability enum +# +# @state: capability state bool +# +# Since: 1.2 +## +{ 'struct': 'MigrationCapabilityStatus', + 'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } } + +## +# @migrate-set-capabilities: +# +# Enable/Disable the following migration capabilities (like xbzrle) +# +# @capabilities: json array of capability modifications to make +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "migrate-set-capabilities" , "arguments": +# { "capabilities": [ { "capability": "xbzrle", "state": true } ] } } +# +## +{ 'command': 'migrate-set-capabilities', + 'data': { 'capabilities': ['MigrationCapabilityStatus'] } } + +## +# @query-migrate-capabilities: +# +# Returns information about the current migration capabilities status +# +# Returns: @MigrationCapabilitiesStatus +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "query-migrate-capabilities" } +# <- { "return": [ +# {"state": false, "capability": "xbzrle"}, +# {"state": false, "capability": "rdma-pin-all"}, +# {"state": false, "capability": "auto-converge"}, +# {"state": false, "capability": "zero-blocks"}, +# {"state": false, "capability": "compress"}, +# {"state": true, "capability": "events"}, +# {"state": false, "capability": "postcopy-ram"}, +# {"state": false, "capability": "x-colo"} +# ]} +# +## +{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']} + +## +# @MigrationParameter: +# +# Migration parameters enumeration +# +# @compress-level: Set the compression level to be used in live migration, +# the compression level is an integer between 0 and 9, where 0 means +# no compression, 1 means the best compression speed, and 9 means best +# compression ratio which will consume more CPU. +# +# @compress-threads: Set compression thread count to be used in live migration, +# the compression thread count is an integer between 1 and 255. +# +# @decompress-threads: Set decompression thread count to be used in live +# migration, the decompression thread count is an integer between 1 +# and 255. Usually, decompression is at least 4 times as fast as +# compression, so set the decompress-threads to the number about 1/4 +# of compress-threads is adequate. +# +# @cpu-throttle-initial: Initial percentage of time guest cpus are throttled +# when migration auto-converge is activated. The +# default value is 20. (Since 2.7) +# +# @cpu-throttle-increment: throttle percentage increase each time +# auto-converge detects that migration is not making +# progress. The default value is 10. (Since 2.7) +# +# @tls-creds: ID of the 'tls-creds' object that provides credentials for +# establishing a TLS connection over the migration data channel. +# On the outgoing side of the migration, the credentials must +# be for a 'client' endpoint, while for the incoming side the +# credentials must be for a 'server' endpoint. Setting this +# will enable TLS for all migrations. The default is unset, +# resulting in unsecured migration at the QEMU level. (Since 2.7) +# +# @tls-hostname: hostname of the target host for the migration. This is +# required when using x509 based TLS credentials and the +# migration URI does not already include a hostname. For +# example if using fd: or exec: based migration, the +# hostname must be provided so that the server's x509 +# certificate identity can be validated. (Since 2.7) +# +# @max-bandwidth: to set maximum speed for migration. maximum speed in +# bytes per second. (Since 2.8) +# +# @downtime-limit: set maximum tolerated downtime for migration. maximum +# downtime in milliseconds (Since 2.8) +# +# @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in +# periodic mode. (Since 2.8) +# +# @block-incremental: Affects how much storage is migrated when the +# block migration capability is enabled. When false, the entire +# storage backing chain is migrated into a flattened image at +# the destination; when true, only the active qcow2 layer is +# migrated and the destination must already have access to the +# same backing chain as was used on the source. (since 2.10) +# +# Since: 2.4 +## +{ 'enum': 'MigrationParameter', + 'data': ['compress-level', 'compress-threads', 'decompress-threads', + 'cpu-throttle-initial', 'cpu-throttle-increment', + 'tls-creds', 'tls-hostname', 'max-bandwidth', + 'downtime-limit', 'x-checkpoint-delay', 'block-incremental' ] } + +## +# @MigrateSetParameters: +# +# @compress-level: compression level +# +# @compress-threads: compression thread count +# +# @decompress-threads: decompression thread count +# +# @cpu-throttle-initial: Initial percentage of time guest cpus are +# throttled when migration auto-converge is activated. +# The default value is 20. (Since 2.7) +# +# @cpu-throttle-increment: throttle percentage increase each time +# auto-converge detects that migration is not making +# progress. The default value is 10. (Since 2.7) +# +# @tls-creds: ID of the 'tls-creds' object that provides credentials +# for establishing a TLS connection over the migration data +# channel. On the outgoing side of the migration, the credentials +# must be for a 'client' endpoint, while for the incoming side the +# credentials must be for a 'server' endpoint. Setting this +# to a non-empty string enables TLS for all migrations. +# An empty string means that QEMU will use plain text mode for +# migration, rather than TLS (Since 2.9) +# Previously (since 2.7), this was reported by omitting +# tls-creds instead. +# +# @tls-hostname: hostname of the target host for the migration. This +# is required when using x509 based TLS credentials and the +# migration URI does not already include a hostname. For +# example if using fd: or exec: based migration, the +# hostname must be provided so that the server's x509 +# certificate identity can be validated. (Since 2.7) +# An empty string means that QEMU will use the hostname +# associated with the migration URI, if any. (Since 2.9) +# Previously (since 2.7), this was reported by omitting +# tls-hostname instead. +# +# @max-bandwidth: to set maximum speed for migration. maximum speed in +# bytes per second. (Since 2.8) +# +# @downtime-limit: set maximum tolerated downtime for migration. maximum +# downtime in milliseconds (Since 2.8) +# +# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8) +# +# @block-incremental: Affects how much storage is migrated when the +# block migration capability is enabled. When false, the entire +# storage backing chain is migrated into a flattened image at +# the destination; when true, only the active qcow2 layer is +# migrated and the destination must already have access to the +# same backing chain as was used on the source. (since 2.10) +# +# Since: 2.4 +## +# TODO either fuse back into MigrationParameters, or make +# MigrationParameters members mandatory +{ 'struct': 'MigrateSetParameters', + 'data': { '*compress-level': 'int', + '*compress-threads': 'int', + '*decompress-threads': 'int', + '*cpu-throttle-initial': 'int', + '*cpu-throttle-increment': 'int', + '*tls-creds': 'StrOrNull', + '*tls-hostname': 'StrOrNull', + '*max-bandwidth': 'int', + '*downtime-limit': 'int', + '*x-checkpoint-delay': 'int', + '*block-incremental': 'bool' } } + +## +# @migrate-set-parameters: +# +# Set various migration parameters. +# +# Since: 2.4 +# +# Example: +# +# -> { "execute": "migrate-set-parameters" , +# "arguments": { "compress-level": 1 } } +# +## +{ 'command': 'migrate-set-parameters', 'boxed': true, + 'data': 'MigrateSetParameters' } + +## +# @MigrationParameters: +# +# The optional members aren't actually optional. +# +# @compress-level: compression level +# +# @compress-threads: compression thread count +# +# @decompress-threads: decompression thread count +# +# @cpu-throttle-initial: Initial percentage of time guest cpus are +# throttled when migration auto-converge is activated. +# (Since 2.7) +# +# @cpu-throttle-increment: throttle percentage increase each time +# auto-converge detects that migration is not making +# progress. (Since 2.7) +# +# @tls-creds: ID of the 'tls-creds' object that provides credentials +# for establishing a TLS connection over the migration data +# channel. On the outgoing side of the migration, the credentials +# must be for a 'client' endpoint, while for the incoming side the +# credentials must be for a 'server' endpoint. +# An empty string means that QEMU will use plain text mode for +# migration, rather than TLS (Since 2.7) +# Note: 2.8 reports this by omitting tls-creds instead. +# +# @tls-hostname: hostname of the target host for the migration. This +# is required when using x509 based TLS credentials and the +# migration URI does not already include a hostname. For +# example if using fd: or exec: based migration, the +# hostname must be provided so that the server's x509 +# certificate identity can be validated. (Since 2.7) +# An empty string means that QEMU will use the hostname +# associated with the migration URI, if any. (Since 2.9) +# Note: 2.8 reports this by omitting tls-hostname instead. +# +# @max-bandwidth: to set maximum speed for migration. maximum speed in +# bytes per second. (Since 2.8) +# +# @downtime-limit: set maximum tolerated downtime for migration. maximum +# downtime in milliseconds (Since 2.8) +# +# @x-checkpoint-delay: the delay time between two COLO checkpoints. (Since 2.8) +# +# @block-incremental: Affects how much storage is migrated when the +# block migration capability is enabled. When false, the entire +# storage backing chain is migrated into a flattened image at +# the destination; when true, only the active qcow2 layer is +# migrated and the destination must already have access to the +# same backing chain as was used on the source. (since 2.10) +# +# Since: 2.4 +## +{ 'struct': 'MigrationParameters', + 'data': { '*compress-level': 'int', + '*compress-threads': 'int', + '*decompress-threads': 'int', + '*cpu-throttle-initial': 'int', + '*cpu-throttle-increment': 'int', + '*tls-creds': 'str', + '*tls-hostname': 'str', + '*max-bandwidth': 'int', + '*downtime-limit': 'int', + '*x-checkpoint-delay': 'int', + '*block-incremental': 'bool' } } + +## +# @query-migrate-parameters: +# +# Returns information about the current migration parameters +# +# Returns: @MigrationParameters +# +# Since: 2.4 +# +# Example: +# +# -> { "execute": "query-migrate-parameters" } +# <- { "return": { +# "decompress-threads": 2, +# "cpu-throttle-increment": 10, +# "compress-threads": 8, +# "compress-level": 1, +# "cpu-throttle-initial": 20, +# "max-bandwidth": 33554432, +# "downtime-limit": 300 +# } +# } +# +## +{ 'command': 'query-migrate-parameters', + 'returns': 'MigrationParameters' } + +## +# @client_migrate_info: +# +# Set migration information for remote display. This makes the server +# ask the client to automatically reconnect using the new parameters +# once migration finished successfully. Only implemented for SPICE. +# +# @protocol: must be "spice" +# @hostname: migration target hostname +# @port: spice tcp port for plaintext channels +# @tls-port: spice tcp port for tls-secured channels +# @cert-subject: server certificate subject +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "client_migrate_info", +# "arguments": { "protocol": "spice", +# "hostname": "virt42.lab.kraxel.org", +# "port": 1234 } } +# <- { "return": {} } +# +## +{ 'command': 'client_migrate_info', + 'data': { 'protocol': 'str', 'hostname': 'str', '*port': 'int', + '*tls-port': 'int', '*cert-subject': 'str' } } + +## +# @migrate-start-postcopy: +# +# Followup to a migration command to switch the migration to postcopy mode. +# The postcopy-ram capability must be set before the original migration +# command. +# +# Since: 2.5 +# +# Example: +# +# -> { "execute": "migrate-start-postcopy" } +# <- { "return": {} } +# +## +{ 'command': 'migrate-start-postcopy' } + +## +# @MIGRATION: +# +# Emitted when a migration event happens +# +# @status: @MigrationStatus describing the current migration status. +# +# Since: 2.4 +# +# Example: +# +# <- {"timestamp": {"seconds": 1432121972, "microseconds": 744001}, +# "event": "MIGRATION", +# "data": {"status": "completed"} } +# +## +{ 'event': 'MIGRATION', + 'data': {'status': 'MigrationStatus'}} + +## +# @MIGRATION_PASS: +# +# Emitted from the source side of a migration at the start of each pass +# (when it syncs the dirty bitmap) +# +# @pass: An incrementing count (starting at 1 on the first pass) +# +# Since: 2.6 +# +# Example: +# +# { "timestamp": {"seconds": 1449669631, "microseconds": 239225}, +# "event": "MIGRATION_PASS", "data": {"pass": 2} } +# +## +{ 'event': 'MIGRATION_PASS', + 'data': { 'pass': 'int' } } + +## +# @COLOMessage: +# +# The message transmission between Primary side and Secondary side. +# +# @checkpoint-ready: Secondary VM (SVM) is ready for checkpointing +# +# @checkpoint-request: Primary VM (PVM) tells SVM to prepare for checkpointing +# +# @checkpoint-reply: SVM gets PVM's checkpoint request +# +# @vmstate-send: VM's state will be sent by PVM. +# +# @vmstate-size: The total size of VMstate. +# +# @vmstate-received: VM's state has been received by SVM. +# +# @vmstate-loaded: VM's state has been loaded by SVM. +# +# Since: 2.8 +## +{ 'enum': 'COLOMessage', + 'data': [ 'checkpoint-ready', 'checkpoint-request', 'checkpoint-reply', + 'vmstate-send', 'vmstate-size', 'vmstate-received', + 'vmstate-loaded' ] } + +## +# @COLOMode: +# +# The colo mode +# +# @unknown: unknown mode +# +# @primary: master side +# +# @secondary: slave side +# +# Since: 2.8 +## +{ 'enum': 'COLOMode', + 'data': [ 'unknown', 'primary', 'secondary'] } + +## +# @FailoverStatus: +# +# An enumeration of COLO failover status +# +# @none: no failover has ever happened +# +# @require: got failover requirement but not handled +# +# @active: in the process of doing failover +# +# @completed: finish the process of failover +# +# @relaunch: restart the failover process, from 'none' -> 'completed' (Since 2.9) +# +# Since: 2.8 +## +{ 'enum': 'FailoverStatus', + 'data': [ 'none', 'require', 'active', 'completed', 'relaunch' ] } + +## +# @x-colo-lost-heartbeat: +# +# Tell qemu that heartbeat is lost, request it to do takeover procedures. +# If this command is sent to the PVM, the Primary side will exit COLO mode. +# If sent to the Secondary, the Secondary side will run failover work, +# then takes over server operation to become the service VM. +# +# Since: 2.8 +# +# Example: +# +# -> { "execute": "x-colo-lost-heartbeat" } +# <- { "return": {} } +# +## +{ 'command': 'x-colo-lost-heartbeat' } + +## +# @migrate_cancel: +# +# Cancel the current executing migration process. +# +# Returns: nothing on success +# +# Notes: This command succeeds even if there is no migration process running. +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "migrate_cancel" } +# <- { "return": {} } +# +## +{ 'command': 'migrate_cancel' } + +## +# @migrate_set_downtime: +# +# Set maximum tolerated downtime for migration. +# +# @value: maximum downtime in seconds +# +# Returns: nothing on success +# +# Notes: This command is deprecated in favor of 'migrate-set-parameters' +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } } +# <- { "return": {} } +# +## +{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} } + +## +# @migrate_set_speed: +# +# Set maximum speed for migration. +# +# @value: maximum speed in bytes per second. +# +# Returns: nothing on success +# +# Notes: This command is deprecated in favor of 'migrate-set-parameters' +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } } +# <- { "return": {} } +# +## +{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} } + +## +# @migrate-set-cache-size: +# +# Set cache size to be used by XBZRLE migration +# +# @value: cache size in bytes +# +# The size will be rounded down to the nearest power of 2. +# The cache size can be modified before and during ongoing migration +# +# Returns: nothing on success +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "migrate-set-cache-size", +# "arguments": { "value": 536870912 } } +# <- { "return": {} } +# +## +{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} } + +## +# @query-migrate-cache-size: +# +# Query migration XBZRLE cache size +# +# Returns: XBZRLE cache size in bytes +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "query-migrate-cache-size" } +# <- { "return": 67108864 } +# +## +{ 'command': 'query-migrate-cache-size', 'returns': 'int' } + +## +# @migrate: +# +# Migrates the current running guest to another Virtual Machine. +# +# @uri: the Uniform Resource Identifier of the destination VM +# +# @blk: do block migration (full disk copy) +# +# @inc: incremental disk copy migration +# +# @detach: this argument exists only for compatibility reasons and +# is ignored by QEMU +# +# Returns: nothing on success +# +# Since: 0.14.0 +# +# Notes: +# +# 1. The 'query-migrate' command should be used to check migration's progress +# and final result (this information is provided by the 'status' member) +# +# 2. All boolean arguments default to false +# +# 3. The user Monitor's "detach" argument is invalid in QMP and should not +# be used +# +# Example: +# +# -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } } +# <- { "return": {} } +# +## +{ 'command': 'migrate', + 'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } } + +## +# @migrate-incoming: +# +# Start an incoming migration, the qemu must have been started +# with -incoming defer +# +# @uri: The Uniform Resource Identifier identifying the source or +# address to listen on +# +# Returns: nothing on success +# +# Since: 2.3 +# +# Notes: +# +# 1. It's a bad idea to use a string for the uri, but it needs to stay +# compatible with -incoming and the format of the uri is already exposed +# above libvirt. +# +# 2. QEMU must be started with -incoming defer to allow migrate-incoming to +# be used. +# +# 3. The uri format is the same as for -incoming +# +# Example: +# +# -> { "execute": "migrate-incoming", +# "arguments": { "uri": "tcp::4446" } } +# <- { "return": {} } +# +## +{ 'command': 'migrate-incoming', 'data': {'uri': 'str' } } + +## +# @xen-save-devices-state: +# +# Save the state of all devices to file. The RAM and the block devices +# of the VM are not saved by this command. +# +# @filename: the file to save the state of the devices to as binary +# data. See xen-save-devices-state.txt for a description of the binary +# format. +# +# Returns: Nothing on success +# +# Since: 1.1 +# +# Example: +# +# -> { "execute": "xen-save-devices-state", +# "arguments": { "filename": "/tmp/save" } } +# <- { "return": {} } +# +## +{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} } + +## +# @xen-set-replication: +# +# Enable or disable replication. +# +# @enable: true to enable, false to disable. +# +# @primary: true for primary or false for secondary. +# +# @failover: true to do failover, false to stop. but cannot be +# specified if 'enable' is true. default value is false. +# +# Returns: nothing. +# +# Example: +# +# -> { "execute": "xen-set-replication", +# "arguments": {"enable": true, "primary": false} } +# <- { "return": {} } +# +# Since: 2.9 +## +{ 'command': 'xen-set-replication', + 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' } } + +## +# @ReplicationStatus: +# +# The result format for 'query-xen-replication-status'. +# +# @error: true if an error happened, false if replication is normal. +# +# @desc: the human readable error description string, when +# @error is 'true'. +# +# Since: 2.9 +## +{ 'struct': 'ReplicationStatus', + 'data': { 'error': 'bool', '*desc': 'str' } } + +## +# @query-xen-replication-status: +# +# Query replication status while the vm is running. +# +# Returns: A @ReplicationResult object showing the status. +# +# Example: +# +# -> { "execute": "query-xen-replication-status" } +# <- { "return": { "error": false } } +# +# Since: 2.9 +## +{ 'command': 'query-xen-replication-status', + 'returns': 'ReplicationStatus' } + +## +# @xen-colo-do-checkpoint: +# +# Xen uses this command to notify replication to trigger a checkpoint. +# +# Returns: nothing. +# +# Example: +# +# -> { "execute": "xen-colo-do-checkpoint" } +# <- { "return": {} } +# +# Since: 2.9 +## +{ 'command': 'xen-colo-do-checkpoint' } diff --git a/qapi/net.json b/qapi/net.json new file mode 100644 index 0000000000..4beff5d582 --- /dev/null +++ b/qapi/net.json @@ -0,0 +1,706 @@ +# -*- Mode: Python -*- +# + +## +# = Net devices +## + +{ 'include': 'common.json' } + +## +# @set_link: +# +# Sets the link status of a virtual network adapter. +# +# @name: the device name of the virtual network adapter +# +# @up: true to set the link status to be up +# +# Returns: Nothing on success +# If @name is not a valid network device, DeviceNotFound +# +# Since: 0.14.0 +# +# Notes: Not all network adapters support setting link status. This command +# will succeed even if the network adapter does not support link status +# notification. +# +# Example: +# +# -> { "execute": "set_link", +# "arguments": { "name": "e1000.0", "up": false } } +# <- { "return": {} } +# +## +{ 'command': 'set_link', 'data': {'name': 'str', 'up': 'bool'} } + +## +# @netdev_add: +# +# Add a network backend. +# +# @type: the type of network backend. Current valid values are 'user', 'tap', +# 'vde', 'socket', 'dump' and 'bridge' +# +# @id: the name of the new network backend +# +# Additional arguments depend on the type. +# +# TODO: This command effectively bypasses QAPI completely due to its +# "additional arguments" business. It shouldn't have been added to +# the schema in this form. It should be qapified properly, or +# replaced by a properly qapified command. +# +# Since: 0.14.0 +# +# Returns: Nothing on success +# If @type is not a valid network backend, DeviceNotFound +# +# Example: +# +# -> { "execute": "netdev_add", +# "arguments": { "type": "user", "id": "netdev1", +# "dnssearch": "example.org" } } +# <- { "return": {} } +# +## +{ 'command': 'netdev_add', + 'data': {'type': 'str', 'id': 'str'}, + 'gen': false } # so we can get the additional arguments + +## +# @netdev_del: +# +# Remove a network backend. +# +# @id: the name of the network backend to remove +# +# Returns: Nothing on success +# If @id is not a valid network backend, DeviceNotFound +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "netdev_del", "arguments": { "id": "netdev1" } } +# <- { "return": {} } +# +## +{ 'command': 'netdev_del', 'data': {'id': 'str'} } + +## +# @NetdevNoneOptions: +# +# Use it alone to have zero network devices. +# +# Since: 1.2 +## +{ 'struct': 'NetdevNoneOptions', + 'data': { } } + +## +# @NetLegacyNicOptions: +# +# Create a new Network Interface Card. +# +# @netdev: id of -netdev to connect to +# +# @macaddr: MAC address +# +# @model: device model (e1000, rtl8139, virtio etc.) +# +# @addr: PCI device address +# +# @vectors: number of MSI-x vectors, 0 to disable MSI-X +# +# Since: 1.2 +## +{ 'struct': 'NetLegacyNicOptions', + 'data': { + '*netdev': 'str', + '*macaddr': 'str', + '*model': 'str', + '*addr': 'str', + '*vectors': 'uint32' } } + +## +# @NetdevUserOptions: +# +# Use the user mode network stack which requires no administrator privilege to +# run. +# +# @hostname: client hostname reported by the builtin DHCP server +# +# @restrict: isolate the guest from the host +# +# @ipv4: whether to support IPv4, default true for enabled +# (since 2.6) +# +# @ipv6: whether to support IPv6, default true for enabled +# (since 2.6) +# +# @ip: legacy parameter, use net= instead +# +# @net: IP network address that the guest will see, in the +# form addr[/netmask] The netmask is optional, and can be +# either in the form a.b.c.d or as a number of valid top-most +# bits. Default is 10.0.2.0/24. +# +# @host: guest-visible address of the host +# +# @tftp: root directory of the built-in TFTP server +# +# @bootfile: BOOTP filename, for use with tftp= +# +# @dhcpstart: the first of the 16 IPs the built-in DHCP server can +# assign +# +# @dns: guest-visible address of the virtual nameserver +# +# @dnssearch: list of DNS suffixes to search, passed as DHCP option +# to the guest +# +# @ipv6-prefix: IPv6 network prefix (default is fec0::) (since +# 2.6). The network prefix is given in the usual +# hexadecimal IPv6 address notation. +# +# @ipv6-prefixlen: IPv6 network prefix length (default is 64) +# (since 2.6) +# +# @ipv6-host: guest-visible IPv6 address of the host (since 2.6) +# +# @ipv6-dns: guest-visible IPv6 address of the virtual +# nameserver (since 2.6) +# +# @smb: root directory of the built-in SMB server +# +# @smbserver: IP address of the built-in SMB server +# +# @hostfwd: redirect incoming TCP or UDP host connections to guest +# endpoints +# +# @guestfwd: forward guest TCP connections +# +# Since: 1.2 +## +{ 'struct': 'NetdevUserOptions', + 'data': { + '*hostname': 'str', + '*restrict': 'bool', + '*ipv4': 'bool', + '*ipv6': 'bool', + '*ip': 'str', + '*net': 'str', + '*host': 'str', + '*tftp': 'str', + '*bootfile': 'str', + '*dhcpstart': 'str', + '*dns': 'str', + '*dnssearch': ['String'], + '*ipv6-prefix': 'str', + '*ipv6-prefixlen': 'int', + '*ipv6-host': 'str', + '*ipv6-dns': 'str', + '*smb': 'str', + '*smbserver': 'str', + '*hostfwd': ['String'], + '*guestfwd': ['String'] } } + +## +# @NetdevTapOptions: +# +# Connect the host TAP network interface name to the VLAN. +# +# @ifname: interface name +# +# @fd: file descriptor of an already opened tap +# +# @fds: multiple file descriptors of already opened multiqueue capable +# tap +# +# @script: script to initialize the interface +# +# @downscript: script to shut down the interface +# +# @br: bridge name (since 2.8) +# +# @helper: command to execute to configure bridge +# +# @sndbuf: send buffer limit. Understands [TGMKkb] suffixes. +# +# @vnet_hdr: enable the IFF_VNET_HDR flag on the tap interface +# +# @vhost: enable vhost-net network accelerator +# +# @vhostfd: file descriptor of an already opened vhost net device +# +# @vhostfds: file descriptors of multiple already opened vhost net +# devices +# +# @vhostforce: vhost on for non-MSIX virtio guests +# +# @queues: number of queues to be created for multiqueue capable tap +# +# @poll-us: maximum number of microseconds that could +# be spent on busy polling for tap (since 2.7) +# +# Since: 1.2 +## +{ 'struct': 'NetdevTapOptions', + 'data': { + '*ifname': 'str', + '*fd': 'str', + '*fds': 'str', + '*script': 'str', + '*downscript': 'str', + '*br': 'str', + '*helper': 'str', + '*sndbuf': 'size', + '*vnet_hdr': 'bool', + '*vhost': 'bool', + '*vhostfd': 'str', + '*vhostfds': 'str', + '*vhostforce': 'bool', + '*queues': 'uint32', + '*poll-us': 'uint32'} } + +## +# @NetdevSocketOptions: +# +# Connect the VLAN to a remote VLAN in another QEMU virtual machine using a TCP +# socket connection. +# +# @fd: file descriptor of an already opened socket +# +# @listen: port number, and optional hostname, to listen on +# +# @connect: port number, and optional hostname, to connect to +# +# @mcast: UDP multicast address and port number +# +# @localaddr: source address and port for multicast and udp packets +# +# @udp: UDP unicast address and port number +# +# Since: 1.2 +## +{ 'struct': 'NetdevSocketOptions', + 'data': { + '*fd': 'str', + '*listen': 'str', + '*connect': 'str', + '*mcast': 'str', + '*localaddr': 'str', + '*udp': 'str' } } + +## +# @NetdevL2TPv3Options: +# +# Connect the VLAN to Ethernet over L2TPv3 Static tunnel +# +# @src: source address +# +# @dst: destination address +# +# @srcport: source port - mandatory for udp, optional for ip +# +# @dstport: destination port - mandatory for udp, optional for ip +# +# @ipv6: force the use of ipv6 +# +# @udp: use the udp version of l2tpv3 encapsulation +# +# @cookie64: use 64 bit coookies +# +# @counter: have sequence counter +# +# @pincounter: pin sequence counter to zero - +# workaround for buggy implementations or +# networks with packet reorder +# +# @txcookie: 32 or 64 bit transmit cookie +# +# @rxcookie: 32 or 64 bit receive cookie +# +# @txsession: 32 bit transmit session +# +# @rxsession: 32 bit receive session - if not specified +# set to the same value as transmit +# +# @offset: additional offset - allows the insertion of +# additional application-specific data before the packet payload +# +# Since: 2.1 +## +{ 'struct': 'NetdevL2TPv3Options', + 'data': { + 'src': 'str', + 'dst': 'str', + '*srcport': 'str', + '*dstport': 'str', + '*ipv6': 'bool', + '*udp': 'bool', + '*cookie64': 'bool', + '*counter': 'bool', + '*pincounter': 'bool', + '*txcookie': 'uint64', + '*rxcookie': 'uint64', + 'txsession': 'uint32', + '*rxsession': 'uint32', + '*offset': 'uint32' } } + +## +# @NetdevVdeOptions: +# +# Connect the VLAN to a vde switch running on the host. +# +# @sock: socket path +# +# @port: port number +# +# @group: group owner of socket +# +# @mode: permissions for socket +# +# Since: 1.2 +## +{ 'struct': 'NetdevVdeOptions', + 'data': { + '*sock': 'str', + '*port': 'uint16', + '*group': 'str', + '*mode': 'uint16' } } + +## +# @NetdevDumpOptions: +# +# Dump VLAN network traffic to a file. +# +# @len: per-packet size limit (64k default). Understands [TGMKkb] +# suffixes. +# +# @file: dump file path (default is qemu-vlan0.pcap) +# +# Since: 1.2 +## +{ 'struct': 'NetdevDumpOptions', + 'data': { + '*len': 'size', + '*file': 'str' } } + +## +# @NetdevBridgeOptions: +# +# Connect a host TAP network interface to a host bridge device. +# +# @br: bridge name +# +# @helper: command to execute to configure bridge +# +# Since: 1.2 +## +{ 'struct': 'NetdevBridgeOptions', + 'data': { + '*br': 'str', + '*helper': 'str' } } + +## +# @NetdevHubPortOptions: +# +# Connect two or more net clients through a software hub. +# +# @hubid: hub identifier number +# +# Since: 1.2 +## +{ 'struct': 'NetdevHubPortOptions', + 'data': { + 'hubid': 'int32' } } + +## +# @NetdevNetmapOptions: +# +# Connect a client to a netmap-enabled NIC or to a VALE switch port +# +# @ifname: Either the name of an existing network interface supported by +# netmap, or the name of a VALE port (created on the fly). +# A VALE port name is in the form 'valeXXX:YYY', where XXX and +# YYY are non-negative integers. XXX identifies a switch and +# YYY identifies a port of the switch. VALE ports having the +# same XXX are therefore connected to the same switch. +# +# @devname: path of the netmap device (default: '/dev/netmap'). +# +# Since: 2.0 +## +{ 'struct': 'NetdevNetmapOptions', + 'data': { + 'ifname': 'str', + '*devname': 'str' } } + +## +# @NetdevVhostUserOptions: +# +# Vhost-user network backend +# +# @chardev: name of a unix socket chardev +# +# @vhostforce: vhost on for non-MSIX virtio guests (default: false). +# +# @queues: number of queues to be created for multiqueue vhost-user +# (default: 1) (Since 2.5) +# +# Since: 2.1 +## +{ 'struct': 'NetdevVhostUserOptions', + 'data': { + 'chardev': 'str', + '*vhostforce': 'bool', + '*queues': 'int' } } + +## +# @NetClientDriver: +# +# Available netdev drivers. +# +# Since: 2.7 +## +{ 'enum': 'NetClientDriver', + 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', 'dump', + 'bridge', 'hubport', 'netmap', 'vhost-user' ] } + +## +# @Netdev: +# +# Captures the configuration of a network device. +# +# @id: identifier for monitor commands. +# +# @type: Specify the driver used for interpreting remaining arguments. +# +# Since: 1.2 +# +# 'l2tpv3' - since 2.1 +## +{ 'union': 'Netdev', + 'base': { 'id': 'str', 'type': 'NetClientDriver' }, + 'discriminator': 'type', + 'data': { + 'none': 'NetdevNoneOptions', + 'nic': 'NetLegacyNicOptions', + 'user': 'NetdevUserOptions', + 'tap': 'NetdevTapOptions', + 'l2tpv3': 'NetdevL2TPv3Options', + 'socket': 'NetdevSocketOptions', + 'vde': 'NetdevVdeOptions', + 'dump': 'NetdevDumpOptions', + 'bridge': 'NetdevBridgeOptions', + 'hubport': 'NetdevHubPortOptions', + 'netmap': 'NetdevNetmapOptions', + 'vhost-user': 'NetdevVhostUserOptions' } } + +## +# @NetLegacy: +# +# Captures the configuration of a network device; legacy. +# +# @vlan: vlan number +# +# @id: identifier for monitor commands +# +# @name: identifier for monitor commands, ignored if @id is present +# +# @opts: device type specific properties (legacy) +# +# Since: 1.2 +## +{ 'struct': 'NetLegacy', + 'data': { + '*vlan': 'int32', + '*id': 'str', + '*name': 'str', + 'opts': 'NetLegacyOptions' } } + +## +# @NetLegacyOptionsType: +# +# Since: 1.2 +## +{ 'enum': 'NetLegacyOptionsType', + 'data': ['none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', + 'dump', 'bridge', 'netmap', 'vhost-user'] } + +## +# @NetLegacyOptions: +# +# Like Netdev, but for use only by the legacy command line options +# +# Since: 1.2 +## +{ 'union': 'NetLegacyOptions', + 'base': { 'type': 'NetLegacyOptionsType' }, + 'discriminator': 'type', + 'data': { + 'none': 'NetdevNoneOptions', + 'nic': 'NetLegacyNicOptions', + 'user': 'NetdevUserOptions', + 'tap': 'NetdevTapOptions', + 'l2tpv3': 'NetdevL2TPv3Options', + 'socket': 'NetdevSocketOptions', + 'vde': 'NetdevVdeOptions', + 'dump': 'NetdevDumpOptions', + 'bridge': 'NetdevBridgeOptions', + 'netmap': 'NetdevNetmapOptions', + 'vhost-user': 'NetdevVhostUserOptions' } } + +## +# @NetFilterDirection: +# +# Indicates whether a netfilter is attached to a netdev's transmit queue or +# receive queue or both. +# +# @all: the filter is attached both to the receive and the transmit +# queue of the netdev (default). +# +# @rx: the filter is attached to the receive queue of the netdev, +# where it will receive packets sent to the netdev. +# +# @tx: the filter is attached to the transmit queue of the netdev, +# where it will receive packets sent by the netdev. +# +# Since: 2.5 +## +{ 'enum': 'NetFilterDirection', + 'data': [ 'all', 'rx', 'tx' ] } + +## +# @RxState: +# +# Packets receiving state +# +# @normal: filter assigned packets according to the mac-table +# +# @none: don't receive any assigned packet +# +# @all: receive all assigned packets +# +# Since: 1.6 +## +{ 'enum': 'RxState', 'data': [ 'normal', 'none', 'all' ] } + +## +# @RxFilterInfo: +# +# Rx-filter information for a NIC. +# +# @name: net client name +# +# @promiscuous: whether promiscuous mode is enabled +# +# @multicast: multicast receive state +# +# @unicast: unicast receive state +# +# @vlan: vlan receive state (Since 2.0) +# +# @broadcast-allowed: whether to receive broadcast +# +# @multicast-overflow: multicast table is overflowed or not +# +# @unicast-overflow: unicast table is overflowed or not +# +# @main-mac: the main macaddr string +# +# @vlan-table: a list of active vlan id +# +# @unicast-table: a list of unicast macaddr string +# +# @multicast-table: a list of multicast macaddr string +# +# Since: 1.6 +## +{ 'struct': 'RxFilterInfo', + 'data': { + 'name': 'str', + 'promiscuous': 'bool', + 'multicast': 'RxState', + 'unicast': 'RxState', + 'vlan': 'RxState', + 'broadcast-allowed': 'bool', + 'multicast-overflow': 'bool', + 'unicast-overflow': 'bool', + 'main-mac': 'str', + 'vlan-table': ['int'], + 'unicast-table': ['str'], + 'multicast-table': ['str'] }} + +## +# @query-rx-filter: +# +# Return rx-filter information for all NICs (or for the given NIC). +# +# @name: net client name +# +# Returns: list of @RxFilterInfo for all NICs (or for the given NIC). +# Returns an error if the given @name doesn't exist, or given +# NIC doesn't support rx-filter querying, or given net client +# isn't a NIC. +# +# Since: 1.6 +# +# Example: +# +# -> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } } +# <- { "return": [ +# { +# "promiscuous": true, +# "name": "vnet0", +# "main-mac": "52:54:00:12:34:56", +# "unicast": "normal", +# "vlan": "normal", +# "vlan-table": [ +# 4, +# 0 +# ], +# "unicast-table": [ +# ], +# "multicast": "normal", +# "multicast-overflow": false, +# "unicast-overflow": false, +# "multicast-table": [ +# "01:00:5e:00:00:01", +# "33:33:00:00:00:01", +# "33:33:ff:12:34:56" +# ], +# "broadcast-allowed": false +# } +# ] +# } +# +## +{ 'command': 'query-rx-filter', 'data': { '*name': 'str' }, + 'returns': ['RxFilterInfo'] } + +## +# @NIC_RX_FILTER_CHANGED: +# +# Emitted once until the 'query-rx-filter' command is executed, the first event +# will always be emitted +# +# @name: net client name +# +# @path: device path +# +# Since: 1.6 +# +# Example: +# +# <- { "event": "NIC_RX_FILTER_CHANGED", +# "data": { "name": "vnet0", +# "path": "/machine/peripheral/vnet0/virtio-backend" }, +# "timestamp": { "seconds": 1368697518, "microseconds": 326866 } } +# } +# +## +{ 'event': 'NIC_RX_FILTER_CHANGED', + 'data': { '*name': 'str', 'path': 'str' } } diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c index 46eda7d196..e9b266bb70 100644 --- a/qapi/qapi-util.c +++ b/qapi/qapi-util.c @@ -13,10 +13,16 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" -#include "qapi/util.h" -int qapi_enum_parse(const char * const lookup[], const char *buf, - int max, int def, Error **errp) +const char *qapi_enum_lookup(const QEnumLookup *lookup, int val) +{ + assert(val >= 0 && val < lookup->size); + + return lookup->array[val]; +} + +int qapi_enum_parse(const QEnumLookup *lookup, const char *buf, + int def, Error **errp) { int i; @@ -24,8 +30,8 @@ int qapi_enum_parse(const char * const lookup[], const char *buf, return def; } - for (i = 0; i < max; i++) { - if (!strcmp(buf, lookup[i])) { + for (i = 0; i < lookup->size; i++) { + if (!strcmp(buf, lookup->array[i])) { return i; } } diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index ed6d2af462..3dcb968867 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -333,27 +333,29 @@ void visit_type_null(Visitor *v, const char *name, QNull **obj, } static void output_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { - int i = 0; int value = *obj; char *enum_str; - while (strings[i++] != NULL); - if (value < 0 || value >= i - 1) { + /* + * TODO why is this an error, not an assertion? If assertion: + * delete, and rely on qapi_enum_lookup() + */ + if (value < 0 || value >= lookup->size) { error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null"); return; } - enum_str = (char *)strings[value]; + enum_str = (char *)qapi_enum_lookup(lookup, value); visit_type_str(v, name, &enum_str, errp); } static void input_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { Error *local_err = NULL; - int64_t value = 0; + int64_t value; char *enum_str; visit_type_str(v, name, &enum_str, &local_err); @@ -362,14 +364,8 @@ static void input_type_enum(Visitor *v, const char *name, int *obj, return; } - while (strings[value] != NULL) { - if (strcmp(strings[value], enum_str) == 0) { - break; - } - value++; - } - - if (strings[value] == NULL) { + value = qapi_enum_parse(lookup, enum_str, -1, NULL); + if (value < 0) { error_setg(errp, QERR_INVALID_PARAMETER, enum_str); g_free(enum_str); return; @@ -380,16 +376,16 @@ static void input_type_enum(Visitor *v, const char *name, int *obj, } void visit_type_enum(Visitor *v, const char *name, int *obj, - const char *const strings[], Error **errp) + const QEnumLookup *lookup, Error **errp) { - assert(obj && strings); + assert(obj && lookup); trace_visit_type_enum(v, name, obj); switch (v->type) { case VISITOR_INPUT: - input_type_enum(v, name, obj, strings, errp); + input_type_enum(v, name, obj, lookup, errp); break; case VISITOR_OUTPUT: - output_type_enum(v, name, obj, strings, errp); + output_type_enum(v, name, obj, lookup, errp); break; case VISITOR_CLONE: /* nothing further to do, scalar value was already copied by diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 5ad36f8a09..b41fa174fe 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -118,7 +118,7 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request, QObject *qmp_build_error_object(Error *err) { return qobject_from_jsonf("{ 'class': %s, 'desc': %s }", - QapiErrorClass_lookup[error_get_class(err)], + QapiErrorClass_str(error_get_class(err)), error_get_pretty(err)); } diff --git a/qapi/run-state.json b/qapi/run-state.json new file mode 100644 index 0000000000..d36ff49834 --- /dev/null +++ b/qapi/run-state.json @@ -0,0 +1,352 @@ +# -*- Mode: Python -*- +# + +## +# = VM run state +## + +## +# @RunState: +# +# An enumeration of VM run states. +# +# @debug: QEMU is running on a debugger +# +# @finish-migrate: guest is paused to finish the migration process +# +# @inmigrate: guest is paused waiting for an incoming migration. Note +# that this state does not tell whether the machine will start at the +# end of the migration. This depends on the command-line -S option and +# any invocation of 'stop' or 'cont' that has happened since QEMU was +# started. +# +# @internal-error: An internal error that prevents further guest execution +# has occurred +# +# @io-error: the last IOP has failed and the device is configured to pause +# on I/O errors +# +# @paused: guest has been paused via the 'stop' command +# +# @postmigrate: guest is paused following a successful 'migrate' +# +# @prelaunch: QEMU was started with -S and guest has not started +# +# @restore-vm: guest is paused to restore VM state +# +# @running: guest is actively running +# +# @save-vm: guest is paused to save the VM state +# +# @shutdown: guest is shut down (and -no-shutdown is in use) +# +# @suspended: guest is suspended (ACPI S3) +# +# @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: guest has been panicked as a result of guest OS panic +# +# @colo: guest is paused to save/restore VM state under colo checkpoint, +# VM can not get into this state unless colo capability is enabled +# for migration. (since 2.8) +## +{ 'enum': 'RunState', + 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', + 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', + 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', + 'guest-panicked', 'colo' ] } + +## +# @StatusInfo: +# +# Information about VCPU run state +# +# @running: true if all VCPUs are runnable, false if not runnable +# +# @singlestep: true if VCPUs are in single-step mode +# +# @status: the virtual machine @RunState +# +# Since: 0.14.0 +# +# Notes: @singlestep is enabled through the GDB stub +## +{ 'struct': 'StatusInfo', + 'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} } + +## +# @query-status: +# +# Query the run status of all VCPUs +# +# Returns: @StatusInfo reflecting all VCPUs +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-status" } +# <- { "return": { "running": true, +# "singlestep": false, +# "status": "running" } } +# +## +{ 'command': 'query-status', 'returns': 'StatusInfo' } + +## +# @SHUTDOWN: +# +# Emitted when the virtual machine has shut down, indicating that qemu is +# about to exit. +# +# @guest: If true, the shutdown was triggered by a guest request (such as +# a guest-initiated ACPI shutdown request or other hardware-specific action) +# rather than a host request (such as sending qemu a SIGINT). (since 2.10) +# +# Note: If the command-line option "-no-shutdown" has been specified, qemu will +# not exit, and a STOP event will eventually follow the SHUTDOWN event +# +# Since: 0.12.0 +# +# Example: +# +# <- { "event": "SHUTDOWN", "data": { "guest": true }, +# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } +# +## +{ 'event': 'SHUTDOWN', 'data': { 'guest': 'bool' } } + +## +# @POWERDOWN: +# +# Emitted when the virtual machine is powered down through the power control +# system, such as via ACPI. +# +# Since: 0.12.0 +# +# Example: +# +# <- { "event": "POWERDOWN", +# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } +# +## +{ 'event': 'POWERDOWN' } + +## +# @RESET: +# +# Emitted when the virtual machine is reset +# +# @guest: If true, the reset was triggered by a guest request (such as +# a guest-initiated ACPI reboot request or other hardware-specific action) +# rather than a host request (such as the QMP command system_reset). +# (since 2.10) +# +# Since: 0.12.0 +# +# Example: +# +# <- { "event": "RESET", "data": { "guest": false }, +# "timestamp": { "seconds": 1267041653, "microseconds": 9518 } } +# +## +{ 'event': 'RESET', 'data': { 'guest': 'bool' } } + +## +# @STOP: +# +# Emitted when the virtual machine is stopped +# +# Since: 0.12.0 +# +# Example: +# +# <- { "event": "STOP", +# "timestamp": { "seconds": 1267041730, "microseconds": 281295 } } +# +## +{ 'event': 'STOP' } + +## +# @RESUME: +# +# Emitted when the virtual machine resumes execution +# +# Since: 0.12.0 +# +# Example: +# +# <- { "event": "RESUME", +# "timestamp": { "seconds": 1271770767, "microseconds": 582542 } } +# +## +{ 'event': 'RESUME' } + +## +# @SUSPEND: +# +# Emitted when guest enters a hardware suspension state, for example, S3 state, +# which is sometimes called standby state +# +# Since: 1.1 +# +# Example: +# +# <- { "event": "SUSPEND", +# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } +# +## +{ 'event': 'SUSPEND' } + +## +# @SUSPEND_DISK: +# +# Emitted when guest enters a hardware suspension state with data saved on +# disk, for example, S4 state, which is sometimes called hibernate state +# +# Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state +# +# Since: 1.2 +# +# Example: +# +# <- { "event": "SUSPEND_DISK", +# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } } +# +## +{ 'event': 'SUSPEND_DISK' } + +## +# @WAKEUP: +# +# Emitted when the guest has woken up from suspend state and is running +# +# Since: 1.1 +# +# Example: +# +# <- { "event": "WAKEUP", +# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } +# +## +{ 'event': 'WAKEUP' } + +## +# @WATCHDOG: +# +# Emitted when the watchdog device's timer is expired +# +# @action: action that has been taken +# +# Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is +# followed respectively by the RESET, SHUTDOWN, or STOP events +# +# Note: This event is rate-limited. +# +# Since: 0.13.0 +# +# Example: +# +# <- { "event": "WATCHDOG", +# "data": { "action": "reset" }, +# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } } +# +## +{ 'event': 'WATCHDOG', + 'data': { 'action': 'WatchdogExpirationAction' } } + +## +# @WatchdogExpirationAction: +# +# An enumeration of the actions taken when the watchdog device's timer is +# expired +# +# @reset: system resets +# +# @shutdown: system shutdown, note that it is similar to @powerdown, which +# tries to set to system status and notify guest +# +# @poweroff: system poweroff, the emulator program exits +# +# @pause: system pauses, similar to @stop +# +# @debug: system enters debug state +# +# @none: nothing is done +# +# @inject-nmi: a non-maskable interrupt is injected into the first VCPU (all +# VCPUS on x86) (since 2.4) +# +# Since: 2.1 +## +{ 'enum': 'WatchdogExpirationAction', + 'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none', + 'inject-nmi' ] } + +## +# @GUEST_PANICKED: +# +# Emitted when guest OS panic is detected +# +# @action: action that has been taken, currently always "pause" +# +# @info: information about a panic (since 2.9) +# +# Since: 1.5 +# +# Example: +# +# <- { "event": "GUEST_PANICKED", +# "data": { "action": "pause" } } +# +## +{ 'event': 'GUEST_PANICKED', + 'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } } + +## +# @GuestPanicAction: +# +# An enumeration of the actions taken when guest OS panic is detected +# +# @pause: system pauses +# +# Since: 2.1 (poweroff since 2.8) +## +{ 'enum': 'GuestPanicAction', + 'data': [ 'pause', 'poweroff' ] } + +## +# @GuestPanicInformationType: +# +# An enumeration of the guest panic information types +# +# Since: 2.9 +## +{ 'enum': 'GuestPanicInformationType', + 'data': [ 'hyper-v'] } + +## +# @GuestPanicInformation: +# +# Information about a guest panic +# +# Since: 2.9 +## +{'union': 'GuestPanicInformation', + 'base': {'type': 'GuestPanicInformationType'}, + 'discriminator': 'type', + 'data': { 'hyper-v': 'GuestPanicInformationHyperV' } } + +## +# @GuestPanicInformationHyperV: +# +# Hyper-V specific guest panic information (HV crash MSRs) +# +# Since: 2.9 +## +{'struct': 'GuestPanicInformationHyperV', + 'data': { 'arg1': 'uint64', + 'arg2': 'uint64', + 'arg3': 'uint64', + 'arg4': 'uint64', + 'arg5': 'uint64' } } diff --git a/qapi/sockets.json b/qapi/sockets.json new file mode 100644 index 0000000000..ac022c6ad0 --- /dev/null +++ b/qapi/sockets.json @@ -0,0 +1,147 @@ +# -*- Mode: Python -*- + +## +# = Socket data types +## + +{ 'include': 'common.json' } + +## +# @NetworkAddressFamily: +# +# The network address family +# +# @ipv4: IPV4 family +# +# @ipv6: IPV6 family +# +# @unix: unix socket +# +# @vsock: vsock family (since 2.8) +# +# @unknown: otherwise +# +# Since: 2.1 +## +{ 'enum': 'NetworkAddressFamily', + 'data': [ 'ipv4', 'ipv6', 'unix', 'vsock', 'unknown' ] } + +## +# @InetSocketAddressBase: +# +# @host: host part of the address +# @port: port part of the address +## +{ 'struct': 'InetSocketAddressBase', + 'data': { + 'host': 'str', + 'port': 'str' } } + +## +# @InetSocketAddress: +# +# Captures a socket address or address range in the Internet namespace. +# +# @numeric: true if the host/port are guaranteed to be numeric, +# false if name resolution should be attempted. Defaults to false. +# (Since 2.9) +# +# @to: If present, this is range of possible addresses, with port +# between @port and @to. +# +# @ipv4: whether to accept IPv4 addresses, default try both IPv4 and IPv6 +# +# @ipv6: whether to accept IPv6 addresses, default try both IPv4 and IPv6 +# +# Since: 1.3 +## +{ 'struct': 'InetSocketAddress', + 'base': 'InetSocketAddressBase', + 'data': { + '*numeric': 'bool', + '*to': 'uint16', + '*ipv4': 'bool', + '*ipv6': 'bool' } } + +## +# @UnixSocketAddress: +# +# Captures a socket address in the local ("Unix socket") namespace. +# +# @path: filesystem path to use +# +# Since: 1.3 +## +{ 'struct': 'UnixSocketAddress', + 'data': { + 'path': 'str' } } + +## +# @VsockSocketAddress: +# +# Captures a socket address in the vsock namespace. +# +# @cid: unique host identifier +# @port: port +# +# Note: string types are used to allow for possible future hostname or +# service resolution support. +# +# Since: 2.8 +## +{ 'struct': 'VsockSocketAddress', + 'data': { + 'cid': 'str', + 'port': 'str' } } + +## +# @SocketAddressLegacy: +# +# Captures the address of a socket, which could also be a named file descriptor +# +# Note: This type is deprecated in favor of SocketAddress. The +# difference between SocketAddressLegacy and SocketAddress is that the +# latter is a flat union rather than a simple union. Flat is nicer +# because it avoids nesting on the wire, i.e. that form has fewer {}. + +# +# Since: 1.3 +## +{ 'union': 'SocketAddressLegacy', + 'data': { + 'inet': 'InetSocketAddress', + 'unix': 'UnixSocketAddress', + 'vsock': 'VsockSocketAddress', + 'fd': 'String' } } + +## +# @SocketAddressType: +# +# Available SocketAddress types +# +# @inet: Internet address +# +# @unix: Unix domain socket +# +# Since: 2.9 +## +{ 'enum': 'SocketAddressType', + 'data': [ 'inet', 'unix', 'vsock', 'fd' ] } + +## +# @SocketAddress: +# +# Captures the address of a socket, which could also be a named file +# descriptor +# +# @type: Transport type +# +# Since: 2.9 +## +{ 'union': 'SocketAddress', + 'base': { 'type': 'SocketAddressType' }, + 'discriminator': 'type', + 'data': { 'inet': 'InetSocketAddress', + 'unix': 'UnixSocketAddress', + 'vsock': 'VsockSocketAddress', + 'fd': 'String' } } diff --git a/qapi/tpm.json b/qapi/tpm.json new file mode 100644 index 0000000000..e8b2d8dcb7 --- /dev/null +++ b/qapi/tpm.json @@ -0,0 +1,137 @@ +# -*- Mode: Python -*- +# + +## +# = TPM (trusted platform module) devices +## + +## +# @TpmModel: +# +# An enumeration of TPM models +# +# @tpm-tis: TPM TIS model +# +# Since: 1.5 +## +{ 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] } + +## +# @query-tpm-models: +# +# Return a list of supported TPM models +# +# Returns: a list of TpmModel +# +# Since: 1.5 +# +# Example: +# +# -> { "execute": "query-tpm-models" } +# <- { "return": [ "tpm-tis" ] } +# +## +{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] } + +## +# @TpmType: +# +# An enumeration of TPM types +# +# @passthrough: TPM passthrough type +# +# Since: 1.5 +## +{ 'enum': 'TpmType', 'data': [ 'passthrough' ] } + +## +# @query-tpm-types: +# +# Return a list of supported TPM types +# +# Returns: a list of TpmType +# +# Since: 1.5 +# +# Example: +# +# -> { "execute": "query-tpm-types" } +# <- { "return": [ "passthrough" ] } +# +## +{ 'command': 'query-tpm-types', 'returns': ['TpmType'] } + +## +# @TPMPassthroughOptions: +# +# Information about the TPM passthrough type +# +# @path: string describing the path used for accessing the TPM device +# +# @cancel-path: string showing the TPM's sysfs cancel file +# for cancellation of TPM commands while they are executing +# +# Since: 1.5 +## +{ 'struct': 'TPMPassthroughOptions', 'data': { '*path' : 'str', + '*cancel-path' : 'str'} } + +## +# @TpmTypeOptions: +# +# A union referencing different TPM backend types' configuration options +# +# @type: 'passthrough' The configuration options for the TPM passthrough type +# +# Since: 1.5 +## +{ 'union': 'TpmTypeOptions', + 'data': { 'passthrough' : 'TPMPassthroughOptions' } } + +## +# @TPMInfo: +# +# Information about the TPM +# +# @id: The Id of the TPM +# +# @model: The TPM frontend model +# +# @options: The TPM (backend) type configuration options +# +# Since: 1.5 +## +{ 'struct': 'TPMInfo', + 'data': {'id': 'str', + 'model': 'TpmModel', + 'options': 'TpmTypeOptions' } } + +## +# @query-tpm: +# +# Return information about the TPM device +# +# Returns: @TPMInfo on success +# +# Since: 1.5 +# +# Example: +# +# -> { "execute": "query-tpm" } +# <- { "return": +# [ +# { "model": "tpm-tis", +# "options": +# { "type": "passthrough", +# "data": +# { "cancel-path": "/sys/class/misc/tpm0/device/cancel", +# "path": "/dev/tpm0" +# } +# }, +# "id": "tpm0" +# } +# ] +# } +# +## +{ 'command': 'query-tpm', 'returns': ['TPMInfo'] } diff --git a/qapi/trace.json b/qapi/trace.json index de6588d9f7..799b254a18 100644 --- a/qapi/trace.json +++ b/qapi/trace.json @@ -6,7 +6,7 @@ # See the COPYING file in the top-level directory. ## -# = Tracing commands +# = Tracing ## ## diff --git a/qapi/transaction.json b/qapi/transaction.json new file mode 100644 index 0000000000..bd312792da --- /dev/null +++ b/qapi/transaction.json @@ -0,0 +1,158 @@ +# -*- Mode: Python -*- +# + +## +# = Transactions +## + +{ 'include': 'block.json' } + +## +# @Abort: +# +# This action can be used to test transaction failure. +# +# Since: 1.6 +## +{ 'struct': 'Abort', + 'data': { } } + +## +# @ActionCompletionMode: +# +# An enumeration of Transactional completion modes. +# +# @individual: Do not attempt to cancel any other Actions if any Actions fail +# after the Transaction request succeeds. All Actions that +# can complete successfully will do so without waiting on others. +# This is the default. +# +# @grouped: If any Action fails after the Transaction succeeds, cancel all +# Actions. Actions do not complete until all Actions are ready to +# complete. May be rejected by Actions that do not support this +# completion mode. +# +# Since: 2.5 +## +{ 'enum': 'ActionCompletionMode', + 'data': [ 'individual', 'grouped' ] } + +## +# @TransactionAction: +# +# A discriminated record of operations that can be performed with +# @transaction. Action @type can be: +# +# - @abort: since 1.6 +# - @block-dirty-bitmap-add: since 2.5 +# - @block-dirty-bitmap-clear: since 2.5 +# - @blockdev-backup: since 2.3 +# - @blockdev-snapshot: since 2.5 +# - @blockdev-snapshot-internal-sync: since 1.7 +# - @blockdev-snapshot-sync: since 1.1 +# - @drive-backup: since 1.6 +# +# Since: 1.1 +## +{ 'union': 'TransactionAction', + 'data': { + 'abort': 'Abort', + 'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd', + 'block-dirty-bitmap-clear': 'BlockDirtyBitmap', + 'blockdev-backup': 'BlockdevBackup', + 'blockdev-snapshot': 'BlockdevSnapshot', + 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal', + 'blockdev-snapshot-sync': 'BlockdevSnapshotSync', + 'drive-backup': 'DriveBackup' + } } + +## +# @TransactionProperties: +# +# Optional arguments to modify the behavior of a Transaction. +# +# @completion-mode: Controls how jobs launched asynchronously by +# Actions will complete or fail as a group. +# See @ActionCompletionMode for details. +# +# Since: 2.5 +## +{ 'struct': 'TransactionProperties', + 'data': { + '*completion-mode': 'ActionCompletionMode' + } +} + +## +# @transaction: +# +# Executes a number of transactionable QMP commands atomically. If any +# operation fails, then the entire set of actions will be abandoned and the +# appropriate error returned. +# +# For external snapshots, the dictionary contains the device, the file to use for +# the new snapshot, and the format. The default format, if not specified, is +# qcow2. +# +# Each new snapshot defaults to being created by QEMU (wiping any +# contents if the file already exists), but it is also possible to reuse +# an externally-created file. In the latter case, you should ensure that +# the new image file has the same contents as the current one; QEMU cannot +# perform any meaningful check. Typically this is achieved by using the +# current image file as the backing file for the new image. +# +# On failure, the original disks pre-snapshot attempt will be used. +# +# For internal snapshots, the dictionary contains the device and the snapshot's +# name. If an internal snapshot matching name already exists, the request will +# be rejected. Only some image formats support it, for example, qcow2, rbd, +# and sheepdog. +# +# On failure, qemu will try delete the newly created internal snapshot in the +# transaction. When an I/O error occurs during deletion, the user needs to fix +# it later with qemu-img or other command. +# +# @actions: List of @TransactionAction; +# information needed for the respective operations. +# +# @properties: structure of additional options to control the +# execution of the transaction. See @TransactionProperties +# for additional detail. +# +# Returns: nothing on success +# +# Errors depend on the operations of the transaction +# +# Note: The transaction aborts on the first failure. Therefore, there will be +# information on only one failed operation returned in an error condition, and +# subsequent actions will not have been attempted. +# +# Since: 1.1 +# +# Example: +# +# -> { "execute": "transaction", +# "arguments": { "actions": [ +# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd0", +# "snapshot-file": "/some/place/my-image", +# "format": "qcow2" } }, +# { "type": "blockdev-snapshot-sync", "data" : { "node-name": "myfile", +# "snapshot-file": "/some/place/my-image2", +# "snapshot-node-name": "node3432", +# "mode": "existing", +# "format": "qcow2" } }, +# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd1", +# "snapshot-file": "/some/place/my-image2", +# "mode": "existing", +# "format": "qcow2" } }, +# { "type": "blockdev-snapshot-internal-sync", "data" : { +# "device": "ide-hd2", +# "name": "snapshot0" } } ] } } +# <- { "return": {} } +# +## +{ 'command': 'transaction', + 'data': { 'actions': [ 'TransactionAction' ], + '*properties': 'TransactionProperties' + } +} diff --git a/qapi/ui.json b/qapi/ui.json new file mode 100644 index 0000000000..e5d6610b4a --- /dev/null +++ b/qapi/ui.json @@ -0,0 +1,977 @@ +# -*- Mode: Python -*- +# + +## +# = Remote desktop +## + +{ 'include': 'sockets.json' } + +## +# @set_password: +# +# Sets the password of a remote display session. +# +# @protocol: `vnc' to modify the VNC server password +# `spice' to modify the Spice server password +# +# @password: the new password +# +# @connected: how to handle existing clients when changing the +# password. If nothing is specified, defaults to `keep' +# `fail' to fail the command if clients are connected +# `disconnect' to disconnect existing clients +# `keep' to maintain existing clients +# +# Returns: Nothing on success +# If Spice is not enabled, DeviceNotFound +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "set_password", "arguments": { "protocol": "vnc", +# "password": "secret" } } +# <- { "return": {} } +# +## +{ 'command': 'set_password', + 'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} } + +## +# @expire_password: +# +# Expire the password of a remote display server. +# +# @protocol: the name of the remote display protocol `vnc' or `spice' +# +# @time: when to expire the password. +# `now' to expire the password immediately +# `never' to cancel password expiration +# `+INT' where INT is the number of seconds from now (integer) +# `INT' where INT is the absolute time in seconds +# +# Returns: Nothing on success +# If @protocol is `spice' and Spice is not active, DeviceNotFound +# +# Since: 0.14.0 +# +# Notes: Time is relative to the server and currently there is no way to +# coordinate server time with client time. It is not recommended to +# use the absolute time version of the @time parameter unless you're +# sure you are on the same machine as the QEMU instance. +# +# Example: +# +# -> { "execute": "expire_password", "arguments": { "protocol": "vnc", +# "time": "+60" } } +# <- { "return": {} } +# +## +{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} } + +## +# @screendump: +# +# Write a PPM of the VGA screen to a file. +# +# @filename: the path of a new PPM file to store the image +# +# Returns: Nothing on success +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "screendump", +# "arguments": { "filename": "/tmp/image" } } +# <- { "return": {} } +# +## +{ 'command': 'screendump', 'data': {'filename': 'str'} } + +## +# == Spice +## + +## +# @SpiceBasicInfo: +# +# The basic information for SPICE network connection +# +# @host: IP address +# +# @port: port number +# +# @family: address family +# +# Since: 2.1 +## +{ 'struct': 'SpiceBasicInfo', + 'data': { 'host': 'str', + 'port': 'str', + 'family': 'NetworkAddressFamily' } } + +## +# @SpiceServerInfo: +# +# Information about a SPICE server +# +# @auth: authentication method +# +# Since: 2.1 +## +{ 'struct': 'SpiceServerInfo', + 'base': 'SpiceBasicInfo', + 'data': { '*auth': 'str' } } + +## +# @SpiceChannel: +# +# Information about a SPICE client channel. +# +# @connection-id: SPICE connection id number. All channels with the same id +# belong to the same SPICE session. +# +# @channel-type: SPICE channel type number. "1" is the main control +# channel, filter for this one if you want to track spice +# sessions only +# +# @channel-id: SPICE channel ID number. Usually "0", might be different when +# multiple channels of the same type exist, such as multiple +# display channels in a multihead setup +# +# @tls: true if the channel is encrypted, false otherwise. +# +# Since: 0.14.0 +## +{ 'struct': 'SpiceChannel', + 'base': 'SpiceBasicInfo', + 'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', + 'tls': 'bool'} } + +## +# @SpiceQueryMouseMode: +# +# An enumeration of Spice mouse states. +# +# @client: Mouse cursor position is determined by the client. +# +# @server: Mouse cursor position is determined by the server. +# +# @unknown: No information is available about mouse mode used by +# the spice server. +# +# Note: spice/enums.h has a SpiceMouseMode already, hence the name. +# +# Since: 1.1 +## +{ 'enum': 'SpiceQueryMouseMode', + 'data': [ 'client', 'server', 'unknown' ] } + +## +# @SpiceInfo: +# +# Information about the SPICE session. +# +# @enabled: true if the SPICE server is enabled, false otherwise +# +# @migrated: true if the last guest migration completed and spice +# migration had completed as well. false otherwise. (since 1.4) +# +# @host: The hostname the SPICE server is bound to. This depends on +# the name resolution on the host and may be an IP address. +# +# @port: The SPICE server's port number. +# +# @compiled-version: SPICE server version. +# +# @tls-port: The SPICE server's TLS port number. +# +# @auth: the current authentication type used by the server +# 'none' if no authentication is being used +# 'spice' uses SASL or direct TLS authentication, depending on command +# line options +# +# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can +# be determined by the client or the server, or unknown if spice +# server doesn't provide this information. (since: 1.1) +# +# @channels: a list of @SpiceChannel for each active spice channel +# +# Since: 0.14.0 +## +{ 'struct': 'SpiceInfo', + 'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int', + '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str', + 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} } + +## +# @query-spice: +# +# Returns information about the current SPICE server +# +# Returns: @SpiceInfo +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-spice" } +# <- { "return": { +# "enabled": true, +# "auth": "spice", +# "port": 5920, +# "tls-port": 5921, +# "host": "0.0.0.0", +# "channels": [ +# { +# "port": "54924", +# "family": "ipv4", +# "channel-type": 1, +# "connection-id": 1804289383, +# "host": "127.0.0.1", +# "channel-id": 0, +# "tls": true +# }, +# { +# "port": "36710", +# "family": "ipv4", +# "channel-type": 4, +# "connection-id": 1804289383, +# "host": "127.0.0.1", +# "channel-id": 0, +# "tls": false +# }, +# [ ... more channels follow ... ] +# ] +# } +# } +# +## +{ 'command': 'query-spice', 'returns': 'SpiceInfo' } + +## +# @SPICE_CONNECTED: +# +# Emitted when a SPICE client establishes a connection +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +# +# Example: +# +# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, +# "event": "SPICE_CONNECTED", +# "data": { +# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"}, +# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"} +# }} +# +## +{ 'event': 'SPICE_CONNECTED', + 'data': { 'server': 'SpiceBasicInfo', + 'client': 'SpiceBasicInfo' } } + +## +# @SPICE_INITIALIZED: +# +# Emitted after initial handshake and authentication takes place (if any) +# and the SPICE channel is up and running +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +# +# Example: +# +# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, +# "event": "SPICE_INITIALIZED", +# "data": {"server": {"auth": "spice", "port": "5921", +# "family": "ipv4", "host": "127.0.0.1"}, +# "client": {"port": "49004", "family": "ipv4", "channel-type": 3, +# "connection-id": 1804289383, "host": "127.0.0.1", +# "channel-id": 0, "tls": true} +# }} +# +## +{ 'event': 'SPICE_INITIALIZED', + 'data': { 'server': 'SpiceServerInfo', + 'client': 'SpiceChannel' } } + +## +# @SPICE_DISCONNECTED: +# +# Emitted when the SPICE connection is closed +# +# @server: server information +# +# @client: client information +# +# Since: 0.14.0 +# +# Example: +# +# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707}, +# "event": "SPICE_DISCONNECTED", +# "data": { +# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"}, +# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"} +# }} +# +## +{ 'event': 'SPICE_DISCONNECTED', + 'data': { 'server': 'SpiceBasicInfo', + 'client': 'SpiceBasicInfo' } } + +## +# @SPICE_MIGRATE_COMPLETED: +# +# Emitted when SPICE migration has completed +# +# Since: 1.3 +# +# Example: +# +# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172}, +# "event": "SPICE_MIGRATE_COMPLETED" } +# +## +{ 'event': 'SPICE_MIGRATE_COMPLETED' } + +## +# == VNC +## + +## +# @VncBasicInfo: +# +# The basic information for vnc network connection +# +# @host: IP address +# +# @service: The service name of the vnc port. This may depend on the host +# system's service database so symbolic names should not be relied +# on. +# +# @family: address family +# +# @websocket: true in case the socket is a websocket (since 2.3). +# +# Since: 2.1 +## +{ 'struct': 'VncBasicInfo', + 'data': { 'host': 'str', + 'service': 'str', + 'family': 'NetworkAddressFamily', + 'websocket': 'bool' } } + +## +# @VncServerInfo: +# +# The network connection information for server +# +# @auth: authentication method used for +# the plain (non-websocket) VNC server +# +# Since: 2.1 +## +{ 'struct': 'VncServerInfo', + 'base': 'VncBasicInfo', + 'data': { '*auth': 'str' } } + +## +# @VncClientInfo: +# +# Information about a connected VNC client. +# +# @x509_dname: If x509 authentication is in use, the Distinguished +# Name of the client. +# +# @sasl_username: If SASL authentication is in use, the SASL username +# used for authentication. +# +# Since: 0.14.0 +## +{ 'struct': 'VncClientInfo', + 'base': 'VncBasicInfo', + 'data': { '*x509_dname': 'str', '*sasl_username': 'str' } } + +## +# @VncInfo: +# +# Information about the VNC session. +# +# @enabled: true if the VNC server is enabled, false otherwise +# +# @host: The hostname the VNC server is bound to. This depends on +# the name resolution on the host and may be an IP address. +# +# @family: 'ipv6' if the host is listening for IPv6 connections +# 'ipv4' if the host is listening for IPv4 connections +# 'unix' if the host is listening on a unix domain socket +# 'unknown' otherwise +# +# @service: The service name of the server's port. This may depends +# on the host system's service database so symbolic names should not +# be relied on. +# +# @auth: the current authentication type used by the server +# 'none' if no authentication is being used +# 'vnc' if VNC authentication is being used +# 'vencrypt+plain' if VEncrypt is used with plain text authentication +# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication +# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication +# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth +# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth +# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth +# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth +# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth +# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth +# +# @clients: a list of @VncClientInfo of all currently connected clients +# +# Since: 0.14.0 +## +{ 'struct': 'VncInfo', + 'data': {'enabled': 'bool', '*host': 'str', + '*family': 'NetworkAddressFamily', + '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} } + +## +# @VncPrimaryAuth: +# +# vnc primary authentication method. +# +# Since: 2.3 +## +{ 'enum': 'VncPrimaryAuth', + 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra', + 'tls', 'vencrypt', 'sasl' ] } + +## +# @VncVencryptSubAuth: +# +# vnc sub authentication method with vencrypt. +# +# Since: 2.3 +## +{ 'enum': 'VncVencryptSubAuth', + 'data': [ 'plain', + 'tls-none', 'x509-none', + 'tls-vnc', 'x509-vnc', + 'tls-plain', 'x509-plain', + 'tls-sasl', 'x509-sasl' ] } + + +## +# @VncServerInfo2: +# +# The network connection information for server +# +# @auth: The current authentication type used by the servers +# +# @vencrypt: The vencrypt sub authentication type used by the +# servers, only specified in case auth == vencrypt. +# +# Since: 2.9 +## +{ 'struct': 'VncServerInfo2', + 'base': 'VncBasicInfo', + 'data': { 'auth' : 'VncPrimaryAuth', + '*vencrypt' : 'VncVencryptSubAuth' } } + + +## +# @VncInfo2: +# +# Information about a vnc server +# +# @id: vnc server name. +# +# @server: A list of @VncBasincInfo describing all listening sockets. +# The list can be empty (in case the vnc server is disabled). +# It also may have multiple entries: normal + websocket, +# possibly also ipv4 + ipv6 in the future. +# +# @clients: A list of @VncClientInfo of all currently connected clients. +# The list can be empty, for obvious reasons. +# +# @auth: The current authentication type used by the non-websockets servers +# +# @vencrypt: The vencrypt authentication type used by the servers, +# only specified in case auth == vencrypt. +# +# @display: The display device the vnc server is linked to. +# +# Since: 2.3 +## +{ 'struct': 'VncInfo2', + 'data': { 'id' : 'str', + 'server' : ['VncServerInfo2'], + 'clients' : ['VncClientInfo'], + 'auth' : 'VncPrimaryAuth', + '*vencrypt' : 'VncVencryptSubAuth', + '*display' : 'str' } } + +## +# @query-vnc: +# +# Returns information about the current VNC server +# +# Returns: @VncInfo +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-vnc" } +# <- { "return": { +# "enabled":true, +# "host":"0.0.0.0", +# "service":"50402", +# "auth":"vnc", +# "family":"ipv4", +# "clients":[ +# { +# "host":"127.0.0.1", +# "service":"50401", +# "family":"ipv4" +# } +# ] +# } +# } +# +## +{ 'command': 'query-vnc', 'returns': 'VncInfo' } + +## +# @query-vnc-servers: +# +# Returns a list of vnc servers. The list can be empty. +# +# Returns: a list of @VncInfo2 +# +# Since: 2.3 +## +{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] } + +## +# @change-vnc-password: +# +# Change the VNC server password. +# +# @password: the new password to use with VNC authentication +# +# Since: 1.1 +# +# Notes: An empty password in this command will set the password to the empty +# string. Existing clients are unaffected by executing this command. +## +{ 'command': 'change-vnc-password', 'data': {'password': 'str'} } + +## +# @VNC_CONNECTED: +# +# Emitted when a VNC client establishes a connection +# +# @server: server information +# +# @client: client information +# +# Note: This event is emitted before any authentication takes place, thus +# the authentication ID is not provided +# +# Since: 0.13.0 +# +# Example: +# +# <- { "event": "VNC_CONNECTED", +# "data": { +# "server": { "auth": "sasl", "family": "ipv4", +# "service": "5901", "host": "0.0.0.0" }, +# "client": { "family": "ipv4", "service": "58425", +# "host": "127.0.0.1" } }, +# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } } +# +## +{ 'event': 'VNC_CONNECTED', + 'data': { 'server': 'VncServerInfo', + 'client': 'VncBasicInfo' } } + +## +# @VNC_INITIALIZED: +# +# Emitted after authentication takes place (if any) and the VNC session is +# made active +# +# @server: server information +# +# @client: client information +# +# Since: 0.13.0 +# +# Example: +# +# <- { "event": "VNC_INITIALIZED", +# "data": { +# "server": { "auth": "sasl", "family": "ipv4", +# "service": "5901", "host": "0.0.0.0"}, +# "client": { "family": "ipv4", "service": "46089", +# "host": "127.0.0.1", "sasl_username": "luiz" } }, +# "timestamp": { "seconds": 1263475302, "microseconds": 150772 } } +# +## +{ 'event': 'VNC_INITIALIZED', + 'data': { 'server': 'VncServerInfo', + 'client': 'VncClientInfo' } } + +## +# @VNC_DISCONNECTED: +# +# Emitted when the connection is closed +# +# @server: server information +# +# @client: client information +# +# Since: 0.13.0 +# +# Example: +# +# <- { "event": "VNC_DISCONNECTED", +# "data": { +# "server": { "auth": "sasl", "family": "ipv4", +# "service": "5901", "host": "0.0.0.0" }, +# "client": { "family": "ipv4", "service": "58425", +# "host": "127.0.0.1", "sasl_username": "luiz" } }, +# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } } +# +## +{ 'event': 'VNC_DISCONNECTED', + 'data': { 'server': 'VncServerInfo', + 'client': 'VncClientInfo' } } + +## +# = Input +## + +## +# @MouseInfo: +# +# Information about a mouse device. +# +# @name: the name of the mouse device +# +# @index: the index of the mouse device +# +# @current: true if this device is currently receiving mouse events +# +# @absolute: true if this device supports absolute coordinates as input +# +# Since: 0.14.0 +## +{ 'struct': 'MouseInfo', + 'data': {'name': 'str', 'index': 'int', 'current': 'bool', + 'absolute': 'bool'} } + +## +# @query-mice: +# +# Returns information about each active mouse device +# +# Returns: a list of @MouseInfo for each device +# +# Since: 0.14.0 +# +# Example: +# +# -> { "execute": "query-mice" } +# <- { "return": [ +# { +# "name":"QEMU Microsoft Mouse", +# "index":0, +# "current":false, +# "absolute":false +# }, +# { +# "name":"QEMU PS/2 Mouse", +# "index":1, +# "current":true, +# "absolute":true +# } +# ] +# } +# +## +{ 'command': 'query-mice', 'returns': ['MouseInfo'] } + +## +# @QKeyCode: +# +# An enumeration of key name. +# +# This is used by the @send-key command. +# +# @unmapped: since 2.0 +# @pause: since 2.0 +# @ro: since 2.4 +# @kp_comma: since 2.4 +# @kp_equals: since 2.6 +# @power: since 2.6 +# @hiragana: since 2.9 +# @henkan: since 2.9 +# @yen: since 2.9 +# +# @sleep: since 2.10 +# @wake: since 2.10 +# @audionext: since 2.10 +# @audioprev: since 2.10 +# @audiostop: since 2.10 +# @audioplay: since 2.10 +# @audiomute: since 2.10 +# @volumeup: since 2.10 +# @volumedown: since 2.10 +# @mediaselect: since 2.10 +# @mail: since 2.10 +# @calculator: since 2.10 +# @computer: since 2.10 +# @ac_home: since 2.10 +# @ac_back: since 2.10 +# @ac_forward: since 2.10 +# @ac_refresh: since 2.10 +# @ac_bookmarks: since 2.10 +# altgr, altgr_r: dropped in 2.10 +# +# Since: 1.3.0 +# +## +{ 'enum': 'QKeyCode', + 'data': [ 'unmapped', + 'shift', 'shift_r', 'alt', 'alt_r', 'ctrl', + 'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8', + '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e', + 'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right', + 'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'semicolon', + 'apostrophe', 'grave_accent', 'backslash', 'z', 'x', 'c', 'v', 'b', + 'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc', 'caps_lock', + 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', + 'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply', + 'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal', 'sysrq', 'kp_0', + 'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6', 'kp_7', 'kp_8', + 'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end', + 'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again', + 'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut', + 'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause', + 'ro', 'hiragana', 'henkan', 'yen', + 'kp_comma', 'kp_equals', 'power', 'sleep', 'wake', + 'audionext', 'audioprev', 'audiostop', 'audioplay', 'audiomute', + 'volumeup', 'volumedown', 'mediaselect', + 'mail', 'calculator', 'computer', + 'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks' ] } + +## +# @KeyValue: +# +# Represents a keyboard key. +# +# Since: 1.3.0 +## +{ 'union': 'KeyValue', + 'data': { + 'number': 'int', + 'qcode': 'QKeyCode' } } + +## +# @send-key: +# +# Send keys to guest. +# +# @keys: An array of @KeyValue elements. All @KeyValues in this array are +# simultaneously sent to the guest. A @KeyValue.number value is sent +# directly to the guest, while @KeyValue.qcode must be a valid +# @QKeyCode value +# +# @hold-time: time to delay key up events, milliseconds. Defaults +# to 100 +# +# Returns: Nothing on success +# If key is unknown or redundant, InvalidParameter +# +# Since: 1.3.0 +# +# Example: +# +# -> { "execute": "send-key", +# "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" }, +# { "type": "qcode", "data": "alt" }, +# { "type": "qcode", "data": "delete" } ] } } +# <- { "return": {} } +# +## +{ 'command': 'send-key', + 'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } } + +## +# @InputButton: +# +# Button of a pointer input device (mouse, tablet). +# +# @side: front side button of a 5-button mouse (since 2.9) +# +# @extra: rear side button of a 5-button mouse (since 2.9) +# +# Since: 2.0 +## +{ 'enum' : 'InputButton', + 'data' : [ 'left', 'middle', 'right', 'wheel-up', 'wheel-down', 'side', + 'extra' ] } + +## +# @InputAxis: +# +# Position axis of a pointer input device (mouse, tablet). +# +# Since: 2.0 +## +{ 'enum' : 'InputAxis', + 'data' : [ 'x', 'y' ] } + +## +# @InputKeyEvent: +# +# Keyboard input event. +# +# @key: Which key this event is for. +# @down: True for key-down and false for key-up events. +# +# Since: 2.0 +## +{ 'struct' : 'InputKeyEvent', + 'data' : { 'key' : 'KeyValue', + 'down' : 'bool' } } + +## +# @InputBtnEvent: +# +# Pointer button input event. +# +# @button: Which button this event is for. +# @down: True for key-down and false for key-up events. +# +# Since: 2.0 +## +{ 'struct' : 'InputBtnEvent', + 'data' : { 'button' : 'InputButton', + 'down' : 'bool' } } + +## +# @InputMoveEvent: +# +# Pointer motion input event. +# +# @axis: Which axis is referenced by @value. +# @value: Pointer position. For absolute coordinates the +# valid range is 0 -> 0x7ffff +# +# Since: 2.0 +## +{ 'struct' : 'InputMoveEvent', + 'data' : { 'axis' : 'InputAxis', + 'value' : 'int' } } + +## +# @InputEvent: +# +# Input event union. +# +# @type: the input type, one of: +# - 'key': Input event of Keyboard +# - 'btn': Input event of pointer buttons +# - 'rel': Input event of relative pointer motion +# - 'abs': Input event of absolute pointer motion +# +# Since: 2.0 +## +{ 'union' : 'InputEvent', + 'data' : { 'key' : 'InputKeyEvent', + 'btn' : 'InputBtnEvent', + 'rel' : 'InputMoveEvent', + 'abs' : 'InputMoveEvent' } } + +## +# @input-send-event: +# +# Send input event(s) to guest. +# +# @device: display device to send event(s) to. +# @head: head to send event(s) to, in case the +# display device supports multiple scanouts. +# @events: List of InputEvent union. +# +# Returns: Nothing on success. +# +# The @device and @head parameters can be used to send the input event +# to specific input devices in case (a) multiple input devices of the +# same kind are added to the virtual machine and (b) you have +# configured input routing (see docs/multiseat.txt) for those input +# devices. The parameters work exactly like the device and head +# properties of input devices. If @device is missing, only devices +# that have no input routing config are admissible. If @device is +# specified, both input devices with and without input routing config +# are admissible, but devices with input routing config take +# precedence. +# +# Since: 2.6 +# +# Note: The consoles are visible in the qom tree, under +# /backend/console[$index]. They have a device link and head property, +# so it is possible to map which console belongs to which device and +# display. +# +# Example: +# +# 1. Press left mouse button. +# +# -> { "execute": "input-send-event", +# "arguments": { "device": "video0", +# "events": [ { "type": "btn", +# "data" : { "down": true, "button": "left" } } ] } } +# <- { "return": {} } +# +# -> { "execute": "input-send-event", +# "arguments": { "device": "video0", +# "events": [ { "type": "btn", +# "data" : { "down": false, "button": "left" } } ] } } +# <- { "return": {} } +# +# 2. Press ctrl-alt-del. +# +# -> { "execute": "input-send-event", +# "arguments": { "events": [ +# { "type": "key", "data" : { "down": true, +# "key": {"type": "qcode", "data": "ctrl" } } }, +# { "type": "key", "data" : { "down": true, +# "key": {"type": "qcode", "data": "alt" } } }, +# { "type": "key", "data" : { "down": true, +# "key": {"type": "qcode", "data": "delete" } } } ] } } +# <- { "return": {} } +# +# 3. Move mouse pointer to absolute coordinates (20000, 400). +# +# -> { "execute": "input-send-event" , +# "arguments": { "events": [ +# { "type": "abs", "data" : { "axis": "x", "value" : 20000 } }, +# { "type": "abs", "data" : { "axis": "y", "value" : 400 } } ] } } +# <- { "return": {} } +# +## +{ 'command': 'input-send-event', + 'data': { '*device': 'str', + '*head' : 'int', + 'events' : [ 'InputEvent' ] } } diff --git a/qemu-img.c b/qemu-img.c index 56ef49e214..df984b11b9 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -26,7 +26,6 @@ #include "qemu-version.h" #include "qapi/error.h" -#include "qapi/util.h" #include "qapi-visit.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qmp/qerror.h" @@ -3490,9 +3489,8 @@ static int img_resize(int argc, char **argv) image_opts = true; break; case OPTION_PREALLOCATION: - prealloc = qapi_enum_parse(PreallocMode_lookup, optarg, - PREALLOC_MODE__MAX, PREALLOC_MODE__MAX, - NULL); + prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg, + PREALLOC_MODE__MAX, NULL); if (prealloc == PREALLOC_MODE__MAX) { error_report("Invalid preallocation mode '%s'", optarg); return 1; diff --git a/qemu-nbd.c b/qemu-nbd.c index 27164b8205..d75ca51482 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -34,7 +34,6 @@ #include "qemu/log.h" #include "qemu/systemd.h" #include "block/snapshot.h" -#include "qapi/util.h" #include "qapi/qmp/qstring.h" #include "qom/object_interfaces.h" #include "io/channel-socket.h" @@ -639,9 +638,8 @@ int main(int argc, char **argv) break; case QEMU_NBD_OPT_DETECT_ZEROES: detect_zeroes = - qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, + qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, optarg, - BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index fc8885c9a4..002d25873a 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ -util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o +util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o qlit.o util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/qlit.c b/qobject/qlit.c new file mode 100644 index 0000000000..3c4882c784 --- /dev/null +++ b/qobject/qlit.c @@ -0,0 +1,84 @@ +/* + * QLit literal qobject + * + * Copyright IBM, Corp. 2009 + * Copyright (c) 2013, 2015, 2017 Red Hat Inc. + * + * Authors: + * Anthony Liguori <aliguori@us.ibm.com> + * Markus Armbruster <armbru@redhat.com> + * Marc-André Lureau <marcandre.lureau@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qapi/qmp/qlit.h" +#include "qapi/qmp/types.h" + +static bool qlit_equal_qdict(const QLitObject *lhs, const QDict *qdict) +{ + int i; + + for (i = 0; lhs->value.qdict[i].key; i++) { + QObject *obj = qdict_get(qdict, lhs->value.qdict[i].key); + + if (!qlit_equal_qobject(&lhs->value.qdict[i].value, obj)) { + return false; + } + } + + /* Note: the literal qdict must not contain duplicates, this is + * considered a programming error and it isn't checked here. */ + if (qdict_size(qdict) != i) { + return false; + } + + return true; +} + +static bool qlit_equal_qlist(const QLitObject *lhs, const QList *qlist) +{ + QListEntry *e; + int i = 0; + + QLIST_FOREACH_ENTRY(qlist, e) { + QObject *obj = qlist_entry_obj(e); + + if (!qlit_equal_qobject(&lhs->value.qlist[i], obj)) { + return false; + } + i++; + } + + return !e && lhs->value.qlist[i].type == QTYPE_NONE; +} + +bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs) +{ + if (!rhs || lhs->type != qobject_type(rhs)) { + return false; + } + + switch (lhs->type) { + case QTYPE_QBOOL: + return lhs->value.qbool == qbool_get_bool(qobject_to_qbool(rhs)); + case QTYPE_QNUM: + return lhs->value.qnum == qnum_get_int(qobject_to_qnum(rhs)); + case QTYPE_QSTRING: + return (strcmp(lhs->value.qstr, + qstring_get_str(qobject_to_qstring(rhs))) == 0); + case QTYPE_QDICT: + return qlit_equal_qdict(lhs, qobject_to_qdict(rhs)); + case QTYPE_QLIST: + return qlit_equal_qlist(lhs, qobject_to_qlist(rhs)); + case QTYPE_QNULL: + return true; + default: + break; + } + + return false; +} diff --git a/qom/object.c b/qom/object.c index fe6e744b4d..3e18537e9b 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1246,7 +1246,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name, } typedef struct EnumProperty { - const char * const *strings; + const QEnumLookup *lookup; int (*get)(Object *, Error **); void (*set)(Object *, int, Error **); } EnumProperty; @@ -1284,7 +1284,7 @@ int object_property_get_enum(Object *obj, const char *name, visit_complete(v, &str); visit_free(v); v = string_input_visitor_new(str); - visit_type_enum(v, name, &ret, enumprop->strings, errp); + visit_type_enum(v, name, &ret, enumprop->lookup, errp); g_free(str); visit_free(v); @@ -1950,7 +1950,7 @@ static void property_get_enum(Object *obj, Visitor *v, const char *name, return; } - visit_type_enum(v, name, &value, prop->strings, errp); + visit_type_enum(v, name, &value, prop->lookup, errp); } static void property_set_enum(Object *obj, Visitor *v, const char *name, @@ -1960,7 +1960,7 @@ static void property_set_enum(Object *obj, Visitor *v, const char *name, int value; Error *err = NULL; - visit_type_enum(v, name, &value, prop->strings, &err); + visit_type_enum(v, name, &value, prop->lookup, &err); if (err) { error_propagate(errp, err); return; @@ -1977,7 +1977,7 @@ static void property_release_enum(Object *obj, const char *name, void object_property_add_enum(Object *obj, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp) @@ -1985,7 +1985,7 @@ void object_property_add_enum(Object *obj, const char *name, Error *local_err = NULL; EnumProperty *prop = g_malloc(sizeof(*prop)); - prop->strings = strings; + prop->lookup = lookup; prop->get = get; prop->set = set; @@ -2002,7 +2002,7 @@ void object_property_add_enum(Object *obj, const char *name, void object_class_property_add_enum(ObjectClass *klass, const char *name, const char *typename, - const char * const *strings, + const QEnumLookup *lookup, int (*get)(Object *, Error **), void (*set)(Object *, int, Error **), Error **errp) @@ -2010,7 +2010,7 @@ void object_class_property_add_enum(ObjectClass *klass, const char *name, Error *local_err = NULL; EnumProperty *prop = g_malloc(sizeof(*prop)); - prop->strings = strings; + prop->lookup = lookup; prop->get = get; prop->set = set; diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci index c518caf7b1..1120eb1a42 100644 --- a/scripts/coccinelle/qobject.cocci +++ b/scripts/coccinelle/qobject.cocci @@ -20,6 +20,9 @@ expression Obj, Key, E; | - qdict_put(Obj, Key, qstring_from_str(E)); + qdict_put_str(Obj, Key, E); +| +- qdict_put(Obj, Key, qnull()); ++ qdict_put_null(Obj, Key); ) // Use QList macros where they make sense diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py index bcbef1035f..07b4b70199 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi-event.py @@ -217,6 +217,7 @@ fdef.write(mcgen(''' fdecl.write(mcgen(''' #include "qapi/error.h" +#include "qapi/util.h" #include "qapi/qmp/qdict.h" #include "%(prefix)sqapi-types.h" diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index b45e7b5634..7e3051dbb9 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -292,6 +292,10 @@ fdef.write(mcgen(''' ''', prefix=prefix)) +fdecl.write(mcgen(''' +#include "qapi/util.h" +''')) + schema = QAPISchema(input_file) gen = QAPISchemaGenTypeVisitor() schema.visit(gen) diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index bd0b742236..7e1cfc13f0 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -153,7 +153,7 @@ def gen_visit_enum(name): void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp) { int value = *obj; - visit_type_enum(v, name, &value, %(c_name)s_lookup, errp); + visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp); *obj = value; } ''', diff --git a/scripts/qapi.py b/scripts/qapi.py index 8aa2775f12..62dc52ed6e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -825,11 +825,11 @@ def check_alternate(expr, info): else: conflicting.add('QTYPE_QNUM') conflicting.add('QTYPE_QBOOL') - if conflicting & set(types_seen): - raise QAPISemError(info, "Alternate '%s' member '%s' can't " - "be distinguished from member '%s'" - % (name, key, types_seen[qtype])) for qt in conflicting: + if qt in types_seen: + raise QAPISemError(info, "Alternate '%s' member '%s' can't " + "be distinguished from member '%s'" + % (name, key, types_seen[qt])) types_seen[qt] = key @@ -1849,22 +1849,23 @@ def guardend(name): def gen_enum_lookup(name, values, prefix=None): ret = mcgen(''' -const char *const %(c_name)s_lookup[] = { +const QEnumLookup %(c_name)s_lookup = { + .array = (const char *const[]) { ''', c_name=c_name(name)) for value in values: index = c_enum_const(name, value, prefix) ret += mcgen(''' - [%(index)s] = "%(value)s", + [%(index)s] = "%(value)s", ''', index=index, value=value) - max_index = c_enum_const(name, '_MAX', prefix) ret += mcgen(''' - [%(max_index)s] = NULL, + }, + .size = %(max_index)s }; ''', - max_index=max_index) + max_index=c_enum_const(name, '_MAX', prefix)) return ret @@ -1894,7 +1895,10 @@ typedef enum %(c_name)s { ret += mcgen(''' -extern const char *const %(c_name)s_lookup[]; +#define %(c_name)s_str(val) \\ + qapi_enum_lookup(&%(c_name)s_lookup, (val)) + +extern const QEnumLookup %(c_name)s_lookup; ''', c_name=c_name(name)) return ret diff --git a/target/i386/cpu.c b/target/i386/cpu.c index f81576d11d..69676e13e1 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2498,7 +2498,7 @@ static QDict *x86_cpu_static_props(void) d = qdict_new(); for (i = 0; props[i]; i++) { - qdict_put(d, props[i], qnull()); + qdict_put_null(d, props[i]); } for (w = 0; w < FEATURE_WORDS; w++) { @@ -2508,7 +2508,7 @@ static QDict *x86_cpu_static_props(void) if (!fi->feat_names[bit]) { continue; } - qdict_put(d, fi->feat_names[bit], qnull()); + qdict_put_null(d, fi->feat_names[bit]); } } diff --git a/tests/Makefile.include b/tests/Makefile.include index f08b7418f0..fae5715e9c 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -43,6 +43,8 @@ check-unit-y += tests/check-qnull$(EXESUF) gcov-files-check-qnull-y = qobject/qnull.c check-unit-y += tests/check-qjson$(EXESUF) gcov-files-check-qjson-y = qobject/qjson.c +check-unit-y += tests/check-qlit$(EXESUF) +gcov-files-check-qlit-y = qobject/qlit.c check-unit-y += tests/test-qobject-output-visitor$(EXESUF) gcov-files-test-qobject-output-visitor-y = qapi/qobject-output-visitor.c check-unit-y += tests/test-clone-visitor$(EXESUF) @@ -376,6 +378,8 @@ qapi-schema += alternate-conflict-dict.json qapi-schema += alternate-conflict-enum-bool.json qapi-schema += alternate-conflict-enum-int.json qapi-schema += alternate-conflict-string.json +qapi-schema += alternate-conflict-bool-string.json +qapi-schema += alternate-conflict-num-string.json qapi-schema += alternate-empty.json qapi-schema += alternate-nested.json qapi-schema += alternate-unknown.json @@ -539,7 +543,7 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \ test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \ tests/check-qlist.o tests/check-qnull.o \ - tests/check-qjson.o \ + tests/check-qjson.o tests/check-qlit.o \ tests/test-coroutine.o tests/test-string-output-visitor.o \ tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \ tests/test-clone-visitor.o \ @@ -573,6 +577,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y) tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) +tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y) tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y) diff --git a/tests/check-qjson.c b/tests/check-qjson.c index a3a97b0d99..59227934ce 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -16,6 +16,7 @@ #include "qapi/error.h" #include "qapi/qmp/types.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlit.h" #include "qemu-common.h" static void escaped_string(void) @@ -1059,123 +1060,28 @@ static void keyword_literal(void) QDECREF(null); } -typedef struct LiteralQDictEntry LiteralQDictEntry; -typedef struct LiteralQObject LiteralQObject; - -struct LiteralQObject -{ - int type; - union { - int64_t qnum; - const char *qstr; - LiteralQDictEntry *qdict; - LiteralQObject *qlist; - } value; -}; - -struct LiteralQDictEntry -{ - const char *key; - LiteralQObject value; -}; - -#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} -#define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} -#define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} -#define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} - -typedef struct QListCompareHelper -{ - int index; - LiteralQObject *objs; - int result; -} QListCompareHelper; - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs); - -static void compare_helper(QObject *obj, void *opaque) -{ - QListCompareHelper *helper = opaque; - - if (helper->result == 0) { - return; - } - - if (helper->objs[helper->index].type == QTYPE_NONE) { - helper->result = 0; - return; - } - - helper->result = compare_litqobj_to_qobj(&helper->objs[helper->index++], obj); -} - -static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) -{ - int64_t val; - - if (!rhs || lhs->type != qobject_type(rhs)) { - return 0; - } - - switch (lhs->type) { - case QTYPE_QNUM: - g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); - return lhs->value.qnum == val; - case QTYPE_QSTRING: - return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); - case QTYPE_QDICT: { - int i; - - for (i = 0; lhs->value.qdict[i].key; i++) { - QObject *obj = qdict_get(qobject_to_qdict(rhs), lhs->value.qdict[i].key); - - if (!compare_litqobj_to_qobj(&lhs->value.qdict[i].value, obj)) { - return 0; - } - } - - return 1; - } - case QTYPE_QLIST: { - QListCompareHelper helper; - - helper.index = 0; - helper.objs = lhs->value.qlist; - helper.result = 1; - - qlist_iter(qobject_to_qlist(rhs), compare_helper, &helper); - - return helper.result; - } - default: - break; - } - - return 0; -} - static void simple_dict(void) { int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(42) }, { "bar", QLIT_QSTR("hello world") }, { } })), }, { .encoded = "{}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { } })), }, { .encoded = "{\"foo\": 43}", - .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QDICT(((QLitDictEntry[]){ { "foo", QLIT_QNUM(43) }, { } })), @@ -1188,13 +1094,13 @@ static void simple_dict(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1257,11 +1163,11 @@ static void simple_list(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = "[43,42]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1269,21 +1175,21 @@ static void simple_list(void) }, { .encoded = "[43]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), { } })), }, { .encoded = "[]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ { } })), }, { .encoded = "[{}]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QDICT(((LiteralQDictEntry[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ + QLIT_QDICT(((QLitDictEntry[]){ {}, })), {}, @@ -1297,13 +1203,13 @@ static void simple_list(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); } @@ -1314,11 +1220,11 @@ static void simple_whitespace(void) int i; struct { const char *encoded; - LiteralQObject decoded; + QLitObject decoded; } test_cases[] = { { .encoded = " [ 43 , 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), QLIT_QNUM(42), { } @@ -1326,12 +1232,12 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1339,13 +1245,13 @@ static void simple_whitespace(void) }, { .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]", - .decoded = QLIT_QLIST(((LiteralQObject[]){ + .decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(43), - QLIT_QDICT(((LiteralQDictEntry[]){ + QLIT_QDICT(((QLitDictEntry[]){ { "h", QLIT_QSTR("b") }, { "a", QLIT_QNUM(32) }, { }})), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ { }})), QLIT_QNUM(42), { } @@ -1359,13 +1265,13 @@ static void simple_whitespace(void) QString *str; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); str = qobject_to_json(obj); qobject_decref(obj); obj = qobject_from_json(qstring_get_str(str), &error_abort); - g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1); + g_assert(qlit_equal_qobject(&test_cases[i].decoded, obj)); qobject_decref(obj); QDECREF(str); @@ -1376,10 +1282,10 @@ static void simple_varargs(void) { QObject *embedded_obj; QObject *obj; - LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){ + QLitObject decoded = QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(1), QLIT_QNUM(2), - QLIT_QLIST(((LiteralQObject[]){ + QLIT_QLIST(((QLitObject[]){ QLIT_QNUM(32), QLIT_QNUM(42), {}})), @@ -1389,7 +1295,7 @@ static void simple_varargs(void) g_assert(embedded_obj != NULL); obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); - g_assert(compare_litqobj_to_qobj(&decoded, obj) == 1); + g_assert(qlit_equal_qobject(&decoded, obj)); qobject_decref(obj); } diff --git a/tests/check-qlit.c b/tests/check-qlit.c new file mode 100644 index 0000000000..c59ec1ab88 --- /dev/null +++ b/tests/check-qlit.c @@ -0,0 +1,74 @@ +/* + * QLit unit-tests. + * + * Copyright (C) 2017 Red Hat Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qlit.h" +#include "qapi/qmp/qnum.h" +#include "qapi/qmp/qstring.h" + +static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) { + { "foo", QLIT_QNUM(42) }, + { "bar", QLIT_QSTR("hello world") }, + { "baz", QLIT_QNULL }, + { "bee", QLIT_QLIST(((QLitObject[]) { + QLIT_QNUM(43), + QLIT_QNUM(44), + QLIT_QBOOL(true), + { }, + }))}, + { }, +})); + +static QLitObject qlit_foo = QLIT_QDICT(((QLitDictEntry[]) { + { "foo", QLIT_QNUM(42) }, + { }, +})); + +static QObject *make_qobject(void) +{ + QDict *qdict = qdict_new(); + QList *list = qlist_new(); + + qdict_put_int(qdict, "foo", 42); + qdict_put_str(qdict, "bar", "hello world"); + qdict_put_null(qdict, "baz"); + + qlist_append_int(list, 43); + qlist_append_int(list, 44); + qlist_append_bool(list, true); + qdict_put(qdict, "bee", list); + + return QOBJECT(qdict); +} + +static void qlit_equal_qobject_test(void) +{ + QObject *qobj = make_qobject(); + + g_assert(qlit_equal_qobject(&qlit, qobj)); + + g_assert(!qlit_equal_qobject(&qlit_foo, qobj)); + + qdict_put(qobject_to_qdict(qobj), "bee", qlist_new()); + g_assert(!qlit_equal_qobject(&qlit, qobj)); + + qobject_decref(qobj); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test); + + return g_test_run(); +} diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index c51e6e734d..92898e1520 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -46,11 +46,13 @@ enum DummyAnimal { DUMMY_LAST, }; -static const char *const dummy_animal_map[DUMMY_LAST + 1] = { - [DUMMY_FROG] = "frog", - [DUMMY_ALLIGATOR] = "alligator", - [DUMMY_PLATYPUS] = "platypus", - [DUMMY_LAST] = NULL, +const QEnumLookup dummy_animal_map = { + .array = (const char *const[]) { + [DUMMY_FROG] = "frog", + [DUMMY_ALLIGATOR] = "alligator", + [DUMMY_PLATYPUS] = "platypus", + }, + .size = DUMMY_LAST }; struct DummyObject { @@ -142,7 +144,7 @@ static void dummy_class_init(ObjectClass *cls, void *data) NULL); object_class_property_add_enum(cls, "av", "DummyAnimal", - dummy_animal_map, + &dummy_animal_map, dummy_get_av, dummy_set_av, NULL); diff --git a/tests/qapi-schema/alternate-conflict-bool-string.err b/tests/qapi-schema/alternate-conflict-bool-string.err new file mode 100644 index 0000000000..e52fee7620 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-bool-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-bool-string.exit b/tests/qapi-schema/alternate-conflict-bool-string.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-bool-string.json b/tests/qapi-schema/alternate-conflict-bool-string.json new file mode 100644 index 0000000000..0544de10f3 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.json @@ -0,0 +1,4 @@ +# alternate branches of 'str' type conflict with all scalar types +{ 'alternate': 'Alt', + 'data': { 'one': 'bool', + 'two': 'str' } } diff --git a/tests/qapi-schema/alternate-conflict-bool-string.out b/tests/qapi-schema/alternate-conflict-bool-string.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-bool-string.out diff --git a/tests/qapi-schema/alternate-conflict-num-string.err b/tests/qapi-schema/alternate-conflict-num-string.err new file mode 100644 index 0000000000..5ba3827dd1 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-num-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-num-string.exit b/tests/qapi-schema/alternate-conflict-num-string.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-num-string.json b/tests/qapi-schema/alternate-conflict-num-string.json new file mode 100644 index 0000000000..ae901449af --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.json @@ -0,0 +1,4 @@ +# alternate branches of 'str' type conflict with all scalar types +{ 'alternate': 'Alt', + 'data': { 'one': 'number', + 'two': 'str' } } diff --git a/tests/qapi-schema/alternate-conflict-num-string.out b/tests/qapi-schema/alternate-conflict-num-string.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-num-string.out diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 5d0260b2be..c5a5c10b41 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -15,6 +15,7 @@ #include "qapi-visit.h" #include "qapi/error.h" #include "qapi/qobject-input-visitor.h" +#include "qapi/util.h" #include "qapi/visitor.h" const char common_args[] = "-nodefaults -machine none"; @@ -129,11 +130,189 @@ static void test_qmp_protocol(void) qtest_end(); } +static int query_error_class(const char *cmd) +{ + static struct { + const char *cmd; + int err_class; + } fails[] = { + /* Success depends on build configuration: */ +#ifndef CONFIG_SPICE + { "query-spice", ERROR_CLASS_COMMAND_NOT_FOUND }, +#endif +#ifndef CONFIG_VNC + { "query-vnc", ERROR_CLASS_GENERIC_ERROR }, + { "query-vnc-servers", ERROR_CLASS_GENERIC_ERROR }, +#endif +#ifndef CONFIG_REPLICATION + { "query-xen-replication-status", ERROR_CLASS_COMMAND_NOT_FOUND }, +#endif + /* Likewise, and require special QEMU command-line arguments: */ + { "query-acpi-ospm-status", ERROR_CLASS_GENERIC_ERROR }, + { "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE }, + { "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR }, + { "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR }, + { NULL, -1 } + }; + int i; + + for (i = 0; fails[i].cmd; i++) { + if (!strcmp(cmd, fails[i].cmd)) { + return fails[i].err_class; + } + } + return -1; +} + +static void test_query(const void *data) +{ + const char *cmd = data; + int expected_error_class = query_error_class(cmd); + QDict *resp, *error; + const char *error_class; + + qtest_start(common_args); + + resp = qmp("{ 'execute': %s }", cmd); + error = qdict_get_qdict(resp, "error"); + error_class = error ? qdict_get_str(error, "class") : NULL; + + if (expected_error_class < 0) { + g_assert(qdict_haskey(resp, "return")); + } else { + g_assert(error); + g_assert_cmpint(qapi_enum_parse(&QapiErrorClass_lookup, error_class, + -1, &error_abort), + ==, expected_error_class); + } + QDECREF(resp); + + qtest_end(); +} + +static bool query_is_blacklisted(const char *cmd) +{ + const char *blacklist[] = { + /* Not actually queries: */ + "add-fd", + /* Success depends on target arch: */ + "query-cpu-definitions", /* arm, i386, ppc, s390x */ + "query-gic-capabilities", /* arm */ + /* Success depends on target-specific build configuration: */ + "query-pci", /* CONFIG_PCI */ + NULL + }; + int i; + + for (i = 0; blacklist[i]; i++) { + if (!strcmp(cmd, blacklist[i])) { + return true; + } + } + return false; +} + +typedef struct { + SchemaInfoList *list; + GHashTable *hash; +} QmpSchema; + +static void qmp_schema_init(QmpSchema *schema) +{ + QDict *resp; + Visitor *qiv; + SchemaInfoList *tail; + + qtest_start(common_args); + resp = qmp("{ 'execute': 'query-qmp-schema' }"); + + qiv = qobject_input_visitor_new(qdict_get(resp, "return")); + visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort); + visit_free(qiv); + + QDECREF(resp); + qtest_end(); + + schema->hash = g_hash_table_new(g_str_hash, g_str_equal); + + /* Build @schema: hash table mapping entity name to SchemaInfo */ + for (tail = schema->list; tail; tail = tail->next) { + g_hash_table_insert(schema->hash, tail->value->name, tail->value); + } +} + +static SchemaInfo *qmp_schema_lookup(QmpSchema *schema, const char *name) +{ + return g_hash_table_lookup(schema->hash, name); +} + +static void qmp_schema_cleanup(QmpSchema *schema) +{ + qapi_free_SchemaInfoList(schema->list); + g_hash_table_destroy(schema->hash); +} + +static bool object_type_has_mandatory_members(SchemaInfo *type) +{ + SchemaInfoObjectMemberList *tail; + + g_assert(type->meta_type == SCHEMA_META_TYPE_OBJECT); + + for (tail = type->u.object.members; tail; tail = tail->next) { + if (!tail->value->has_q_default) { + return true; + } + } + + return false; +} + +static void add_query_tests(QmpSchema *schema) +{ + SchemaInfoList *tail; + SchemaInfo *si, *arg_type, *ret_type; + const char *test_name; + + /* Test the query-like commands */ + for (tail = schema->list; tail; tail = tail->next) { + si = tail->value; + if (si->meta_type != SCHEMA_META_TYPE_COMMAND) { + continue; + } + + if (query_is_blacklisted(si->name)) { + continue; + } + + arg_type = qmp_schema_lookup(schema, si->u.command.arg_type); + if (object_type_has_mandatory_members(arg_type)) { + continue; + } + + ret_type = qmp_schema_lookup(schema, si->u.command.ret_type); + if (ret_type->meta_type == SCHEMA_META_TYPE_OBJECT + && !ret_type->u.object.members) { + continue; + } + + test_name = g_strdup_printf("qmp/%s", si->name); + qtest_add_data_func(test_name, si->name, test_query); + } +} + int main(int argc, char *argv[]) { + QmpSchema schema; + int ret; + g_test_init(&argc, &argv, NULL); qtest_add_func("qmp/protocol", test_qmp_protocol); + qmp_schema_init(&schema); + add_query_tests(&schema); + + ret = g_test_run(); - return g_test_run(); + qmp_schema_cleanup(&schema); + return ret; } diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c index e8697577a5..4b5e4f8bd3 100644 --- a/tests/test-qapi-util.c +++ b/tests/test-qapi-util.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/util.h" #include "test-qapi-types.h" static void test_qapi_enum_parse(void) @@ -20,25 +19,20 @@ static void test_qapi_enum_parse(void) Error *err = NULL; int ret; - ret = qapi_enum_parse(QType_lookup, NULL, QTYPE__MAX, QTYPE_NONE, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, NULL, QTYPE_NONE, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - NULL); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, NULL); g_assert_cmpint(ret, ==, -1); - ret = qapi_enum_parse(QType_lookup, "junk", QTYPE__MAX, -1, - &err); + ret = qapi_enum_parse(&QType_lookup, "junk", -1, &err); error_free_or_abort(&err); - ret = qapi_enum_parse(QType_lookup, "none", QTYPE__MAX, -1, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, "none", -1, &error_abort); g_assert_cmpint(ret, ==, QTYPE_NONE); - ret = qapi_enum_parse(QType_lookup, QType_lookup[QTYPE__MAX - 1], - QTYPE__MAX, QTYPE__MAX - 1, - &error_abort); + ret = qapi_enum_parse(&QType_lookup, QType_str(QTYPE__MAX - 1), + QTYPE__MAX - 1, &error_abort); g_assert_cmpint(ret, ==, QTYPE__MAX - 1); } diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index bcf02617dc..fe591814e4 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -382,10 +382,10 @@ static void test_visitor_in_enum(TestInputVisitorData *data, Visitor *v; EnumOne i; - for (i = 0; EnumOne_lookup[i]; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { EnumOne res = -1; - v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]); + v = visitor_input_test_init(data, "%s", EnumOne_str(i)); visit_type_EnumOne(v, NULL, &res, &error_abort); g_assert_cmpint(i, ==, res); @@ -699,7 +699,7 @@ static void test_native_list_integer_helper(TestInputVisitorData *data, } } g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }", - UserDefNativeListUnionKind_lookup[kind], + UserDefNativeListUnionKind_str(kind), gstr_list->str); v = visitor_input_test_init_raw(data, gstr_union->str); @@ -1110,7 +1110,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, error_free_or_abort(&err); visit_optional(v, "optional", &present); g_assert(!present); - visit_type_enum(v, "enum", &en, EnumOne_lookup, &err); + visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err); error_free_or_abort(&err); visit_type_int(v, "i64", &i64, &err); error_free_or_abort(&err); diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 7eb162059c..d375100a52 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -133,7 +133,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, qstr = qobject_to_qstring(visitor_get(data)); g_assert(qstr); - g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_lookup[i]); + g_assert_cmpstr(qstring_get_str(qstr), ==, EnumOne_str(i)); visitor_reset(data); } } diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 79313a7f7a..4f9c36bef1 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -279,10 +279,10 @@ static void test_visitor_in_enum(TestInputVisitorData *data, Visitor *v; EnumOne i; - for (i = 0; EnumOne_lookup[i]; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { EnumOne res = -1; - v = visitor_input_test_init(data, EnumOne_lookup[i]); + v = visitor_input_test_init(data, EnumOne_str(i)); visit_type_EnumOne(v, NULL, &res, &err); g_assert(!err); diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index e736db3af8..385cddb5d9 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -194,12 +194,12 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, str = visitor_get(data); if (data->human) { - char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]); + char *str_human = g_strdup_printf("\"%s\"", EnumOne_str(i)); g_assert_cmpstr(str, ==, str_human); g_free(str_human); } else { - g_assert_cmpstr(str, ==, EnumOne_lookup[i]); + g_assert_cmpstr(str, ==, EnumOne_str(i)); } visitor_reset(data); } @@ -23,71 +23,28 @@ static QLIST_HEAD(, TPMBackend) tpm_backends = QLIST_HEAD_INITIALIZER(tpm_backends); +static TPMDriverOps const *be_drivers[TPM_TYPE__MAX]; +static bool tpm_models[TPM_MODEL__MAX]; -#define TPM_MAX_MODELS 1 -#define TPM_MAX_DRIVERS 1 - -static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = { - NULL, -}; - -static enum TpmModel tpm_models[TPM_MAX_MODELS] = { - TPM_MODEL__MAX, -}; - -int tpm_register_model(enum TpmModel model) +void tpm_register_model(enum TpmModel model) { - int i; - - for (i = 0; i < TPM_MAX_MODELS; i++) { - if (tpm_models[i] == TPM_MODEL__MAX) { - tpm_models[i] = model; - return 0; - } - } - error_report("Could not register TPM model"); - return 1; -} - -static bool tpm_model_is_registered(enum TpmModel model) -{ - int i; - - for (i = 0; i < TPM_MAX_MODELS; i++) { - if (tpm_models[i] == model) { - return true; - } - } - return false; + tpm_models[model] = true; } const TPMDriverOps *tpm_get_backend_driver(const char *type) { - int i; + int i = qapi_enum_parse(&TpmType_lookup, type, -1, NULL); - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { - if (!strcmp(TpmType_lookup[be_drivers[i]->type], type)) { - return be_drivers[i]; - } - } - - return NULL; + return i >= 0 ? be_drivers[i] : NULL; } #ifdef CONFIG_TPM -int tpm_register_driver(const TPMDriverOps *tdo) +void tpm_register_driver(const TPMDriverOps *tdo) { - int i; + assert(!be_drivers[tdo->type]); - for (i = 0; i < TPM_MAX_DRIVERS; i++) { - if (!be_drivers[i]) { - be_drivers[i] = tdo; - return 0; - } - } - error_report("Could not register TPM driver"); - return 1; + be_drivers[tdo->type] = tdo; } /* @@ -100,9 +57,12 @@ static void tpm_display_backend_drivers(void) fprintf(stderr, "Supported TPM types (choose only one):\n"); - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { + for (i = 0; i < TPM_TYPE__MAX; i++) { + if (be_drivers[i] == NULL) { + continue; + } fprintf(stderr, "%12s %s\n", - TpmType_lookup[be_drivers[i]->type], be_drivers[i]->desc()); + TpmType_str(i), be_drivers[i]->desc()); } fprintf(stderr, "\n"); } @@ -239,14 +199,7 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg) static const TPMDriverOps *tpm_driver_find_by_type(enum TpmType type) { - int i; - - for (i = 0; i < TPM_MAX_DRIVERS && be_drivers[i] != NULL; i++) { - if (be_drivers[i]->type == type) { - return be_drivers[i]; - } - } - return NULL; + return be_drivers[type]; } static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv) @@ -289,7 +242,7 @@ TPMInfoList *qmp_query_tpm(Error **errp) TPMInfoList *info, *head = NULL, *cur_item = NULL; QLIST_FOREACH(drv, &tpm_backends, list) { - if (!tpm_model_is_registered(drv->fe_model)) { + if (!tpm_models[drv->fe_model]) { continue; } info = g_new0(TPMInfoList, 1); @@ -336,7 +289,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp) TpmModelList *head = NULL, *prev = NULL, *cur_item; for (i = 0; i < TPM_MODEL__MAX; i++) { - if (!tpm_model_is_registered(i)) { + if (!tpm_models[i]) { continue; } cur_item = g_new0(TpmModelList, 1); diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 7159747404..6bc3525499 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -61,9 +61,9 @@ int index_from_key(const char *key, size_t key_length) { int i; - for (i = 0; QKeyCode_lookup[i] != NULL; i++) { - if (!strncmp(key, QKeyCode_lookup[i], key_length) && - !QKeyCode_lookup[i][key_length]) { + for (i = 0; i < Q_KEY_CODE__MAX; i++) { + if (!strncmp(key, QKeyCode_str(i), key_length) && + !QKeyCode_str(i)[key_length]) { break; } } diff --git a/ui/input.c b/ui/input.c index af05f06368..3422d4a8ef 100644 --- a/ui/input.c +++ b/ui/input.c @@ -151,7 +151,7 @@ void qmp_input_send_event(bool has_device, const char *device, if (!qemu_input_find_handler(1 << event->type, con)) { error_setg(errp, "Input handler not found for " "event type %s", - InputEventKind_lookup[event->type]); + InputEventKind_str(event->type)); return; } } @@ -213,12 +213,12 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) switch (key->key->type) { case KEY_VALUE_KIND_NUMBER: qcode = qemu_input_key_number_to_qcode(key->key->u.number.data); - name = QKeyCode_lookup[qcode]; + name = QKeyCode_str(qcode); trace_input_event_key_number(idx, key->key->u.number.data, name, key->down); break; case KEY_VALUE_KIND_QCODE: - name = QKeyCode_lookup[key->key->u.qcode.data]; + name = QKeyCode_str(key->key->u.qcode.data); trace_input_event_key_qcode(idx, name, key->down); break; case KEY_VALUE_KIND__MAX: @@ -228,17 +228,17 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) break; case INPUT_EVENT_KIND_BTN: btn = evt->u.btn.data; - name = InputButton_lookup[btn->button]; + name = InputButton_str(btn->button); trace_input_event_btn(idx, name, btn->down); break; case INPUT_EVENT_KIND_REL: move = evt->u.rel.data; - name = InputAxis_lookup[move->axis]; + name = InputAxis_str(move->axis); trace_input_event_rel(idx, name, move->value); break; case INPUT_EVENT_KIND_ABS: move = evt->u.abs.data; - name = InputAxis_lookup[move->axis]; + name = InputAxis_str(move->axis); trace_input_event_abs(idx, name, move->value); break; case INPUT_EVENT_KIND__MAX: @@ -131,7 +131,7 @@ static void vnc_init_basic_info(SocketAddress *addr, case SOCKET_ADDRESS_TYPE_VSOCK: case SOCKET_ADDRESS_TYPE_FD: error_setg(errp, "Unsupported socket address type %s", - SocketAddressType_lookup[addr->type]); + SocketAddressType_str(addr->type)); break; default: abort(); @@ -416,7 +416,7 @@ VncInfo *qmp_query_vnc(Error **errp) case SOCKET_ADDRESS_TYPE_VSOCK: case SOCKET_ADDRESS_TYPE_FD: error_setg(errp, "Unsupported socket address type %s", - SocketAddressType_lookup[addr->type]); + SocketAddressType_str(addr->type)); goto out_error; default: abort(); @@ -1839,7 +1839,7 @@ static void vnc_release_modifiers(VncState *vs) static const char *code2name(int keycode) { - return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)]; + return QKeyCode_str(qemu_input_key_number_to_qcode(keycode)); } static void key_event(VncState *vs, int down, uint32_t sym) diff --git a/util/keyval.c b/util/keyval.c index 7dbda62305..7dfc75cf01 100644 --- a/util/keyval.c +++ b/util/keyval.c @@ -82,7 +82,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/qmp/qstring.h" -#include "qapi/util.h" #include "qemu/cutils.h" #include "qemu/option.h" @@ -688,7 +688,7 @@ bool runstate_check(RunState state) bool runstate_store(char *str, size_t size) { - const char *state = RunState_lookup[current_run_state]; + const char *state = RunState_str(current_run_state); size_t len = strlen(state) + 1; if (len > size) { @@ -721,8 +721,8 @@ void runstate_set(RunState new_state) if (!runstate_valid_transitions[current_run_state][new_state]) { error_report("invalid runstate transition: '%s' -> '%s'", - RunState_lookup[current_run_state], - RunState_lookup[new_state]); + RunState_str(current_run_state), + RunState_str(new_state)); abort(); } trace_runstate_set(new_state); |