summaryrefslogtreecommitdiffstats
path: root/QMP
diff options
context:
space:
mode:
Diffstat (limited to 'QMP')
-rw-r--r--QMP/README88
-rwxr-xr-xQMP/qemu-ga-client301
-rwxr-xr-xQMP/qmp126
-rw-r--r--QMP/qmp-events.txt502
-rwxr-xr-xQMP/qmp-shell286
-rw-r--r--QMP/qmp-spec.txt282
-rw-r--r--QMP/qmp.py196
-rwxr-xr-xQMP/qom-fuse138
-rwxr-xr-xQMP/qom-get67
-rwxr-xr-xQMP/qom-list64
-rwxr-xr-xQMP/qom-set64
11 files changed, 0 insertions, 2114 deletions
diff --git a/QMP/README b/QMP/README
deleted file mode 100644
index c95a08c234..0000000000
--- a/QMP/README
+++ /dev/null
@@ -1,88 +0,0 @@
- QEMU Monitor Protocol
- =====================
-
-Introduction
--------------
-
-The QEMU Monitor Protocol (QMP) allows applications to communicate with
-QEMU's Monitor.
-
-QMP is JSON[1] based and currently has the following features:
-
-- Lightweight, text-based, easy to parse data format
-- Asynchronous messages support (ie. events)
-- Capabilities Negotiation
-
-For detailed information on QMP's usage, please, refer to the following files:
-
-o qmp-spec.txt QEMU Monitor Protocol current specification
-o qmp-commands.txt QMP supported commands (auto-generated at build-time)
-o qmp-events.txt List of available asynchronous events
-
-There is also a simple Python script called 'qmp-shell' available.
-
-IMPORTANT: It's strongly recommended to read the 'Stability Considerations'
-section in the qmp-commands.txt file before making any serious use of QMP.
-
-
-[1] http://www.json.org
-
-Usage
------
-
-To enable QMP, you need a QEMU monitor instance in "control mode". There are
-two ways of doing this.
-
-The simplest one is using the '-qmp' command-line option. The following
-example makes QMP available on localhost port 4444:
-
- $ qemu [...] -qmp tcp:localhost:4444,server
-
-However, in order to have more complex combinations, like multiple monitors,
-the '-mon' command-line option should be used along with the '-chardev' one.
-For instance, the following example creates one user monitor on stdio and one
-QMP monitor on localhost port 4444.
-
- $ qemu [...] -chardev stdio,id=mon0 -mon chardev=mon0,mode=readline \
- -chardev socket,id=mon1,host=localhost,port=4444,server \
- -mon chardev=mon1,mode=control
-
-Please, refer to QEMU's manpage for more information.
-
-Simple Testing
---------------
-
-To manually test QMP one can connect with telnet and issue commands by hand:
-
-$ telnet localhost 4444
-Trying 127.0.0.1...
-Connected to localhost.
-Escape character is '^]'.
-{"QMP": {"version": {"qemu": {"micro": 50, "minor": 13, "major": 0}, "package": ""}, "capabilities": []}}
-{ "execute": "qmp_capabilities" }
-{"return": {}}
-{ "execute": "query-version" }
-{"return": {"qemu": {"micro": 50, "minor": 13, "major": 0}, "package": ""}}
-
-Development Process
--------------------
-
-When changing QMP's interface (by adding new commands, events or modifying
-existing ones) it's mandatory to update the relevant documentation, which is
-one (or more) of the files listed in the 'Introduction' section*.
-
-Also, it's strongly recommended to send the documentation patch first, before
-doing any code change. This is so because:
-
- 1. Avoids the code dictating the interface
-
- 2. Review can improve your interface. Letting that happen before
- you implement it can save you work.
-
-* The qmp-commands.txt file is generated from the qmp-commands.hx one, which
- is the file that should be edited.
-
-Homepage
---------
-
-http://wiki.qemu.org/QMP
diff --git a/QMP/qemu-ga-client b/QMP/qemu-ga-client
deleted file mode 100755
index b5f7e7c5ff..0000000000
--- a/QMP/qemu-ga-client
+++ /dev/null
@@ -1,301 +0,0 @@
-#!/usr/bin/python
-
-# QEMU Guest Agent Client
-#
-# Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Usage:
-#
-# Start QEMU with:
-#
-# # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-# -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
-#
-# Run the script:
-#
-# $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
-#
-# or
-#
-# $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
-# $ qemu-ga-client <command> [args...]
-#
-# For example:
-#
-# $ qemu-ga-client cat /etc/resolv.conf
-# # Generated by NetworkManager
-# nameserver 10.0.2.3
-# $ qemu-ga-client fsfreeze status
-# thawed
-# $ qemu-ga-client fsfreeze freeze
-# 2 filesystems frozen
-#
-# See also: http://wiki.qemu.org/Features/QAPI/GuestAgent
-#
-
-import base64
-import random
-
-import qmp
-
-
-class QemuGuestAgent(qmp.QEMUMonitorProtocol):
- def __getattr__(self, name):
- def wrapper(**kwds):
- return self.command('guest-' + name.replace('_', '-'), **kwds)
- return wrapper
-
-
-class QemuGuestAgentClient:
- error = QemuGuestAgent.error
-
- def __init__(self, address):
- self.qga = QemuGuestAgent(address)
- self.qga.connect(negotiate=False)
-
- def sync(self, timeout=3):
- # Avoid being blocked forever
- if not self.ping(timeout):
- raise EnvironmentError('Agent seems not alive')
- uid = random.randint(0, (1 << 32) - 1)
- while True:
- ret = self.qga.sync(id=uid)
- if isinstance(ret, int) and int(ret) == uid:
- break
-
- def __file_read_all(self, handle):
- eof = False
- data = ''
- while not eof:
- ret = self.qga.file_read(handle=handle, count=1024)
- _data = base64.b64decode(ret['buf-b64'])
- data += _data
- eof = ret['eof']
- return data
-
- def read(self, path):
- handle = self.qga.file_open(path=path)
- try:
- data = self.__file_read_all(handle)
- finally:
- self.qga.file_close(handle=handle)
- return data
-
- def info(self):
- info = self.qga.info()
-
- msgs = []
- msgs.append('version: ' + info['version'])
- msgs.append('supported_commands:')
- enabled = [c['name'] for c in info['supported_commands'] if c['enabled']]
- msgs.append('\tenabled: ' + ', '.join(enabled))
- disabled = [c['name'] for c in info['supported_commands'] if not c['enabled']]
- msgs.append('\tdisabled: ' + ', '.join(disabled))
-
- return '\n'.join(msgs)
-
- def __gen_ipv4_netmask(self, prefixlen):
- mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
- return '.'.join([str(mask >> 24),
- str((mask >> 16) & 0xff),
- str((mask >> 8) & 0xff),
- str(mask & 0xff)])
-
- def ifconfig(self):
- nifs = self.qga.network_get_interfaces()
-
- msgs = []
- for nif in nifs:
- msgs.append(nif['name'] + ':')
- if 'ip-addresses' in nif:
- for ipaddr in nif['ip-addresses']:
- if ipaddr['ip-address-type'] == 'ipv4':
- addr = ipaddr['ip-address']
- mask = self.__gen_ipv4_netmask(int(ipaddr['prefix']))
- msgs.append("\tinet %s netmask %s" % (addr, mask))
- elif ipaddr['ip-address-type'] == 'ipv6':
- addr = ipaddr['ip-address']
- prefix = ipaddr['prefix']
- msgs.append("\tinet6 %s prefixlen %s" % (addr, prefix))
- if nif['hardware-address'] != '00:00:00:00:00:00':
- msgs.append("\tether " + nif['hardware-address'])
-
- return '\n'.join(msgs)
-
- def ping(self, timeout):
- self.qga.settimeout(timeout)
- try:
- self.qga.ping()
- except self.qga.timeout:
- return False
- return True
-
- def fsfreeze(self, cmd):
- if cmd not in ['status', 'freeze', 'thaw']:
- raise StandardError('Invalid command: ' + cmd)
-
- return getattr(self.qga, 'fsfreeze' + '_' + cmd)()
-
- def fstrim(self, minimum=0):
- return getattr(self.qga, 'fstrim')(minimum=minimum)
-
- def suspend(self, mode):
- if mode not in ['disk', 'ram', 'hybrid']:
- raise StandardError('Invalid mode: ' + mode)
-
- try:
- getattr(self.qga, 'suspend' + '_' + mode)()
- # On error exception will raise
- except self.qga.timeout:
- # On success command will timed out
- return
-
- def shutdown(self, mode='powerdown'):
- if mode not in ['powerdown', 'halt', 'reboot']:
- raise StandardError('Invalid mode: ' + mode)
-
- try:
- self.qga.shutdown(mode=mode)
- except self.qga.timeout:
- return
-
-
-def _cmd_cat(client, args):
- if len(args) != 1:
- print('Invalid argument')
- print('Usage: cat <file>')
- sys.exit(1)
- print(client.read(args[0]))
-
-
-def _cmd_fsfreeze(client, args):
- usage = 'Usage: fsfreeze status|freeze|thaw'
- if len(args) != 1:
- print('Invalid argument')
- print(usage)
- sys.exit(1)
- if args[0] not in ['status', 'freeze', 'thaw']:
- print('Invalid command: ' + args[0])
- print(usage)
- sys.exit(1)
- cmd = args[0]
- ret = client.fsfreeze(cmd)
- if cmd == 'status':
- print(ret)
- elif cmd == 'freeze':
- print("%d filesystems frozen" % ret)
- else:
- print("%d filesystems thawed" % ret)
-
-
-def _cmd_fstrim(client, args):
- if len(args) == 0:
- minimum = 0
- else:
- minimum = int(args[0])
- print(client.fstrim(minimum))
-
-
-def _cmd_ifconfig(client, args):
- print(client.ifconfig())
-
-
-def _cmd_info(client, args):
- print(client.info())
-
-
-def _cmd_ping(client, args):
- if len(args) == 0:
- timeout = 3
- else:
- timeout = float(args[0])
- alive = client.ping(timeout)
- if not alive:
- print("Not responded in %s sec" % args[0])
- sys.exit(1)
-
-
-def _cmd_suspend(client, args):
- usage = 'Usage: suspend disk|ram|hybrid'
- if len(args) != 1:
- print('Less argument')
- print(usage)
- sys.exit(1)
- if args[0] not in ['disk', 'ram', 'hybrid']:
- print('Invalid command: ' + args[0])
- print(usage)
- sys.exit(1)
- client.suspend(args[0])
-
-
-def _cmd_shutdown(client, args):
- client.shutdown()
-_cmd_powerdown = _cmd_shutdown
-
-
-def _cmd_halt(client, args):
- client.shutdown('halt')
-
-
-def _cmd_reboot(client, args):
- client.shutdown('reboot')
-
-
-commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]
-
-
-def main(address, cmd, args):
- if not os.path.exists(address):
- print('%s not found' % address)
- sys.exit(1)
-
- if cmd not in commands:
- print('Invalid command: ' + cmd)
- print('Available commands: ' + ', '.join(commands))
- sys.exit(1)
-
- try:
- client = QemuGuestAgentClient(address)
- except QemuGuestAgent.error, e:
- import errno
-
- print(e)
- if e.errno == errno.ECONNREFUSED:
- print('Hint: qemu is not running?')
- sys.exit(1)
-
- if cmd == 'fsfreeze' and args[0] == 'freeze':
- client.sync(60)
- elif cmd != 'ping':
- client.sync()
-
- globals()['_cmd_' + cmd](client, args)
-
-
-if __name__ == '__main__':
- import sys
- import os
- import optparse
-
- address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in os.environ else None
-
- usage = "%prog [--address=<unix_path>|<ipv4_address>] <command> [args...]\n"
- usage += '<command>: ' + ', '.join(commands)
- parser = optparse.OptionParser(usage=usage)
- parser.add_option('--address', action='store', type='string',
- default=address, help='Specify a ip:port pair or a unix socket path')
- options, args = parser.parse_args()
-
- address = options.address
- if address is None:
- parser.error('address is not specified')
- sys.exit(1)
-
- if len(args) == 0:
- parser.error('Less argument')
- sys.exit(1)
-
- main(address, args[0], args[1:])
diff --git a/QMP/qmp b/QMP/qmp
deleted file mode 100755
index 1db3c7ffeb..0000000000
--- a/QMP/qmp
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/python
-#
-# QMP command line tool
-#
-# Copyright IBM, Corp. 2011
-#
-# Authors:
-# Anthony Liguori <aliguori@us.ibm.com>
-#
-# This work is licensed under the terms of the GNU GPLv2 or later.
-# See the COPYING file in the top-level directory.
-
-import sys, os
-from qmp import QEMUMonitorProtocol
-
-def print_response(rsp, prefix=[]):
- if type(rsp) == list:
- i = 0
- for item in rsp:
- if prefix == []:
- prefix = ['item']
- print_response(item, prefix[:-1] + ['%s[%d]' % (prefix[-1], i)])
- i += 1
- elif type(rsp) == dict:
- for key in rsp.keys():
- print_response(rsp[key], prefix + [key])
- else:
- if len(prefix):
- print '%s: %s' % ('.'.join(prefix), rsp)
- else:
- print '%s' % (rsp)
-
-def main(args):
- path = None
-
- # Use QMP_PATH if it's set
- if os.environ.has_key('QMP_PATH'):
- path = os.environ['QMP_PATH']
-
- while len(args):
- arg = args[0]
-
- if arg.startswith('--'):
- arg = arg[2:]
- if arg.find('=') == -1:
- value = True
- else:
- arg, value = arg.split('=', 1)
-
- if arg in ['path']:
- if type(value) == str:
- path = value
- elif arg in ['help']:
- os.execlp('man', 'man', 'qmp')
- else:
- print 'Unknown argument "%s"' % arg
-
- args = args[1:]
- else:
- break
-
- if not path:
- print "QMP path isn't set, use --path=qmp-monitor-address or set QMP_PATH"
- return 1
-
- if len(args):
- command, args = args[0], args[1:]
- else:
- print 'No command found'
- print 'Usage: "qmp [--path=qmp-monitor-address] qmp-cmd arguments"'
- return 1
-
- if command in ['help']:
- os.execlp('man', 'man', 'qmp')
-
- srv = QEMUMonitorProtocol(path)
- srv.connect()
-
- def do_command(srv, cmd, **kwds):
- rsp = srv.cmd(cmd, kwds)
- if rsp.has_key('error'):
- raise Exception(rsp['error']['desc'])
- return rsp['return']
-
- commands = map(lambda x: x['name'], do_command(srv, 'query-commands'))
-
- srv.close()
-
- if command not in commands:
- fullcmd = 'qmp-%s' % command
- try:
- os.environ['QMP_PATH'] = path
- os.execvp(fullcmd, [fullcmd] + args)
- except OSError, (errno, msg):
- if errno == 2:
- print 'Command "%s" not found.' % (fullcmd)
- return 1
- raise
- return 0
-
- srv = QEMUMonitorProtocol(path)
- srv.connect()
-
- arguments = {}
- for arg in args:
- if not arg.startswith('--'):
- print 'Unknown argument "%s"' % arg
- return 1
-
- arg = arg[2:]
- if arg.find('=') == -1:
- value = True
- else:
- arg, value = arg.split('=', 1)
-
- if arg in ['help']:
- os.execlp('man', 'man', 'qmp-%s' % command)
- return 1
-
- arguments[arg] = value
-
- rsp = do_command(srv, command, **arguments)
- print_response(rsp)
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
deleted file mode 100644
index 4b24ec900d..0000000000
--- a/QMP/qmp-events.txt
+++ /dev/null
@@ -1,502 +0,0 @@
- QEMU Monitor Protocol Events
- ============================
-
-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
-
-Data:
-
-- "actual": actual level of the guest memory balloon in bytes (json-number)
-
-Example:
-
-{ "event": "BALLOON_CHANGE",
- "data": { "actual": 944766976 },
- "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-
-BLOCK_IMAGE_CORRUPTED
----------------------
-
-Emitted when a disk image is being marked corrupt.
-
-Data:
-
-- "device": Device name (json-string)
-- "msg": Informative message (e.g., reason for the corruption) (json-string)
-- "offset": If the corruption resulted from an image access, this is the access
- offset into the image (json-int)
-- "size": If the corruption resulted from an image access, this is the access
- size (json-int)
-
-Example:
-
-{ "event": "BLOCK_IMAGE_CORRUPTED",
- "data": { "device": "ide0-hd0",
- "msg": "Prevented active L1 table overwrite", "offset": 196608,
- "size": 65536 },
- "timestamp": { "seconds": 1378126126, "microseconds": 966463 } }
-
-BLOCK_IO_ERROR
---------------
-
-Emitted when a disk I/O error occurs.
-
-Data:
-
-- "device": device name (json-string)
-- "operation": I/O operation (json-string, "read" or "write")
-- "action": action that has been taken, it's one of the following (json-string):
- "ignore": error has been ignored
- "report": error has been reported to the device
- "stop": error caused VM to be stopped
-
-Example:
-
-{ "event": "BLOCK_IO_ERROR",
- "data": { "device": "ide0-hd1",
- "operation": "write",
- "action": "stop" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-Note: If action is "stop", a STOP event will eventually follow the
-BLOCK_IO_ERROR event.
-
-BLOCK_JOB_CANCELLED
--------------------
-
-Emitted when a block job has been cancelled.
-
-Data:
-
-- "type": Job type (json-string; "stream" for image streaming
- "commit" for block commit)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-
-Example:
-
-{ "event": "BLOCK_JOB_CANCELLED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 134217728,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_COMPLETED
--------------------
-
-Emitted when a block job has completed.
-
-Data:
-
-- "type": Job type (json-string; "stream" for image streaming
- "commit" for block commit)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-- "error": Error message (json-string, optional)
- Only present on failure. This field contains a human-readable
- error message. There are no semantics other than that streaming
- has failed and clients should not try to interpret the error
- string.
-
-Example:
-
-{ "event": "BLOCK_JOB_COMPLETED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 10737418240,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_ERROR
----------------
-
-Emitted when a block job encounters an error.
-
-Data:
-
-- "device": device name (json-string)
-- "operation": I/O operation (json-string, "read" or "write")
-- "action": action that has been taken, it's one of the following (json-string):
- "ignore": error has been ignored, the job may fail later
- "report": error will be reported and the job canceled
- "stop": error caused job to be paused
-
-Example:
-
-{ "event": "BLOCK_JOB_ERROR",
- "data": { "device": "ide0-hd1",
- "operation": "write",
- "action": "stop" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-BLOCK_JOB_READY
----------------
-
-Emitted when a block job is ready to complete.
-
-Data:
-
-- "device": device name (json-string)
-
-Example:
-
-{ "event": "BLOCK_JOB_READY",
- "data": { "device": "ide0-hd1" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-Note: The "ready to complete" status is always reset by a BLOCK_JOB_ERROR
-event.
-
-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.
-
-Data:
-
-- "device": device name (json-string, optional)
-- "path": device path (json-string)
-
-{ "event": "DEVICE_DELETED",
- "data": { "device": "virtio-net-pci-0",
- "path": "/machine/peripheral/virtio-net-pci-0" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-DEVICE_TRAY_MOVED
------------------
-
-It's emitted whenever the tray of a removable device is moved by the guest
-or by HMP/QMP commands.
-
-Data:
-
-- "device": device name (json-string)
-- "tray-open": true if the tray has been opened or false if it has been closed
- (json-bool)
-
-{ "event": "DEVICE_TRAY_MOVED",
- "data": { "device": "ide1-cd0",
- "tray-open": true
- },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-NIC_RX_FILTER_CHANGED
------------------
-
-The event is emitted once until the query command is executed,
-the first event will always be emitted.
-
-Data:
-
-- "name": net client name (json-string)
-- "path": device path (json-string)
-
-{ "event": "NIC_RX_FILTER_CHANGED",
- "data": { "name": "vnet0",
- "path": "/machine/peripheral/vnet0/virtio-backend" },
- "timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
-}
-
-RESET
------
-
-Emitted when the Virtual Machine is reseted.
-
-Data: None.
-
-Example:
-
-{ "event": "RESET",
- "timestamp": { "seconds": 1267041653, "microseconds": 9518 } }
-
-RESUME
-------
-
-Emitted when the Virtual Machine resumes execution.
-
-Data: None.
-
-Example:
-
-{ "event": "RESUME",
- "timestamp": { "seconds": 1271770767, "microseconds": 582542 } }
-
-RTC_CHANGE
-----------
-
-Emitted when the guest changes the RTC time.
-
-Data:
-
-- "offset": Offset between base RTC clock (as specified by -rtc base), and
-new RTC clock value (json-number)
-
-Example:
-
-{ "event": "RTC_CHANGE",
- "data": { "offset": 78 },
- "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-
-SHUTDOWN
---------
-
-Emitted when the Virtual Machine is powered down.
-
-Data: None.
-
-Example:
-
-{ "event": "SHUTDOWN",
- "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
-
-Note: If the command-line option "-no-shutdown" has been specified, a STOP
-event will eventually follow the SHUTDOWN event.
-
-SPICE_CONNECTED, SPICE_DISCONNECTED
------------------------------------
-
-Emitted when a SPICE client connects or disconnects.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-
-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"}
-}}
-
-SPICE_INITIALIZED
------------------
-
-Emitted after initial handshake and authentication takes place (if any)
-and the SPICE channel is up'n'running
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "connection-id": spice connection id. All channels with the same id
- belong to the same spice session (json-int)
- - "channel-type": channel type. "1" is the main control channel, filter for
- this one if you want track spice sessions only (json-int)
- - "channel-id": channel id. Usually "0", might be different needed when
- multiple channels of the same type exist, such as multiple
- display channels in a multihead setup (json-int)
- - "tls": whevener the channel is encrypted (json-bool)
-
-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}
-}}
-
-STOP
-----
-
-Emitted when the Virtual Machine is stopped.
-
-Data: None.
-
-Example:
-
-{ "event": "STOP",
- "timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
-
-SUSPEND
--------
-
-Emitted when guest enters S3 state.
-
-Data: None.
-
-Example:
-
-{ "event": "SUSPEND",
- "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
-
-SUSPEND_DISK
-------------
-
-Emitted when the guest makes a request to enter S4 state.
-
-Data: None.
-
-Example:
-
-{ "event": "SUSPEND_DISK",
- "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
-
-Note: QEMU shuts down when entering S4 state.
-
-VNC_CONNECTED
--------------
-
-Emitted when a VNC client establishes a connection.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-
-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 } }
-
-
-Note: This event is emitted before any authentication takes place, thus
-the authentication ID is not provided.
-
-VNC_DISCONNECTED
-----------------
-
-Emitted when the connection is closed.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "x509_dname": TLS dname (json-string, optional)
- - "sasl_username": SASL username (json-string, optional)
-
-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 } }
-
-VNC_INITIALIZED
----------------
-
-Emitted after authentication takes place (if any) and the VNC session is
-made active.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "x509_dname": TLS dname (json-string, optional)
- - "sasl_username": SASL username (json-string, optional)
-
-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 } }
-
-WAKEUP
-------
-
-Emitted when the guest has woken up from S3 and is running.
-
-Data: None.
-
-Example:
-
-{ "event": "WATCHDOG",
- "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-
-WATCHDOG
---------
-
-Emitted when the watchdog device's timer is expired.
-
-Data:
-
-- "action": Action that has been taken, it's one of the following (json-string):
- "reset", "shutdown", "poweroff", "pause", "debug", or "none"
-
-Example:
-
-{ "event": "WATCHDOG",
- "data": { "action": "reset" },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is
-followed respectively by the RESET, SHUTDOWN, or STOP events.
-
-GUEST_PANICKED
---------------
-
-Emitted when guest OS panic is detected.
-
-Data:
-
-- "action": Action that has been taken (json-string, currently always "pause").
-
-Example:
-
-{ "event": "GUEST_PANICKED",
- "data": { "action": "pause" } }
diff --git a/QMP/qmp-shell b/QMP/qmp-shell
deleted file mode 100755
index 73cb3b6cef..0000000000
--- a/QMP/qmp-shell
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/python
-#
-# Low-level QEMU shell on top of QMP.
-#
-# Copyright (C) 2009, 2010 Red Hat Inc.
-#
-# Authors:
-# Luiz Capitulino <lcapitulino@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-#
-# Usage:
-#
-# Start QEMU with:
-#
-# # qemu [...] -qmp unix:./qmp-sock,server
-#
-# Run the shell:
-#
-# $ qmp-shell ./qmp-sock
-#
-# Commands have the following format:
-#
-# < command-name > [ arg-name1=arg1 ] ... [ arg-nameN=argN ]
-#
-# For example:
-#
-# (QEMU) device_add driver=e1000 id=net1
-# {u'return': {}}
-# (QEMU)
-
-import qmp
-import readline
-import sys
-import pprint
-
-class QMPCompleter(list):
- def complete(self, text, state):
- for cmd in self:
- if cmd.startswith(text):
- if not state:
- return cmd
- else:
- state -= 1
-
-class QMPShellError(Exception):
- pass
-
-class QMPShellBadPort(QMPShellError):
- pass
-
-# TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and
-# _execute_cmd()). Let's design a better one.
-class QMPShell(qmp.QEMUMonitorProtocol):
- def __init__(self, address, pp=None):
- qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address))
- self._greeting = None
- self._completer = None
- self._pp = pp
-
- def __get_address(self, arg):
- """
- Figure out if the argument is in the port:host form, if it's not it's
- probably a file path.
- """
- addr = arg.split(':')
- if len(addr) == 2:
- try:
- port = int(addr[1])
- except ValueError:
- raise QMPShellBadPort
- return ( addr[0], port )
- # socket path
- return arg
-
- def _fill_completion(self):
- for cmd in self.cmd('query-commands')['return']:
- self._completer.append(cmd['name'])
-
- def __completer_setup(self):
- self._completer = QMPCompleter()
- self._fill_completion()
- readline.set_completer(self._completer.complete)
- readline.parse_and_bind("tab: complete")
- # XXX: default delimiters conflict with some command names (eg. query-),
- # clearing everything as it doesn't seem to matter
- readline.set_completer_delims('')
-
- def __build_cmd(self, cmdline):
- """
- Build a QMP input object from a user provided command-line in the
- following format:
-
- < command-name > [ arg-name1=arg1 ] ... [ arg-nameN=argN ]
- """
- cmdargs = cmdline.split()
- qmpcmd = { 'execute': cmdargs[0], 'arguments': {} }
- for arg in cmdargs[1:]:
- opt = arg.split('=')
- try:
- if(len(opt) > 2):
- opt[1] = '='.join(opt[1:])
- value = int(opt[1])
- except ValueError:
- if opt[1] == 'true':
- value = True
- elif opt[1] == 'false':
- value = False
- else:
- value = opt[1]
- qmpcmd['arguments'][opt[0]] = value
- return qmpcmd
-
- def _execute_cmd(self, cmdline):
- try:
- qmpcmd = self.__build_cmd(cmdline)
- except:
- print 'command format: <command-name> ',
- print '[arg-name1=arg1] ... [arg-nameN=argN]'
- return True
- resp = self.cmd_obj(qmpcmd)
- if resp is None:
- print 'Disconnected'
- return False
-
- if self._pp is not None:
- self._pp.pprint(resp)
- else:
- print resp
- return True
-
- def connect(self):
- self._greeting = qmp.QEMUMonitorProtocol.connect(self)
- self.__completer_setup()
-
- def show_banner(self, msg='Welcome to the QMP low-level shell!'):
- print msg
- version = self._greeting['QMP']['version']['qemu']
- print 'Connected to QEMU %d.%d.%d\n' % (version['major'],version['minor'],version['micro'])
-
- def read_exec_command(self, prompt):
- """
- Read and execute a command.
-
- @return True if execution was ok, return False if disconnected.
- """
- try:
- cmdline = raw_input(prompt)
- except EOFError:
- print
- return False
- if cmdline == '':
- for ev in self.get_events():
- print ev
- self.clear_events()
- return True
- else:
- return self._execute_cmd(cmdline)
-
-class HMPShell(QMPShell):
- def __init__(self, address):
- QMPShell.__init__(self, address)
- self.__cpu_index = 0
-
- def __cmd_completion(self):
- for cmd in self.__cmd_passthrough('help')['return'].split('\r\n'):
- if cmd and cmd[0] != '[' and cmd[0] != '\t':
- name = cmd.split()[0] # drop help text
- if name == 'info':
- continue
- if name.find('|') != -1:
- # Command in the form 'foobar|f' or 'f|foobar', take the
- # full name
- opt = name.split('|')
- if len(opt[0]) == 1:
- name = opt[1]
- else:
- name = opt[0]
- self._completer.append(name)
- self._completer.append('help ' + name) # help completion
-
- def __info_completion(self):
- for cmd in self.__cmd_passthrough('info')['return'].split('\r\n'):
- if cmd:
- self._completer.append('info ' + cmd.split()[1])
-
- def __other_completion(self):
- # special cases
- self._completer.append('help info')
-
- def _fill_completion(self):
- self.__cmd_completion()
- self.__info_completion()
- self.__other_completion()
-
- def __cmd_passthrough(self, cmdline, cpu_index = 0):
- return self.cmd_obj({ 'execute': 'human-monitor-command', 'arguments':
- { 'command-line': cmdline,
- 'cpu-index': cpu_index } })
-
- def _execute_cmd(self, cmdline):
- if cmdline.split()[0] == "cpu":
- # trap the cpu command, it requires special setting
- try:
- idx = int(cmdline.split()[1])
- if not 'return' in self.__cmd_passthrough('info version', idx):
- print 'bad CPU index'
- return True
- self.__cpu_index = idx
- except ValueError:
- print 'cpu command takes an integer argument'
- return True
- resp = self.__cmd_passthrough(cmdline, self.__cpu_index)
- if resp is None:
- print 'Disconnected'
- return False
- assert 'return' in resp or 'error' in resp
- if 'return' in resp:
- # Success
- if len(resp['return']) > 0:
- print resp['return'],
- else:
- # Error
- print '%s: %s' % (resp['error']['class'], resp['error']['desc'])
- return True
-
- def show_banner(self):
- QMPShell.show_banner(self, msg='Welcome to the HMP shell!')
-
-def die(msg):
- sys.stderr.write('ERROR: %s\n' % msg)
- sys.exit(1)
-
-def fail_cmdline(option=None):
- if option:
- sys.stderr.write('ERROR: bad command-line option \'%s\'\n' % option)
- sys.stderr.write('qemu-shell [ -p ] [ -H ] < UNIX socket path> | < TCP address:port >\n')
- sys.exit(1)
-
-def main():
- addr = ''
- qemu = None
- hmp = False
- pp = None
-
- try:
- for arg in sys.argv[1:]:
- if arg == "-H":
- if qemu is not None:
- fail_cmdline(arg)
- hmp = True
- elif arg == "-p":
- if pp is not None:
- fail_cmdline(arg)
- pp = pprint.PrettyPrinter(indent=4)
- else:
- if qemu is not None:
- fail_cmdline(arg)
- if hmp:
- qemu = HMPShell(arg)
- else:
- qemu = QMPShell(arg, pp)
- addr = arg
-
- if qemu is None:
- fail_cmdline()
- except QMPShellBadPort:
- die('bad port number in command-line')
-
- try:
- qemu.connect()
- except qmp.QMPConnectError:
- die('Didn\'t get QMP greeting message')
- except qmp.QMPCapabilitiesError:
- die('Could not negotiate capabilities')
- except qemu.error:
- die('Could not connect to %s' % addr)
-
- qemu.show_banner()
- while qemu.read_exec_command('(QEMU) '):
- pass
- qemu.close()
-
-if __name__ == '__main__':
- main()
diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt
deleted file mode 100644
index a27789692b..0000000000
--- a/QMP/qmp-spec.txt
+++ /dev/null
@@ -1,282 +0,0 @@
- QEMU Monitor Protocol Specification - Version 0.1
-
-1. Introduction
-===============
-
-This document specifies the QEMU Monitor Protocol (QMP), a JSON-based protocol
-which is available for applications to control QEMU at the machine-level.
-
-To enable QMP support, QEMU has to be run in "control mode". This is done by
-starting QEMU with the appropriate command-line options. Please, refer to the
-QEMU manual page for more information.
-
-2. Protocol Specification
-=========================
-
-This section details the protocol format. For the purpose of this document
-"Client" is any application which is communicating with QEMU in control mode,
-and "Server" is QEMU itself.
-
-JSON data structures, when mentioned in this document, are always in the
-following format:
-
- json-DATA-STRUCTURE-NAME
-
-Where DATA-STRUCTURE-NAME is any valid JSON data structure, as defined by
-the JSON standard:
-
-http://www.ietf.org/rfc/rfc4627.txt
-
-For convenience, json-object members and json-array elements mentioned in
-this document will be in a certain order. However, in real protocol usage
-they can be in ANY order, thus no particular order should be assumed.
-
-2.1 General Definitions
------------------------
-
-2.1.1 All interactions transmitted by the Server are json-objects, always
- terminating with CRLF
-
-2.1.2 All json-objects members are mandatory when not specified otherwise
-
-2.2 Server Greeting
--------------------
-
-Right when connected the Server will issue a greeting message, which signals
-that the connection has been successfully established and that the Server is
-ready for capabilities negotiation (for more information refer to section
-'4. Capabilities Negotiation').
-
-The format is:
-
-{ "QMP": { "version": json-object, "capabilities": json-array } }
-
- Where,
-
-- The "version" member contains the Server's version information (the format
- is the same of the 'query-version' command)
-- The "capabilities" member specify the availability of features beyond the
- baseline specification
-
-2.3 Issuing Commands
---------------------
-
-The format for command execution is:
-
-{ "execute": json-string, "arguments": json-object, "id": json-value }
-
- Where,
-
-- The "execute" member identifies the command to be executed by the Server
-- The "arguments" member is used to pass any arguments required for the
- execution of the command, it is optional when no arguments are required
-- The "id" member is a transaction identification associated with the
- command execution, it is optional and will be part of the response if
- provided
-
-2.4 Commands Responses
-----------------------
-
-There are two possible responses which the Server will issue as the result
-of a command execution: success or error.
-
-2.4.1 success
--------------
-
-The success response is issued when the command execution has finished
-without errors.
-
-The format is:
-
-{ "return": json-object, "id": json-value }
-
- Where,
-
-- The "return" member contains the command returned data, which is defined
- in a per-command basis or an empty json-object if the command does not
- return data
-- The "id" member contains the transaction identification associated
- with the command execution (if issued by the Client)
-
-2.4.2 error
------------
-
-The error response is issued when the command execution could not be
-completed because of an error condition.
-
-The format is:
-
-{ "error": { "class": json-string, "desc": json-string }, "id": json-value }
-
- Where,
-
-- The "class" member contains the error class name (eg. "GenericError")
-- The "desc" member is a human-readable error message. Clients should
- not attempt to parse this message.
-- The "id" member contains the transaction identification associated with
- the command execution (if issued by the Client)
-
-NOTE: Some errors can occur before the Server is able to read the "id" member,
-in these cases the "id" member will not be part of the error response, even
-if provided by the client.
-
-2.5 Asynchronous events
------------------------
-
-As a result of state changes, the Server may send messages unilaterally
-to the Client at any time. They are called 'asynchronous events'.
-
-The format is:
-
-{ "event": json-string, "data": json-object,
- "timestamp": { "seconds": json-number, "microseconds": json-number } }
-
- Where,
-
-- The "event" member contains the event's name
-- The "data" member contains event specific data, which is defined in a
- per-event basis, it is optional
-- The "timestamp" member contains the exact time of when the event occurred
- in the Server. It is a fixed json-object with time in seconds and
- microseconds
-
-For a listing of supported asynchronous events, please, refer to the
-qmp-events.txt file.
-
-3. QMP Examples
-===============
-
-This section provides some examples of real QMP usage, in all of them
-'C' stands for 'Client' and 'S' stands for 'Server'.
-
-3.1 Server greeting
--------------------
-
-S: {"QMP": {"version": {"qemu": "0.12.50", "package": ""}, "capabilities": []}}
-
-3.2 Simple 'stop' execution
----------------------------
-
-C: { "execute": "stop" }
-S: {"return": {}}
-
-3.3 KVM information
--------------------
-
-C: { "execute": "query-kvm", "id": "example" }
-S: {"return": {"enabled": true, "present": true}, "id": "example"}
-
-3.4 Parsing error
-------------------
-
-C: { "execute": }
-S: {"error": {"class": "GenericError", "desc": "Invalid JSON syntax" } }
-
-3.5 Powerdown event
--------------------
-
-S: {"timestamp": {"seconds": 1258551470, "microseconds": 802384}, "event":
-"POWERDOWN"}
-
-4. Capabilities Negotiation
-----------------------------
-
-When a Client successfully establishes a connection, the Server is in
-Capabilities Negotiation mode.
-
-In this mode only the 'qmp_capabilities' command is allowed to run, all
-other commands will return the CommandNotFound error. Asynchronous messages
-are not delivered either.
-
-Clients should use the 'qmp_capabilities' command to enable capabilities
-advertised in the Server's greeting (section '2.2 Server Greeting') they
-support.
-
-When the 'qmp_capabilities' command is issued, and if it does not return an
-error, the Server enters in Command mode where capabilities changes take
-effect, all commands (except 'qmp_capabilities') are allowed and asynchronous
-messages are delivered.
-
-5 Compatibility Considerations
-------------------------------
-
-All protocol changes or new features which modify the protocol format in an
-incompatible way are disabled by default and will be advertised by the
-capabilities array (section '2.2 Server Greeting'). Thus, Clients can check
-that array and enable the capabilities they support.
-
-The QMP Server performs a type check on the arguments to a command. It
-generates an error if a value does not have the expected type for its
-key, or if it does not understand a key that the Client included. The
-strictness of the Server catches wrong assumptions of Clients about
-the Server's schema. Clients can assume that, when such validation
-errors occur, they will be reported before the command generated any
-side effect.
-
-However, Clients must not assume any particular:
-
-- Length of json-arrays
-- Size of json-objects; in particular, future versions of QEMU may add
- new keys and Clients should be able to ignore them.
-- Order of json-object members or json-array elements
-- Amount of errors generated by a command, that is, new errors can be added
- to any existing command in newer versions of the Server
-
-Of course, the Server does guarantee to send valid JSON. But apart from
-this, a Client should be "conservative in what they send, and liberal in
-what they accept".
-
-6. Downstream extension of QMP
-------------------------------
-
-We recommend that downstream consumers of QEMU do *not* modify QMP.
-Management tools should be able to support both upstream and downstream
-versions of QMP without special logic, and downstream extensions are
-inherently at odds with that.
-
-However, we recognize that it is sometimes impossible for downstreams to
-avoid modifying QMP. Both upstream and downstream need to take care to
-preserve long-term compatibility and interoperability.
-
-To help with that, QMP reserves JSON object member names beginning with
-'__' (double underscore) for downstream use ("downstream names"). This
-means upstream will never use any downstream names for its commands,
-arguments, errors, asynchronous events, and so forth.
-
-Any new names downstream wishes to add must begin with '__'. To
-ensure compatibility with other downstreams, it is strongly
-recommended that you prefix your downstram names with '__RFQDN_' where
-RFQDN is a valid, reverse fully qualified domain name which you
-control. For example, a qemu-kvm specific monitor command would be:
-
- (qemu) __org.linux-kvm_enable_irqchip
-
-Downstream must not change the server greeting (section 2.2) other than
-to offer additional capabilities. But see below for why even that is
-discouraged.
-
-Section '5 Compatibility Considerations' applies to downstream as well
-as to upstream, obviously. It follows that downstream must behave
-exactly like upstream for any input not containing members with
-downstream names ("downstream members"), except it may add members
-with downstream names to its output.
-
-Thus, a client should not be able to distinguish downstream from
-upstream as long as it doesn't send input with downstream members, and
-properly ignores any downstream members in the output it receives.
-
-Advice on downstream modifications:
-
-1. Introducing new commands is okay. If you want to extend an existing
- command, consider introducing a new one with the new behaviour
- instead.
-
-2. Introducing new asynchronous messages is okay. If you want to extend
- an existing message, consider adding a new one instead.
-
-3. Introducing new errors for use in new commands is okay. Adding new
- errors to existing commands counts as extension, so 1. applies.
-
-4. New capabilities are strongly discouraged. Capabilities are for
- evolving the basic protocol, and multiple diverging basic protocol
- dialects are most undesirable.
diff --git a/QMP/qmp.py b/QMP/qmp.py
deleted file mode 100644
index 074f09a063..0000000000
--- a/QMP/qmp.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# QEMU Monitor Protocol Python class
-#
-# Copyright (C) 2009, 2010 Red Hat Inc.
-#
-# Authors:
-# Luiz Capitulino <lcapitulino@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2. See
-# the COPYING file in the top-level directory.
-
-import json
-import errno
-import socket
-
-class QMPError(Exception):
- pass
-
-class QMPConnectError(QMPError):
- pass
-
-class QMPCapabilitiesError(QMPError):
- pass
-
-class QEMUMonitorProtocol:
- def __init__(self, address, server=False):
- """
- Create a QEMUMonitorProtocol class.
-
- @param address: QEMU address, can be either a unix socket path (string)
- or a tuple in the form ( address, port ) for a TCP
- connection
- @param server: server mode listens on the socket (bool)
- @raise socket.error on socket connection errors
- @note No connection is established, this is done by the connect() or
- accept() methods
- """
- self.__events = []
- self.__address = address
- self.__sock = self.__get_sock()
- if server:
- self.__sock.bind(self.__address)
- self.__sock.listen(1)
-
- def __get_sock(self):
- if isinstance(self.__address, tuple):
- family = socket.AF_INET
- else:
- family = socket.AF_UNIX
- return socket.socket(family, socket.SOCK_STREAM)
-
- def __negotiate_capabilities(self):
- greeting = self.__json_read()
- if greeting is None or not greeting.has_key('QMP'):
- raise QMPConnectError
- # Greeting seems ok, negotiate capabilities
- resp = self.cmd('qmp_capabilities')
- if "return" in resp:
- return greeting
- raise QMPCapabilitiesError
-
- def __json_read(self, only_event=False):
- while True:
- data = self.__sockfile.readline()
- if not data:
- return
- resp = json.loads(data)
- if 'event' in resp:
- self.__events.append(resp)
- if not only_event:
- continue
- return resp
-
- error = socket.error
-
- def connect(self, negotiate=True):
- """
- Connect to the QMP Monitor and perform capabilities negotiation.
-
- @return QMP greeting dict
- @raise socket.error on socket connection errors
- @raise QMPConnectError if the greeting is not received
- @raise QMPCapabilitiesError if fails to negotiate capabilities
- """
- self.__sock.connect(self.__address)
- self.__sockfile = self.__sock.makefile()
- if negotiate:
- return self.__negotiate_capabilities()
-
- def accept(self):
- """
- Await connection from QMP Monitor and perform capabilities negotiation.
-
- @return QMP greeting dict
- @raise socket.error on socket connection errors
- @raise QMPConnectError if the greeting is not received
- @raise QMPCapabilitiesError if fails to negotiate capabilities
- """
- self.__sock, _ = self.__sock.accept()
- self.__sockfile = self.__sock.makefile()
- return self.__negotiate_capabilities()
-
- def cmd_obj(self, qmp_cmd):
- """
- Send a QMP command to the QMP Monitor.
-
- @param qmp_cmd: QMP command to be sent as a Python dict
- @return QMP response as a Python dict or None if the connection has
- been closed
- """
- try:
- self.__sock.sendall(json.dumps(qmp_cmd))
- except socket.error, err:
- if err[0] == errno.EPIPE:
- return
- raise socket.error(err)
- return self.__json_read()
-
- def cmd(self, name, args=None, id=None):
- """
- Build a QMP command and send it to the QMP Monitor.
-
- @param name: command name (string)
- @param args: command arguments (dict)
- @param id: command id (dict, list, string or int)
- """
- qmp_cmd = { 'execute': name }
- if args:
- qmp_cmd['arguments'] = args
- if id:
- qmp_cmd['id'] = id
- return self.cmd_obj(qmp_cmd)
-
- def command(self, cmd, **kwds):
- ret = self.cmd(cmd, kwds)
- if ret.has_key('error'):
- raise Exception(ret['error']['desc'])
- return ret['return']
-
- def pull_event(self, wait=False):
- """
- Get and delete the first available QMP event.
-
- @param wait: block until an event is available (bool)
- """
- self.__sock.setblocking(0)
- try:
- self.__json_read()
- except socket.error, err:
- if err[0] == errno.EAGAIN:
- # No data available
- pass
- self.__sock.setblocking(1)
- if not self.__events and wait:
- self.__json_read(only_event=True)
- event = self.__events[0]
- del self.__events[0]
- return event
-
- def get_events(self, wait=False):
- """
- Get a list of available QMP events.
-
- @param wait: block until an event is available (bool)
- """
- self.__sock.setblocking(0)
- try:
- self.__json_read()
- except socket.error, err:
- if err[0] == errno.EAGAIN:
- # No data available
- pass
- self.__sock.setblocking(1)
- if not self.__events and wait:
- self.__json_read(only_event=True)
- return self.__events
-
- def clear_events(self):
- """
- Clear current list of pending events.
- """
- self.__events = []
-
- def close(self):
- self.__sock.close()
- self.__sockfile.close()
-
- timeout = socket.timeout
-
- def settimeout(self, timeout):
- self.__sock.settimeout(timeout)
-
- def get_sock_fd(self):
- return self.__sock.fileno()
-
- def is_scm_available(self):
- return self.__sock.family == socket.AF_UNIX
diff --git a/QMP/qom-fuse b/QMP/qom-fuse
deleted file mode 100755
index 5c6754aa63..0000000000
--- a/QMP/qom-fuse
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/python
-##
-# QEMU Object Model test tools
-#
-# Copyright IBM, Corp. 2012
-#
-# Authors:
-# Anthony Liguori <aliguori@us.ibm.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or later. See
-# the COPYING file in the top-level directory.
-##
-
-import fuse, stat
-from fuse import Fuse
-import os, posix
-from errno import *
-from qmp import QEMUMonitorProtocol
-
-fuse.fuse_python_api = (0, 2)
-
-class QOMFS(Fuse):
- def __init__(self, qmp, *args, **kwds):
- Fuse.__init__(self, *args, **kwds)
- self.qmp = qmp
- self.qmp.connect()
- self.ino_map = {}
- self.ino_count = 1
-
- def get_ino(self, path):
- if self.ino_map.has_key(path):
- return self.ino_map[path]
- self.ino_map[path] = self.ino_count
- self.ino_count += 1
- return self.ino_map[path]
-
- def is_object(self, path):
- try:
- items = self.qmp.command('qom-list', path=path)
- return True
- except:
- return False
-
- def is_property(self, path):
- try:
- path, prop = path.rsplit('/', 1)
- for item in self.qmp.command('qom-list', path=path):
- if item['name'] == prop:
- return True
- return False
- except:
- return False
-
- def is_link(self, path):
- try:
- path, prop = path.rsplit('/', 1)
- for item in self.qmp.command('qom-list', path=path):
- if item['name'] == prop:
- if item['type'].startswith('link<'):
- return True
- return False
- return False
- except:
- return False
-
- def read(self, path, length, offset):
- if not self.is_property(path):
- return -ENOENT
-
- path, prop = path.rsplit('/', 1)
- try:
- data = str(self.qmp.command('qom-get', path=path, property=prop))
- data += '\n' # make values shell friendly
- except:
- return -EPERM
-
- if offset > len(data):
- return ''
-
- return str(data[offset:][:length])
-
- def readlink(self, path):
- if not self.is_link(path):
- return False
- path, prop = path.rsplit('/', 1)
- prefix = '/'.join(['..'] * (len(path.split('/')) - 1))
- return prefix + str(self.qmp.command('qom-get', path=path,
- property=prop))
-
- def getattr(self, path):
- if self.is_link(path):
- value = posix.stat_result((0755 | stat.S_IFLNK,
- self.get_ino(path),
- 0,
- 2,
- 1000,
- 1000,
- 4096,
- 0,
- 0,
- 0))
- elif self.is_object(path):
- value = posix.stat_result((0755 | stat.S_IFDIR,
- self.get_ino(path),
- 0,
- 2,
- 1000,
- 1000,
- 4096,
- 0,
- 0,
- 0))
- elif self.is_property(path):
- value = posix.stat_result((0644 | stat.S_IFREG,
- self.get_ino(path),
- 0,
- 1,
- 1000,
- 1000,
- 4096,
- 0,
- 0,
- 0))
- else:
- value = -ENOENT
- return value
-
- def readdir(self, path, offset):
- yield fuse.Direntry('.')
- yield fuse.Direntry('..')
- for item in self.qmp.command('qom-list', path=path):
- yield fuse.Direntry(str(item['name']))
-
-if __name__ == '__main__':
- import sys, os
-
- fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET']))
- fs.main(sys.argv)
diff --git a/QMP/qom-get b/QMP/qom-get
deleted file mode 100755
index 0172c69441..0000000000
--- a/QMP/qom-get
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/python
-##
-# QEMU Object Model test tools
-#
-# Copyright IBM, Corp. 2011
-#
-# Authors:
-# Anthony Liguori <aliguori@us.ibm.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or later. See
-# the COPYING file in the top-level directory.
-##
-
-import sys
-import os
-from qmp import QEMUMonitorProtocol
-
-cmd, args = sys.argv[0], sys.argv[1:]
-socket_path = None
-path = None
-prop = None
-
-def usage():
- return '''environment variables:
- QMP_SOCKET=<path | addr:port>
-usage:
- %s [-h] [-s <QMP socket path | addr:port>] <path>.<property>
-''' % cmd
-
-def usage_error(error_msg = "unspecified error"):
- sys.stderr.write('%s\nERROR: %s\n' % (usage(), error_msg))
- exit(1)
-
-if len(args) > 0:
- if args[0] == "-h":
- print usage()
- exit(0);
- elif args[0] == "-s":
- try:
- socket_path = args[1]
- except:
- usage_error("missing argument: QMP socket path or address");
- args = args[2:]
-
-if not socket_path:
- if os.environ.has_key('QMP_SOCKET'):
- socket_path = os.environ['QMP_SOCKET']
- else:
- usage_error("no QMP socket path or address given");
-
-if len(args) > 0:
- try:
- path, prop = args[0].rsplit('.', 1)
- except:
- usage_error("invalid format for path/property/value")
-else:
- usage_error("not enough arguments")
-
-srv = QEMUMonitorProtocol(socket_path)
-srv.connect()
-
-rsp = srv.command('qom-get', path=path, property=prop)
-if type(rsp) == dict:
- for i in rsp.keys():
- print '%s: %s' % (i, rsp[i])
-else:
- print rsp
diff --git a/QMP/qom-list b/QMP/qom-list
deleted file mode 100755
index 1e7cc6cb2d..0000000000
--- a/QMP/qom-list
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python
-##
-# QEMU Object Model test tools
-#
-# Copyright IBM, Corp. 2011
-#
-# Authors:
-# Anthony Liguori <aliguori@us.ibm.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or later. See
-# the COPYING file in the top-level directory.
-##
-
-import sys
-import os
-from qmp import QEMUMonitorProtocol
-
-cmd, args = sys.argv[0], sys.argv[1:]
-socket_path = None
-path = None
-prop = None
-
-def usage():
- return '''environment variables:
- QMP_SOCKET=<path | addr:port>
-usage:
- %s [-h] [-s <QMP socket path | addr:port>] [<path>]
-''' % cmd
-
-def usage_error(error_msg = "unspecified error"):
- sys.stderr.write('%s\nERROR: %s\n' % (usage(), error_msg))
- exit(1)
-
-if len(args) > 0:
- if args[0] == "-h":
- print usage()
- exit(0);
- elif args[0] == "-s":
- try:
- socket_path = args[1]
- except:
- usage_error("missing argument: QMP socket path or address");
- args = args[2:]
-
-if not socket_path:
- if os.environ.has_key('QMP_SOCKET'):
- socket_path = os.environ['QMP_SOCKET']
- else:
- usage_error("no QMP socket path or address given");
-
-srv = QEMUMonitorProtocol(socket_path)
-srv.connect()
-
-if len(args) == 0:
- print '/'
- sys.exit(0)
-
-for item in srv.command('qom-list', path=args[0]):
- if item['type'].startswith('child<'):
- print '%s/' % item['name']
- elif item['type'].startswith('link<'):
- print '@%s/' % item['name']
- else:
- print '%s' % item['name']
diff --git a/QMP/qom-set b/QMP/qom-set
deleted file mode 100755
index 54ecfecc53..0000000000
--- a/QMP/qom-set
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python
-##
-# QEMU Object Model test tools
-#
-# Copyright IBM, Corp. 2011
-#
-# Authors:
-# Anthony Liguori <aliguori@us.ibm.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or later. See
-# the COPYING file in the top-level directory.
-##
-
-import sys
-import os
-from qmp import QEMUMonitorProtocol
-
-cmd, args = sys.argv[0], sys.argv[1:]
-socket_path = None
-path = None
-prop = None
-value = None
-
-def usage():
- return '''environment variables:
- QMP_SOCKET=<path | addr:port>
-usage:
- %s [-h] [-s <QMP socket path | addr:port>] <path>.<property> <value>
-''' % cmd
-
-def usage_error(error_msg = "unspecified error"):
- sys.stderr.write('%s\nERROR: %s\n' % (usage(), error_msg))
- exit(1)
-
-if len(args) > 0:
- if args[0] == "-h":
- print usage()
- exit(0);
- elif args[0] == "-s":
- try:
- socket_path = args[1]
- except:
- usage_error("missing argument: QMP socket path or address");
- args = args[2:]
-
-if not socket_path:
- if os.environ.has_key('QMP_SOCKET'):
- socket_path = os.environ['QMP_SOCKET']
- else:
- usage_error("no QMP socket path or address given");
-
-if len(args) > 1:
- try:
- path, prop = args[0].rsplit('.', 1)
- except:
- usage_error("invalid format for path/property/value")
- value = args[1]
-else:
- usage_error("not enough arguments")
-
-srv = QEMUMonitorProtocol(socket_path)
-srv.connect()
-
-print srv.command('qom-set', path=path, property=prop, value=sys.argv[2])