diff mbox

RFC: Full introspection support for QMP (with draft patch)

Message ID 20130607101230.GA32546@t430s.nay.redhat.com
State New
Headers show

Commit Message

Amos Kong June 7, 2013, 10:12 a.m. UTC
Sent out a draft patch in the end of this week. It doesn't support:
* output all stuffs in one shot.
* introspect event
* provide metadata date

How can we define a dynamic dict in qmp-schema.json ?

Currently I just output the raw json dict by a string, Libvirt needs
parse two times, convert the string to json format.

qmp-schema.h: auto generated head file by qapi script

Attached some examples.
* query-qmp-schema-no-param.txt
* query-qmp-schema-filter-by-name.txt
* query-qmp-schema-filter-all-command.txt
* query-qmp-schema-filter-all-type.txt
* query-qmp-schema-filter-all-enum.txt

-----

From 00fe59bde40a8beadf16196db9ed1bac5d862db0 Mon Sep 17 00:00:00 2001
From: Amos Kong <akong@redhat.com>
Date: Fri, 7 Jun 2013 18:02:21 +0800
Subject: [PATCH] full introspection support for QMP

Signed-off-by: Amos Kong <akong@redhat.com>
---
 qapi-schema.json         |  3 +++
 qmp-commands.hx          | 23 +++++++++++++++++++++++
 qmp.c                    | 36 ++++++++++++++++++++++++++++++++++++
 scripts/qapi-commands.py |  2 +-
 scripts/qapi-types.py    | 27 ++++++++++++++++++++++++++-
 scripts/qapi-visit.py    |  2 +-
 scripts/qapi.py          | 13 ++++++++++++-
 7 files changed, 102 insertions(+), 4 deletions(-)

Comments

Amos Kong June 7, 2013, 10:17 a.m. UTC | #1
On Fri, Jun 07, 2013 at 06:12:30PM +0800, Amos Kong wrote:
> Sent out a draft patch in the end of this week. It doesn't support:
> * output all stuffs in one shot.
> * introspect event
> * provide metadata date
> 
> How can we define a dynamic dict in qmp-schema.json ?
> 
> Currently I just output the raw json dict by a string, Libvirt needs
> parse two times, convert the string to json format.
> 
> qmp-schema.h: auto generated head file by qapi script
> 
> Attached some examples.
> * query-qmp-schema-no-param.txt
{'execute': 'query-qmp-schema'}

> * query-qmp-schema-filter-by-name.txt
{"execute": "query-qmp-schema", "arguments": { "name" : "query-name"}}

> * query-qmp-schema-filter-all-command.txt
{'execute': 'query-qmp-schema', 'arguments': {'type': 'command'}}

> * query-qmp-schema-filter-all-type.txt
{'execute': 'query-qmp-schema', 'arguments': {'type': 'type'}}

> * query-qmp-schema-filter-all-enum.txt
{'execute': 'query-qmp-schema', 'arguments': { 'type': 'enum'}}
{'execute': 'query-qmp-schema'}
{
    "return": [
        "{ 'enum': 'ErrorClass',  'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',  'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }", 
        "{ 'command': 'add_client',  'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',  '*tls': 'bool' } }", 
        "{ 'type': 'NameInfo', 'data': {'*name': 'str'} }", 
        "{ 'command': 'query-name', 'returns': 'NameInfo' }", 
        "{ 'type': 'VersionInfo',  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},  'package': 'str'} }", 
        "{ 'command': 'query-version', 'returns': 'VersionInfo' }", 
        "{ 'type': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }", 
        "{ 'command': 'query-kvm', 'returns': 'KvmInfo' }", 
        "{ 'enum': 'RunState',  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',  'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',  'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',  'guest-panicked' ] }", 
        "{ 'type': 'SnapshotInfo',  'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int',  'date-sec': 'int', 'date-nsec': 'int',  'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }", 
        "{ 'type': 'ImageInfo',  'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',  '*actual-size': 'int', 'virtual-size': 'int',  '*cluster-size': 'int', '*encrypted': 'bool',  '*backing-filename': 'str', '*full-backing-filename': 'str',  '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'] } }", 
        "{ 'type': 'ImageCheck',  'data': {'filename': 'str', 'format': 'str', 'check-errors': 'int',  '*image-end-offset': 'int', '*corruptions': 'int', '*leaks': 'int',  '*corruptions-fixed': 'int', '*leaks-fixed': 'int',  '*total-clusters': 'int', '*allocated-clusters': 'int',  '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }", 
        "{ 'type': 'StatusInfo',  'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }", 
        "{ 'command': 'query-status', 'returns': 'StatusInfo' }", 
        "{ 'type': 'UuidInfo', 'data': {'UUID': 'str'} }", 
        "{ 'command': 'query-uuid', 'returns': 'UuidInfo' }", 
        "{ 'type': 'ChardevInfo', 'data': {'label': 'str', 'filename': 'str'} }", 
        "{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] }", 
        "{ 'enum': 'DataFormat'  'data': [ 'utf8', 'base64' ] }", 
        "{ 'command': 'ringbuf-write',  'data': {'device': 'str', 'data': 'str',  '*format': 'DataFormat'} }", 
        "{ 'command': 'ringbuf-read',  'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},  'returns': 'str' }", 
        "{ 'type': 'CommandInfo', 'data': {'name': 'str'} }", 
        "{ 'command': 'query-commands', 'returns': ['CommandInfo'] }", 
        "{ 'type': 'EventInfo', 'data': {'name': 'str'} }", 
        "{ 'command': 'query-events', 'returns': ['EventInfo'] }", 
        "{ 'type': 'MigrationStats',  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,  'duplicate': 'int', 'skipped': 'int', 'normal': 'int',  'normal-bytes': 'int', 'dirty-pages-rate' : 'int' } }", 
        "{ 'type': 'XBZRLECacheStats',  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',  'cache-miss': 'int', 'overflow': 'int' } }", 
        "{ 'type': 'MigrationInfo',  'data': {'*status': 'str', '*ram': 'MigrationStats',  '*disk': 'MigrationStats',  '*xbzrle-cache': 'XBZRLECacheStats',  '*total-time': 'int',  '*expected-downtime': 'int',  '*downtime': 'int'} }", 
        "{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }", 
        "{ 'enum': 'MigrationCapability',  'data': ['xbzrle'] }", 
        "{ 'type': 'MigrationCapabilityStatus',  'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }", 
        "{ 'command': 'migrate-set-capabilities',  'data': { 'capabilities': ['MigrationCapabilityStatus'] } }", 
        "{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}", 
        "{ 'type': 'MouseInfo',  'data': {'name': 'str', 'index': 'int', 'current': 'bool',  'absolute': 'bool'} }", 
        "{ 'command': 'query-mice', 'returns': ['MouseInfo'] }", 
        "{ 'type': 'CpuInfo',  'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', '*pc': 'int',  '*nip': 'int', '*npc': 'int', '*PC': 'int', 'thread_id': 'int'} }", 
        "{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }", 
        "{ 'type': 'BlockDeviceInfo',  'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',  '*backing_file': 'str', 'backing_file_depth': 'int',  'encrypted': 'bool', 'encryption_key_missing': 'bool',  'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',  'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }", 
        "{ 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }", 
        "{ 'type': 'BlockDirtyInfo',  'data': {'count': 'int', 'granularity': 'int'} }", 
        "{ 'type': 'BlockInfo',  'data': {'device': 'str', 'type': 'str', 'removable': 'bool',  'locked': 'bool', '*inserted': 'BlockDeviceInfo',  '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',  '*dirty': 'BlockDirtyInfo' } }", 
        "{ 'command': 'query-block', 'returns': ['BlockInfo'] }", 
        "{ 'type': 'BlockDeviceStats',  'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',  'wr_operations': 'int', 'flush_operations': 'int',  'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',  'rd_total_time_ns': 'int', 'wr_highest_offset': 'int' } }", 
        "{ 'type': 'BlockStats',  'data': {'*device': 'str', 'stats': 'BlockDeviceStats',  '*parent': 'BlockStats'} }", 
        "{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }", 
        "{ 'type': 'VncClientInfo',  'data': {'host': 'str', 'family': 'str', 'service': 'str',  '*x509_dname': 'str', '*sasl_username': 'str'} }", 
        "{ 'type': 'VncInfo',  'data': {'enabled': 'bool', '*host': 'str', '*family': 'str',  '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }", 
        "{ 'command': 'query-vnc', 'returns': 'VncInfo' }", 
        "{ 'type': 'SpiceChannel',  'data': {'host': 'str', 'family': 'str', 'port': 'str',  'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',  'tls': 'bool'} }", 
        "{ 'enum': 'SpiceQueryMouseMode',  'data': [ 'client', 'server', 'unknown' ] }", 
        "{ 'type': 'SpiceInfo',  'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',  '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',  'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }", 
        "{ 'command': 'query-spice', 'returns': 'SpiceInfo' }", 
        "{ 'type': 'BalloonInfo', 'data': {'actual': 'int' } }", 
        "{ 'command': 'query-balloon', 'returns': 'BalloonInfo' }", 
        "{ 'type': 'PciMemoryRange', 'data': {'base': 'int', 'limit': 'int'} }", 
        "{ 'type': 'PciMemoryRegion',  'data': {'bar': 'int', 'type': 'str', 'address': 'int', 'size': 'int',  '*prefetch': 'bool', '*mem_type_64': 'bool' } }", 
        "{ 'type': 'PciBridgeInfo',  'data': {'bus': { 'number': 'int', 'secondary': 'int', 'subordinate': 'int',  'io_range': 'PciMemoryRange',  'memory_range': 'PciMemoryRange',  'prefetchable_range': 'PciMemoryRange' },  '*devices': ['PciDeviceInfo']} }", 
        "{ 'type': 'PciDeviceInfo',  'data': {'bus': 'int', 'slot': 'int', 'function': 'int',  'class_info': {'*desc': 'str', 'class': 'int'},  'id': {'device': 'int', 'vendor': 'int'},  '*irq': 'int', 'qdev_id': 'str', '*pci_bridge': 'PciBridgeInfo',  'regions': ['PciMemoryRegion']} }", 
        "{ 'type': 'PciInfo', 'data': {'bus': 'int', 'devices': ['PciDeviceInfo']} }", 
        "{ 'command': 'query-pci', 'returns': ['PciInfo'] }", 
        "{ 'enum': 'BlockdevOnError',  'data': ['report', 'ignore', 'enospc', 'stop'] }", 
        "{ 'enum': 'MirrorSyncMode',  'data': ['top', 'full', 'none'] }", 
        "{ 'type': 'BlockJobInfo',  'data': {'type': 'str', 'device': 'str', 'len': 'int',  'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',  'io-status': 'BlockDeviceIoStatus'} }", 
        "{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }", 
        "{ 'command': 'quit' }", 
        "{ 'command': 'stop' }", 
        "{ 'command': 'system_reset' }", 
        "{ 'command': 'system_powerdown' }", 
        "{ 'command': 'cpu', 'data': {'index': 'int'} }", 
        "{ 'command': 'cpu-add', 'data': {'id': 'int'} }", 
        "{ 'command': 'memsave',  'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }", 
        "{ 'command': 'pmemsave',  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }", 
        "{ 'command': 'cont' }", 
        "{ 'command': 'system_wakeup' }", 
        "{ 'command': 'inject-nmi' }", 
        "{ 'command': 'set_link', 'data': {'name': 'str', 'up': 'bool'} }", 
        "{ 'command': 'block_passwd', 'data': {'device': 'str', 'password': 'str'} }", 
        "{ 'command': 'balloon', 'data': {'value': 'int'} }", 
        "{ 'command': 'block_resize', 'data': { 'device': 'str', 'size': 'int' }}", 
        "{ 'enum': 'NewImageMode'  'data': [ 'existing', 'absolute-paths' ] }", 
        "{ 'type': 'BlockdevSnapshot',  'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str',  '*mode': 'NewImageMode' } }", 
        "{ 'union': 'TransactionAction',  'data': {  'blockdev-snapshot-sync': 'BlockdevSnapshot'  } }", 
        "{ 'command': 'transaction',  'data': { 'actions': [ 'TransactionAction' ] } }", 
        "{ 'command': 'blockdev-snapshot-sync',  'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str',  '*mode': 'NewImageMode'} }", 
        "{ 'command': 'human-monitor-command',  'data': {'command-line': 'str', '*cpu-index': 'int'},  'returns': 'str' }", 
        "{ 'command': 'block-commit',  'data': { 'device': 'str', '*base': 'str', 'top': 'str',  '*speed': 'int' } }", 
        "{ 'command': 'drive-mirror',  'data': { 'device': 'str', 'target': 'str', '*format': 'str',  'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',  '*speed': 'int', '*granularity': 'uint32',  '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',  '*on-target-error': 'BlockdevOnError' } }", 
        "{ 'command': 'migrate_cancel' }", 
        "{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }", 
        "{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }", 
        "{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }", 
        "{ 'command': 'query-migrate-cache-size', 'returns': 'int' }", 
        "{ 'type': 'ObjectPropertyInfo',  'data': { 'name': 'str', 'type': 'str' } }", 
        "{ 'command': 'qom-list',  'data': { 'path': 'str' },  'returns': [ 'ObjectPropertyInfo' ] }", 
        "{ 'command': 'qom-get',  'data': { 'path': 'str', 'property': 'str' },  'returns': 'visitor',  'gen': 'no' }", 
        "{ 'command': 'qom-set',  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },  'gen': 'no' }", 
        "{ 'command': 'set_password',  'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }", 
        "{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }", 
        "{ 'command': 'eject', 'data': {'device': 'str', '*force': 'bool'} }", 
        "{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }", 
        "{ 'command': 'change',  'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }", 
        "{ 'command': 'block_set_io_throttle',  'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',  'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int' } }", 
        "{ 'command': 'block-stream',  'data': { 'device': 'str', '*base': 'str', '*speed': 'int',  '*on-error': 'BlockdevOnError' } }", 
        "{ 'command': 'block-job-set-speed',  'data': { 'device': 'str', 'speed': 'int' } }", 
        "{ 'command': 'block-job-cancel', 'data': { 'device': 'str', '*force': 'bool' } }", 
        "{ 'command': 'block-job-pause', 'data': { 'device': 'str' } }", 
        "{ 'command': 'block-job-resume', 'data': { 'device': 'str' } }", 
        "{ 'command': 'block-job-complete', 'data': { 'device': 'str' } }", 
        "{ 'type': 'ObjectTypeInfo',  'data': { 'name': 'str' } }", 
        "{ 'command': 'qom-list-types',  'data': { '*implements': 'str', '*abstract': 'bool' },  'returns': [ 'ObjectTypeInfo' ] }", 
        "{ 'type': 'DevicePropertyInfo',  'data': { 'name': 'str', 'type': 'str' } }", 
        "{ 'command': 'device-list-properties',  'data': { 'typename': 'str'},  'returns': [ 'DevicePropertyInfo' ] }", 
        "{ 'command': 'migrate',  'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } }", 
        "{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }", 
        "{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }", 
        "{ 'command': 'device_del', 'data': {'id': 'str'} }", 
        "{ 'command': 'dump-guest-memory',  'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',  '*length': 'int' } }", 
        "{ 'command': 'netdev_add',  'data': {'type': 'str', 'id': 'str', '*props': '**'},  'gen': 'no' }", 
        "{ 'command': 'netdev_del', 'data': {'id': 'str'} }", 
        "{ 'type': 'NetdevNoneOptions',  'data': { } }", 
        "{ 'type': 'NetLegacyNicOptions',  'data': {  '*netdev': 'str',  '*macaddr': 'str',  '*model': 'str',  '*addr': 'str',  '*vectors': 'uint32' } }", 
        "{ 'type': 'String',  'data': {  'str': 'str' } }", 
        "{ 'type': 'NetdevUserOptions',  'data': {  '*hostname': 'str',  '*restrict': 'bool',  '*ip': 'str',  '*net': 'str',  '*host': 'str',  '*tftp': 'str',  '*bootfile': 'str',  '*dhcpstart': 'str',  '*dns': 'str',  '*dnssearch': ['String'],  '*smb': 'str',  '*smbserver': 'str',  '*hostfwd': ['String'],  '*guestfwd': ['String'] } }", 
        "{ 'type': 'NetdevTapOptions',  'data': {  '*ifname': 'str',  '*fd': 'str',  '*fds': 'str',  '*script': 'str',  '*downscript': 'str',  '*helper': 'str',  '*sndbuf': 'size',  '*vnet_hdr': 'bool',  '*vhost': 'bool',  '*vhostfd': 'str',  '*vhostfds': 'str',  '*vhostforce': 'bool',  '*queues': 'uint32'} }", 
        "{ 'type': 'NetdevSocketOptions',  'data': {  '*fd': 'str',  '*listen': 'str',  '*connect': 'str',  '*mcast': 'str',  '*localaddr': 'str',  '*udp': 'str' } }", 
        "{ 'type': 'NetdevVdeOptions',  'data': {  '*sock': 'str',  '*port': 'uint16',  '*group': 'str',  '*mode': 'uint16' } }", 
        "{ 'type': 'NetdevDumpOptions',  'data': {  '*len': 'size',  '*file': 'str' } }", 
        "{ 'type': 'NetdevBridgeOptions',  'data': {  '*br': 'str',  '*helper': 'str' } }", 
        "{ 'type': 'NetdevHubPortOptions',  'data': {  'hubid': 'int32' } }", 
        "{ 'union': 'NetClientOptions',  'data': {  'none': 'NetdevNoneOptions',  'nic': 'NetLegacyNicOptions',  'user': 'NetdevUserOptions',  'tap': 'NetdevTapOptions',  'socket': 'NetdevSocketOptions',  'vde': 'NetdevVdeOptions',  'dump': 'NetdevDumpOptions',  'bridge': 'NetdevBridgeOptions',  'hubport': 'NetdevHubPortOptions' } }", 
        "{ 'type': 'NetLegacy',  'data': {  '*vlan': 'int32',  '*id': 'str',  '*name': 'str',  'opts': 'NetClientOptions' } }", 
        "{ 'type': 'Netdev',  'data': {  'id': 'str',  'opts': 'NetClientOptions' } }", 
        "{ 'type': 'InetSocketAddress',  'data': {  'host': 'str',  'port': 'str',  '*to': 'uint16',  '*ipv4': 'bool',  '*ipv6': 'bool' } }", 
        "{ 'type': 'UnixSocketAddress',  'data': {  'path': 'str' } }", 
        "{ 'union': 'SocketAddress',  'data': {  'inet': 'InetSocketAddress',  'unix': 'UnixSocketAddress',  'fd': 'String' } }", 
        "{ 'command': 'getfd', 'data': {'fdname': 'str'} }", 
        "{ 'command': 'closefd', 'data': {'fdname': 'str'} }", 
        "{ 'command': 'query-machines', 'returns': ['MachineInfo'] }", 
        "{ 'type': 'CpuDefinitionInfo',  'data': { 'name': 'str' } }", 
        "{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }", 
        "{ 'type': 'AddfdInfo', 'data': {'fdset-id': 'int', 'fd': 'int'} }", 
        "{ 'command': 'add-fd', 'data': {'*fdset-id': 'int', '*opaque': 'str'},  'returns': 'AddfdInfo' }", 
        "{ 'command': 'remove-fd', 'data': {'fdset-id': 'int', '*fd': 'int'} }", 
        "{ 'type': 'FdsetFdInfo',  'data': {'fd': 'int', '*opaque': 'str'} }", 
        "{ 'type': 'FdsetInfo',  'data': {'fdset-id': 'int', 'fds': ['FdsetFdInfo']} }", 
        "{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }", 
        "{ 'enum': 'TargetType',  'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',  'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'moxie',  'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4',  'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }", 
        "{ 'type': 'TargetInfo',  'data': { 'arch': 'TargetType' } }", 
        "{ 'command': 'query-target', 'returns': 'TargetInfo' }", 
        "{ 'enum': 'QKeyCode',  'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_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' ] }", 
        "{ 'union': 'KeyValue',  'data': {  'number': 'int',  'qcode': 'QKeyCode' } }", 
        "{ 'command': 'send-key',  'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }", 
        "{ 'command': 'screendump', 'data': {'filename': 'str'} }", 
        "{ 'command': 'nbd-server-start',  'data': { 'addr': 'SocketAddress' } }", 
        "{ 'command': 'nbd-server-add', 'data': {'device': 'str', '*writable': 'bool'} }", 
        "{ 'command': 'nbd-server-stop' }", 
        "{ 'type': 'ChardevFile', 'data': { '*in' : 'str',  'out' : 'str' } }", 
        "{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } }", 
        "{ 'type': 'ChardevSocket', 'data': { 'addr' : 'SocketAddress',  '*server' : 'bool',  '*wait' : 'bool',  '*nodelay' : 'bool',  '*telnet' : 'bool' } }", 
        "{ 'type': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',  '*local' : 'SocketAddress' } }", 
        "{ 'type': 'ChardevMux', 'data': { 'chardev' : 'str' } }", 
        "{ 'type': 'ChardevStdio', 'data': { '*signal' : 'bool' } }", 
        "{ 'type': 'ChardevSpiceChannel', 'data': { 'type' : 'str' } }", 
        "{ 'type': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' } }", 
        "{ 'type': 'ChardevVC', 'data': { '*width' : 'int',  '*height' : 'int',  '*cols' : 'int',  '*rows' : 'int' } }", 
        "{ 'type': 'ChardevMemory', 'data': { '*size' : 'int' } }", 
        "{ 'type': 'ChardevDummy', 'data': { } }", 
        "{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile',  'serial' : 'ChardevHostdev',  'parallel': 'ChardevHostdev',  'pipe' : 'ChardevHostdev',  'socket' : 'ChardevSocket',  'udp' : 'ChardevUdp',  'pty' : 'ChardevDummy',  'null' : 'ChardevDummy',  'mux' : 'ChardevMux',  'msmouse': 'ChardevDummy',  'braille': 'ChardevDummy',  'stdio' : 'ChardevStdio',  'console': 'ChardevDummy',  'spicevmc' : 'ChardevSpiceChannel',  'spiceport' : 'ChardevSpicePort',  'vc' : 'ChardevVC',  'memory' : 'ChardevMemory' } }", 
        "{ 'type' : 'ChardevReturn', 'data': { '*pty' : 'str' } }", 
        "{ 'command': 'chardev-add', 'data': {'id' : 'str',  'backend' : 'ChardevBackend' },  'returns': 'ChardevReturn' }", 
        "{ 'command': 'chardev-remove', 'data': {'id': 'str'} }", 
        "{ 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] }", 
        "{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] }", 
        "{ 'enum': 'TpmType', 'data': [ 'passthrough' ] }", 
        "{ 'command': 'query-tpm-types', 'returns': ['TpmType'] }", 
        "{ 'type': 'TPMPassthroughOptions', 'data': { '*path' : 'str',  '*cancel-path' : 'str'} }", 
        "{ 'union': 'TpmTypeOptions',  'data': { 'passthrough' : 'TPMPassthroughOptions' } }", 
        "{ 'type': 'TPMInfo',  'data': {'id': 'str',  'model': 'TpmModel',  'options': 'TpmTypeOptions' } }", 
        "{ 'command': 'query-tpm', 'returns': ['TPMInfo'] }", 
        "{ 'type': 'AcpiTableOptions',  'data': {  '*sig': 'str',  '*rev': 'uint8',  '*oem_id': 'str',  '*oem_table_id': 'str',  '*oem_rev': 'uint32',  '*asl_compiler_id': 'str',  '*asl_compiler_rev': 'uint32',  '*file': 'str',  '*data': 'str' }}", 
        "{ 'enum': 'CommandLineParameterType',  'data': ['string', 'boolean', 'number', 'size'] }", 
        "{ 'type': 'CommandLineParameterInfo',  'data': { 'name': 'str',  'type': 'CommandLineParameterType',  '*help': 'str' } }", 
        "{ 'type': 'CommandLineOptionInfo',  'data': { 'option': 'str', 'parameters': ['CommandLineParameterInfo'] } }", 
        "{'command': 'query-command-line-options', 'data': { '*option': 'str' },  'returns': ['CommandLineOptionInfo'] }", 
        "{ 'enum': 'X86CPURegister32',  'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }", 
        "{ 'type': 'X86CPUFeatureWordInfo',  'data': { 'cpuid-input-eax': 'int',  '*cpuid-input-ecx': 'int',  'cpuid-register': 'X86CPURegister32',  'features': 'int' } }", 
        "{ 'command': 'query-qmp-schema', 'data': { '*type': 'str', '*name': 'str' },  'returns': ['str'] }"
    ]
}
{"execute": "query-qmp-schema", "arguments": { "name" : "query-name" }}
{
    "return": [
        "{ 'command': 'query-name', 'returns': 'NameInfo' }"
    ]
}
{'execute': 'query-qmp-schema', 'arguments': {'type': 'command'}}
{
    "return": [
        "{ 'command': 'add_client',  'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',  '*tls': 'bool' } }", 
        "{ 'command': 'query-name', 'returns': 'NameInfo' }", 
        "{ 'command': 'query-version', 'returns': 'VersionInfo' }", 
        "{ 'command': 'query-kvm', 'returns': 'KvmInfo' }", 
        "{ 'command': 'query-status', 'returns': 'StatusInfo' }", 
        "{ 'command': 'query-uuid', 'returns': 'UuidInfo' }", 
        "{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] }", 
        "{ 'command': 'ringbuf-write',  'data': {'device': 'str', 'data': 'str',  '*format': 'DataFormat'} }", 
        "{ 'command': 'ringbuf-read',  'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},  'returns': 'str' }", 
        "{ 'command': 'query-commands', 'returns': ['CommandInfo'] }", 
        "{ 'command': 'query-events', 'returns': ['EventInfo'] }", 
        "{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }", 
        "{ 'command': 'migrate-set-capabilities',  'data': { 'capabilities': ['MigrationCapabilityStatus'] } }", 
        "{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}", 
        "{ 'command': 'query-mice', 'returns': ['MouseInfo'] }", 
        "{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }", 
        "{ 'command': 'query-block', 'returns': ['BlockInfo'] }", 
        "{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }", 
        "{ 'command': 'query-vnc', 'returns': 'VncInfo' }", 
        "{ 'command': 'query-spice', 'returns': 'SpiceInfo' }", 
        "{ 'command': 'query-balloon', 'returns': 'BalloonInfo' }", 
        "{ 'command': 'query-pci', 'returns': ['PciInfo'] }", 
        "{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }", 
        "{ 'command': 'quit' }", 
        "{ 'command': 'stop' }", 
        "{ 'command': 'system_reset' }", 
        "{ 'command': 'system_powerdown' }", 
        "{ 'command': 'cpu', 'data': {'index': 'int'} }", 
        "{ 'command': 'cpu-add', 'data': {'id': 'int'} }", 
        "{ 'command': 'memsave',  'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }", 
        "{ 'command': 'pmemsave',  'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }", 
        "{ 'command': 'cont' }", 
        "{ 'command': 'system_wakeup' }", 
        "{ 'command': 'inject-nmi' }", 
        "{ 'command': 'block_passwd', 'data': {'device': 'str', 'password': 'str'} }", 
        "{ 'command': 'balloon', 'data': {'value': 'int'} }", 
        "{ 'command': 'block_resize', 'data': { 'device': 'str', 'size': 'int' }}", 
        "{ 'command': 'transaction',  'data': { 'actions': [ 'TransactionAction' ] } }", 
        "{ 'command': 'blockdev-snapshot-sync',  'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str',  '*mode': 'NewImageMode'} }", 
        "{ 'command': 'human-monitor-command',  'data': {'command-line': 'str', '*cpu-index': 'int'},  'returns': 'str' }", 
        "{ 'command': 'block-commit',  'data': { 'device': 'str', '*base': 'str', 'top': 'str',  '*speed': 'int' } }", 
        "{ 'command': 'drive-mirror',  'data': { 'device': 'str', 'target': 'str', '*format': 'str',  'sync': 'MirrorSyncMode', '*mode': 'NewImageMode',  '*speed': 'int', '*granularity': 'uint32',  '*buf-size': 'int', '*on-source-error': 'BlockdevOnError',  '*on-target-error': 'BlockdevOnError' } }", 
        "{ 'command': 'migrate_cancel' }", 
        "{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }", 
        "{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }", 
        "{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }", 
        "{ 'command': 'query-migrate-cache-size', 'returns': 'int' }", 
        "{ 'command': 'qom-list',  'data': { 'path': 'str' },  'returns': [ 'ObjectPropertyInfo' ] }", 
        "{ 'command': 'qom-get',  'data': { 'path': 'str', 'property': 'str' },  'returns': 'visitor',  'gen': 'no' }", 
        "{ 'command': 'qom-set',  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },  'gen': 'no' }", 
        "{ 'command': 'set_password',  'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }", 
        "{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }", 
        "{ 'command': 'eject', 'data': {'device': 'str', '*force': 'bool'} }", 
        "{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }", 
        "{ 'command': 'change',  'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }", 
        "{ 'command': 'block_set_io_throttle',  'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',  'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int' } }", 
        "{ 'command': 'block-stream',  'data': { 'device': 'str', '*base': 'str', '*speed': 'int',  '*on-error': 'BlockdevOnError' } }", 
        "{ 'command': 'block-job-set-speed',  'data': { 'device': 'str', 'speed': 'int' } }", 
        "{ 'command': 'block-job-cancel', 'data': { 'device': 'str', '*force': 'bool' } }", 
        "{ 'command': 'block-job-pause', 'data': { 'device': 'str' } }", 
        "{ 'command': 'block-job-resume', 'data': { 'device': 'str' } }", 
        "{ 'command': 'block-job-complete', 'data': { 'device': 'str' } }", 
        "{ 'command': 'qom-list-types',  'data': { '*implements': 'str', '*abstract': 'bool' },  'returns': [ 'ObjectTypeInfo' ] }", 
        "{ 'command': 'device-list-properties',  'data': { 'typename': 'str'},  'returns': [ 'DevicePropertyInfo' ] }", 
        "{ 'command': 'migrate',  'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } }", 
        "{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }", 
        "{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }", 
        "{ 'command': 'device_del', 'data': {'id': 'str'} }", 
        "{ 'command': 'dump-guest-memory',  'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',  '*length': 'int' } }", 
        "{ 'command': 'netdev_add',  'data': {'type': 'str', 'id': 'str', '*props': '**'},  'gen': 'no' }", 
        "{ 'command': 'netdev_del', 'data': {'id': 'str'} }", 
        "{ 'command': 'getfd', 'data': {'fdname': 'str'} }", 
        "{ 'command': 'closefd', 'data': {'fdname': 'str'} }", 
        "{ 'command': 'query-machines', 'returns': ['MachineInfo'] }", 
        "{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }", 
        "{ 'command': 'add-fd', 'data': {'*fdset-id': 'int', '*opaque': 'str'},  'returns': 'AddfdInfo' }", 
        "{ 'command': 'remove-fd', 'data': {'fdset-id': 'int', '*fd': 'int'} }", 
        "{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }", 
        "{ 'command': 'query-target', 'returns': 'TargetInfo' }", 
        "{ 'command': 'send-key',  'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }", 
        "{ 'command': 'screendump', 'data': {'filename': 'str'} }", 
        "{ 'command': 'nbd-server-start',  'data': { 'addr': 'SocketAddress' } }", 
        "{ 'command': 'nbd-server-add', 'data': {'device': 'str', '*writable': 'bool'} }", 
        "{ 'command': 'nbd-server-stop' }", 
        "{ 'command': 'chardev-add', 'data': {'id' : 'str',  'backend' : 'ChardevBackend' },  'returns': 'ChardevReturn' }", 
        "{ 'command': 'chardev-remove', 'data': {'id': 'str'} }", 
        "{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] }", 
        "{ 'command': 'query-tpm-types', 'returns': ['TpmType'] }", 
        "{ 'command': 'query-tpm', 'returns': ['TPMInfo'] }", 
        "{'command': 'query-command-line-options', 'data': { '*option': 'str' },  'returns': ['CommandLineOptionInfo'] }", 
        "{ 'command': 'query-qmp-schema', 'data': { '*type': 'str', '*name': 'str' },  'returns': ['str'] }"
    ]
}
{'execute': 'query-qmp-schema', 'arguments': { 'type': 'enum'}}
{
    "return": [
        "{ 'enum': 'ErrorClass',  'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',  'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }", 
        "{ 'enum': 'RunState',  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',  'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',  'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',  'guest-panicked' ] }", 
        "{ 'enum': 'DataFormat'  'data': [ 'utf8', 'base64' ] }", 
        "{ 'enum': 'MigrationCapability',  'data': ['xbzrle'] }", 
        "{ 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }", 
        "{ 'enum': 'SpiceQueryMouseMode',  'data': [ 'client', 'server', 'unknown' ] }", 
        "{ 'enum': 'BlockdevOnError',  'data': ['report', 'ignore', 'enospc', 'stop'] }", 
        "{ 'enum': 'MirrorSyncMode',  'data': ['top', 'full', 'none'] }", 
        "{ 'enum': 'NewImageMode'  'data': [ 'existing', 'absolute-paths' ] }", 
        "{ 'enum': 'TargetType',  'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',  'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'moxie',  'or32', 'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4',  'sparc64', 'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }", 
        "{ 'enum': 'QKeyCode',  'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_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' ] }", 
        "{ 'enum': 'TpmModel', 'data': [ 'tpm-tis' ] }", 
        "{ 'enum': 'TpmType', 'data': [ 'passthrough' ] }", 
        "{ 'enum': 'CommandLineParameterType',  'data': ['string', 'boolean', 'number', 'size'] }", 
        "{ 'enum': 'X86CPURegister32',  'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }"
    ]
}
{'execute': 'query-qmp-schema', 'arguments': {'type': 'type'}}
{
    "return": [
        "{ 'type': 'NameInfo', 'data': {'*name': 'str'} }", 
        "{ 'type': 'VersionInfo',  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},  'package': 'str'} }", 
        "{ 'type': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }", 
        "{ 'type': 'SnapshotInfo',  'data': { 'id': 'str', 'name': 'str', 'vm-state-size': 'int',  'date-sec': 'int', 'date-nsec': 'int',  'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } }", 
        "{ 'type': 'ImageInfo',  'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',  '*actual-size': 'int', 'virtual-size': 'int',  '*cluster-size': 'int', '*encrypted': 'bool',  '*backing-filename': 'str', '*full-backing-filename': 'str',  '*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'] } }", 
        "{ 'type': 'ImageCheck',  'data': {'filename': 'str', 'format': 'str', 'check-errors': 'int',  '*image-end-offset': 'int', '*corruptions': 'int', '*leaks': 'int',  '*corruptions-fixed': 'int', '*leaks-fixed': 'int',  '*total-clusters': 'int', '*allocated-clusters': 'int',  '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }", 
        "{ 'type': 'StatusInfo',  'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }", 
        "{ 'type': 'UuidInfo', 'data': {'UUID': 'str'} }", 
        "{ 'type': 'ChardevInfo', 'data': {'label': 'str', 'filename': 'str'} }", 
        "{ 'type': 'CommandInfo', 'data': {'name': 'str'} }", 
        "{ 'type': 'EventInfo', 'data': {'name': 'str'} }", 
        "{ 'type': 'MigrationStats',  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,  'duplicate': 'int', 'skipped': 'int', 'normal': 'int',  'normal-bytes': 'int', 'dirty-pages-rate' : 'int' } }", 
        "{ 'type': 'XBZRLECacheStats',  'data': {'cache-size': 'int', 'bytes': 'int', 'pages': 'int',  'cache-miss': 'int', 'overflow': 'int' } }", 
        "{ 'type': 'MigrationInfo',  'data': {'*status': 'str', '*ram': 'MigrationStats',  '*disk': 'MigrationStats',  '*xbzrle-cache': 'XBZRLECacheStats',  '*total-time': 'int',  '*expected-downtime': 'int',  '*downtime': 'int'} }", 
        "{ 'type': 'MigrationCapabilityStatus',  'data': { 'capability' : 'MigrationCapability', 'state' : 'bool' } }", 
        "{ 'type': 'MouseInfo',  'data': {'name': 'str', 'index': 'int', 'current': 'bool',  'absolute': 'bool'} }", 
        "{ 'type': 'CpuInfo',  'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', '*pc': 'int',  '*nip': 'int', '*npc': 'int', '*PC': 'int', 'thread_id': 'int'} }", 
        "{ 'type': 'BlockDeviceInfo',  'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',  '*backing_file': 'str', 'backing_file_depth': 'int',  'encrypted': 'bool', 'encryption_key_missing': 'bool',  'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',  'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }", 
        "{ 'type': 'BlockDirtyInfo',  'data': {'count': 'int', 'granularity': 'int'} }", 
        "{ 'type': 'BlockInfo',  'data': {'device': 'str', 'type': 'str', 'removable': 'bool',  'locked': 'bool', '*inserted': 'BlockDeviceInfo',  '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',  '*dirty': 'BlockDirtyInfo' } }", 
        "{ 'type': 'BlockDeviceStats',  'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',  'wr_operations': 'int', 'flush_operations': 'int',  'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',  'rd_total_time_ns': 'int', 'wr_highest_offset': 'int' } }", 
        "{ 'type': 'BlockStats',  'data': {'*device': 'str', 'stats': 'BlockDeviceStats',  '*parent': 'BlockStats'} }", 
        "{ 'type': 'VncClientInfo',  'data': {'host': 'str', 'family': 'str', 'service': 'str',  '*x509_dname': 'str', '*sasl_username': 'str'} }", 
        "{ 'type': 'SpiceChannel',  'data': {'host': 'str', 'family': 'str', 'port': 'str',  'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',  'tls': 'bool'} }", 
        "{ 'type': 'SpiceInfo',  'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',  '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',  'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }", 
        "{ 'type': 'BalloonInfo', 'data': {'actual': 'int' } }", 
        "{ 'type': 'PciMemoryRange', 'data': {'base': 'int', 'limit': 'int'} }", 
        "{ 'type': 'PciMemoryRegion',  'data': {'bar': 'int', 'type': 'str', 'address': 'int', 'size': 'int',  '*prefetch': 'bool', '*mem_type_64': 'bool' } }", 
        "{ 'type': 'PciBridgeInfo',  'data': {'bus': { 'number': 'int', 'secondary': 'int', 'subordinate': 'int',  'io_range': 'PciMemoryRange',  'memory_range': 'PciMemoryRange',  'prefetchable_range': 'PciMemoryRange' },  '*devices': ['PciDeviceInfo']} }", 
        "{ 'type': 'PciDeviceInfo',  'data': {'bus': 'int', 'slot': 'int', 'function': 'int',  'class_info': {'*desc': 'str', 'class': 'int'},  'id': {'device': 'int', 'vendor': 'int'},  '*irq': 'int', 'qdev_id': 'str', '*pci_bridge': 'PciBridgeInfo',  'regions': ['PciMemoryRegion']} }", 
        "{ 'type': 'PciInfo', 'data': {'bus': 'int', 'devices': ['PciDeviceInfo']} }", 
        "{ 'type': 'BlockJobInfo',  'data': {'type': 'str', 'device': 'str', 'len': 'int',  'offset': 'int', 'busy': 'bool', 'paused': 'bool', 'speed': 'int',  'io-status': 'BlockDeviceIoStatus'} }", 
        "{ 'type': 'BlockdevSnapshot',  'data': { 'device': 'str', 'snapshot-file': 'str', '*format': 'str',  '*mode': 'NewImageMode' } }", 
        "{ 'type': 'ObjectPropertyInfo',  'data': { 'name': 'str', 'type': 'str' } }", 
        "{ 'type': 'ObjectTypeInfo',  'data': { 'name': 'str' } }", 
        "{ 'type': 'DevicePropertyInfo',  'data': { 'name': 'str', 'type': 'str' } }", 
        "{ 'type': 'NetdevNoneOptions',  'data': { } }", 
        "{ 'type': 'NetLegacyNicOptions',  'data': {  '*netdev': 'str',  '*macaddr': 'str',  '*model': 'str',  '*addr': 'str',  '*vectors': 'uint32' } }", 
        "{ 'type': 'String',  'data': {  'str': 'str' } }", 
        "{ 'type': 'NetdevUserOptions',  'data': {  '*hostname': 'str',  '*restrict': 'bool',  '*ip': 'str',  '*net': 'str',  '*host': 'str',  '*tftp': 'str',  '*bootfile': 'str',  '*dhcpstart': 'str',  '*dns': 'str',  '*dnssearch': ['String'],  '*smb': 'str',  '*smbserver': 'str',  '*hostfwd': ['String'],  '*guestfwd': ['String'] } }", 
        "{ 'type': 'NetdevTapOptions',  'data': {  '*ifname': 'str',  '*fd': 'str',  '*fds': 'str',  '*script': 'str',  '*downscript': 'str',  '*helper': 'str',  '*sndbuf': 'size',  '*vnet_hdr': 'bool',  '*vhost': 'bool',  '*vhostfd': 'str',  '*vhostfds': 'str',  '*vhostforce': 'bool',  '*queues': 'uint32'} }", 
        "{ 'type': 'NetdevSocketOptions',  'data': {  '*fd': 'str',  '*listen': 'str',  '*connect': 'str',  '*mcast': 'str',  '*localaddr': 'str',  '*udp': 'str' } }", 
        "{ 'type': 'NetdevVdeOptions',  'data': {  '*sock': 'str',  '*port': 'uint16',  '*group': 'str',  '*mode': 'uint16' } }", 
        "{ 'type': 'NetdevDumpOptions',  'data': {  '*len': 'size',  '*file': 'str' } }", 
        "{ 'type': 'NetdevBridgeOptions',  'data': {  '*br': 'str',  '*helper': 'str' } }", 
        "{ 'type': 'NetdevHubPortOptions',  'data': {  'hubid': 'int32' } }", 
        "{ 'type': 'NetLegacy',  'data': {  '*vlan': 'int32',  '*id': 'str',  '*name': 'str',  'opts': 'NetClientOptions' } }", 
        "{ 'type': 'Netdev',  'data': {  'id': 'str',  'opts': 'NetClientOptions' } }", 
        "{ 'type': 'InetSocketAddress',  'data': {  'host': 'str',  'port': 'str',  '*to': 'uint16',  '*ipv4': 'bool',  '*ipv6': 'bool' } }", 
        "{ 'type': 'UnixSocketAddress',  'data': {  'path': 'str' } }", 
        "{ 'type': 'MachineInfo',  'data': { 'name': 'str', '*alias': 'str',  '*is-default': 'bool', 'cpu-max': 'int' } }", 
        "{ 'type': 'CpuDefinitionInfo',  'data': { 'name': 'str' } }", 
        "{ 'type': 'AddfdInfo', 'data': {'fdset-id': 'int', 'fd': 'int'} }", 
        "{ 'type': 'FdsetFdInfo',  'data': {'fd': 'int', '*opaque': 'str'} }", 
        "{ 'type': 'FdsetInfo',  'data': {'fdset-id': 'int', 'fds': ['FdsetFdInfo']} }", 
        "{ 'type': 'TargetInfo',  'data': { 'arch': 'TargetType' } }", 
        "{ 'type': 'ChardevFile', 'data': { '*in' : 'str',  'out' : 'str' } }", 
        "{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } }", 
        "{ 'type': 'ChardevSocket', 'data': { 'addr' : 'SocketAddress',  '*server' : 'bool',  '*wait' : 'bool',  '*nodelay' : 'bool',  '*telnet' : 'bool' } }", 
        "{ 'type': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',  '*local' : 'SocketAddress' } }", 
        "{ 'type': 'ChardevMux', 'data': { 'chardev' : 'str' } }", 
        "{ 'type': 'ChardevStdio', 'data': { '*signal' : 'bool' } }", 
        "{ 'type': 'ChardevSpiceChannel', 'data': { 'type' : 'str' } }", 
        "{ 'type': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' } }", 
        "{ 'type': 'ChardevVC', 'data': { '*width' : 'int',  '*height' : 'int',  '*cols' : 'int',  '*rows' : 'int' } }", 
        "{ 'type': 'ChardevMemory', 'data': { '*size' : 'int' } }", 
        "{ 'type': 'ChardevDummy', 'data': { } }", 
        "{ 'type' : 'ChardevReturn', 'data': { '*pty' : 'str' } }", 
        "{ 'type': 'TPMPassthroughOptions', 'data': { '*path' : 'str',  '*cancel-path' : 'str'} }", 
        "{ 'type': 'TPMInfo',  'data': {'id': 'str',  'model': 'TpmModel',  'options': 'TpmTypeOptions' } }", 
        "{ 'type': 'AcpiTableOptions',  'data': {  '*sig': 'str',  '*rev': 'uint8',  '*oem_id': 'str',  '*oem_table_id': 'str',  '*oem_rev': 'uint32',  '*asl_compiler_id': 'str',  '*asl_compiler_rev': 'uint32',  '*file': 'str',  '*data': 'str' }}", 
        "{ 'type': 'CommandLineParameterInfo',  'data': { 'name': 'str',  'type': 'CommandLineParameterType',  '*help': 'str' } }", 
        "{ 'type': 'CommandLineOptionInfo',  'data': { 'option': 'str', 'parameters': ['CommandLineParameterInfo'] } }", 
        "{ 'type': 'X86CPUFeatureWordInfo',  'data': { 'cpuid-input-eax': 'int',  '*cpuid-input-ecx': 'int',  'cpuid-register': 'X86CPURegister32',  'features': 'int' } }"
    ]
}
diff mbox

Patch

diff --git a/qapi-schema.json b/qapi-schema.json
index ef1f657..2234e6a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3618,3 +3618,6 @@ 
             '*cpuid-input-ecx': 'int',
             'cpuid-register': 'X86CPURegister32',
             'features': 'int' } }
+
+{ 'command': 'query-qmp-schema', 'data': { '*type': 'str', '*name': 'str' },
+  'returns': ['str'] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ffd130e..fc56fba 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2932,3 +2932,26 @@  Example:
 <- { "return": {} }
 
 EQMP
+
+    {
+        .name       = "query-qmp-schema",
+        .args_type  = "type:s?,name:s?",
+        .mhandler.cmd_new = qmp_marshal_input_query_qmp_schema,
+    },
+
+
+SQMP
+query-qmp-schema
+----------------
+
+query qmp schema information
+
+Example:
+
+-> { "execute": "query-qmp-schema", "arguments": { "name" : "query-name" }}
+<- { "return": [
+        "{ 'command': 'query-name', 'returns': 'NameInfo' }"
+      ]
+   }
+
+EQMP
\ No newline at end of file
diff --git a/qmp.c b/qmp.c
index 4c149b3..11ce275 100644
--- a/qmp.c
+++ b/qmp.c
@@ -25,6 +25,7 @@ 
 #include "sysemu/blockdev.h"
 #include "qom/qom-qobject.h"
 #include "hw/boards.h"
+#include "qmp-schema.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -486,6 +487,41 @@  CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
     return arch_query_cpu_definitions(errp);
 }
 
+strList *qmp_query_qmp_schema(bool has_type, const char *type, bool
+                              has_name, const char * name, Error **errp)
+
+{
+    strList *list = NULL, *last_entry, *entry;
+    int i = 0;
+
+    while (qmp_schema_table[i].json_string) {
+        if (has_type && strcmp(type, qmp_schema_table[i].type)) {
+            i++;
+            continue;
+        }
+        if (has_name && strcmp(name, qmp_schema_table[i].name)) {
+            i++;
+            continue;
+        }
+
+        entry = malloc(sizeof(strList *));
+        entry->value = g_strdup(qmp_schema_table[i].json_string);
+        entry->next = NULL;
+
+        if (!list) {
+            list = entry;
+        } else {
+            last_entry->next = entry;
+        }
+        last_entry = entry;
+
+        printf("%d\n", i);
+        i++;
+    }
+
+    return list;
+}
+
 void qmp_add_client(const char *protocol, const char *fdname,
                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
                     Error **errp)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index e06332b..d15d04f 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -437,7 +437,7 @@  except os.error, e:
     if e.errno != errno.EEXIST:
         raise
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin)[0]
 commands = filter(lambda expr: expr.has_key('command'), exprs)
 commands = filter(lambda expr: not expr.has_key('gen'), commands)
 
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index ddcfed9..ce448d8 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -15,6 +15,7 @@  import sys
 import os
 import getopt
 import errno
+import re
 
 def generate_fwd_struct(name, members, builtin_type=False):
     if builtin_type:
@@ -303,7 +304,31 @@  fdecl.write(mcgen('''
 ''',
                   guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs_all = parse_schema(sys.stdin)
+
+schema_table = """
+/* convert qapi-schema.json to a string table */
+
+struct qmp_schem {
+const char *json_string;
+const char *type;
+const char *name;
+} qmp_schema_table[] = {
+"""
+
+for i in exprs_all[1]:
+    print i
+    str = re.sub(r'\n', ' \\\n', i[0].strip())
+    str = re.sub(r' +', ' ', str)
+    schema_table += '{"%s", "%s", "%s"},\n' % (str, i[1], i[2])
+
+schema_table += '{NULL, NULL, NULL } };\n'
+
+f = open("qmp-schema.h", "w")
+f.write(schema_table)
+f.close()
+
+exprs = exprs_all[0]
 exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
 
 fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 6cac05a..70f80eb 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -334,7 +334,7 @@  fdecl.write(mcgen('''
 ''',
                   prefix=prefix, guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin)[0]
 
 # to avoid header dependency hell, we always generate declarations
 # for built-in types in our header files and simply guard them
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 02ad668..46cc2e4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -80,6 +80,7 @@  def evaluate(string):
 
 def parse_schema(fp):
     exprs = []
+    raw_exprs = []
     expr = ''
     expr_eval = None
 
@@ -91,6 +92,11 @@  def parse_schema(fp):
             expr += line
         elif expr:
             expr_eval = evaluate(expr)
+
+            for name in ['command', 'type', 'enum', 'union']:
+                if expr_eval.has_key(name):
+                    raw_exprs.append([expr, name, expr_eval[name]])
+
             if expr_eval.has_key('enum'):
                 add_enum(expr_eval['enum'])
             elif expr_eval.has_key('union'):
@@ -102,13 +108,18 @@  def parse_schema(fp):
 
     if expr:
         expr_eval = evaluate(expr)
+
+        for name in ['command', 'type', 'enum', 'union']:
+            if expr_eval.has_key(name):
+                raw_exprs.append([expr, name, expr_eval[name]])
+
         if expr_eval.has_key('enum'):
             add_enum(expr_eval['enum'])
         elif expr_eval.has_key('union'):
             add_enum('%sKind' % expr_eval['union'])
         exprs.append(expr_eval)
 
-    return exprs
+    return exprs, raw_exprs
 
 def parse_args(typeinfo):
     for member in typeinfo: