qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/6] QMP: add scripts/qmp


From: Luiz Capitulino
Subject: [Qemu-devel] [PATCH 1/6] QMP: add scripts/qmp
Date: Wed, 11 Sep 2013 16:52:12 -0400

Populate it with all scripts stored in QMP/.

Signed-off-by: Luiz Capitulino <address@hidden>
---
 QMP/qemu-ga-client         | 299 ---------------------------------------------
 QMP/qmp                    | 126 -------------------
 QMP/qmp-shell              | 286 -------------------------------------------
 QMP/qmp.py                 | 190 ----------------------------
 QMP/qom-fuse               | 138 ---------------------
 QMP/qom-get                |  67 ----------
 QMP/qom-list               |  64 ----------
 QMP/qom-set                |  64 ----------
 scripts/qmp/qemu-ga-client | 299 +++++++++++++++++++++++++++++++++++++++++++++
 scripts/qmp/qmp            | 126 +++++++++++++++++++
 scripts/qmp/qmp-shell      | 286 +++++++++++++++++++++++++++++++++++++++++++
 scripts/qmp/qmp.py         | 190 ++++++++++++++++++++++++++++
 scripts/qmp/qom-fuse       | 138 +++++++++++++++++++++
 scripts/qmp/qom-get        |  67 ++++++++++
 scripts/qmp/qom-list       |  64 ++++++++++
 scripts/qmp/qom-set        |  64 ++++++++++
 16 files changed, 1234 insertions(+), 1234 deletions(-)
 delete mode 100755 QMP/qemu-ga-client
 delete mode 100755 QMP/qmp
 delete mode 100755 QMP/qmp-shell
 delete mode 100644 QMP/qmp.py
 delete mode 100755 QMP/qom-fuse
 delete mode 100755 QMP/qom-get
 delete mode 100755 QMP/qom-list
 delete mode 100755 QMP/qom-set
 create mode 100755 scripts/qmp/qemu-ga-client
 create mode 100755 scripts/qmp/qmp
 create mode 100755 scripts/qmp/qmp-shell
 create mode 100644 scripts/qmp/qmp.py
 create mode 100755 scripts/qmp/qom-fuse
 create mode 100755 scripts/qmp/qom-get
 create mode 100755 scripts/qmp/qom-list
 create mode 100755 scripts/qmp/qom-set

diff --git a/QMP/qemu-ga-client b/QMP/qemu-ga-client
deleted file mode 100755
index 46676c3..0000000
--- a/QMP/qemu-ga-client
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/python
-
-# QEMU Guest Agent Client
-#
-# Copyright (C) 2012 Ryota Ozaki <address@hidden>
-#
-# 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 != '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 1db3c7f..0000000
--- a/QMP/qmp
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/python
-#
-# QMP command line tool
-#
-# Copyright IBM, Corp. 2011
-#
-# Authors:
-#  Anthony Liguori <address@hidden>
-#
-# 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-shell b/QMP/qmp-shell
deleted file mode 100755
index 73cb3b6..0000000
--- 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 <address@hidden>
-#
-# 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.py b/QMP/qmp.py
deleted file mode 100644
index c551df1..0000000
--- a/QMP/qmp.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# QEMU Monitor Protocol Python class
-# 
-# Copyright (C) 2009, 2010 Red Hat Inc.
-#
-# Authors:
-#  Luiz Capitulino <address@hidden>
-#
-# 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)
diff --git a/QMP/qom-fuse b/QMP/qom-fuse
deleted file mode 100755
index 5c6754a..0000000
--- 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   <address@hidden>
-#
-# 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 0172c69..0000000
--- 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   <address@hidden>
-#
-# 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 1e7cc6c..0000000
--- 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   <address@hidden>
-#
-# 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 54ecfec..0000000
--- 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   <address@hidden>
-#
-# 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])
diff --git a/scripts/qmp/qemu-ga-client b/scripts/qmp/qemu-ga-client
new file mode 100755
index 0000000..46676c3
--- /dev/null
+++ b/scripts/qmp/qemu-ga-client
@@ -0,0 +1,299 @@
+#!/usr/bin/python
+
+# QEMU Guest Agent Client
+#
+# Copyright (C) 2012 Ryota Ozaki <address@hidden>
+#
+# 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 != '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/scripts/qmp/qmp b/scripts/qmp/qmp
new file mode 100755
index 0000000..1db3c7f
--- /dev/null
+++ b/scripts/qmp/qmp
@@ -0,0 +1,126 @@
+#!/usr/bin/python
+#
+# QMP command line tool
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori <address@hidden>
+#
+# 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/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
new file mode 100755
index 0000000..73cb3b6
--- /dev/null
+++ b/scripts/qmp/qmp-shell
@@ -0,0 +1,286 @@
+#!/usr/bin/python
+#
+# Low-level QEMU shell on top of QMP.
+#
+# Copyright (C) 2009, 2010 Red Hat Inc.
+#
+# Authors:
+#  Luiz Capitulino <address@hidden>
+#
+# 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/scripts/qmp/qmp.py b/scripts/qmp/qmp.py
new file mode 100644
index 0000000..c551df1
--- /dev/null
+++ b/scripts/qmp/qmp.py
@@ -0,0 +1,190 @@
+# QEMU Monitor Protocol Python class
+# 
+# Copyright (C) 2009, 2010 Red Hat Inc.
+#
+# Authors:
+#  Luiz Capitulino <address@hidden>
+#
+# 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)
diff --git a/scripts/qmp/qom-fuse b/scripts/qmp/qom-fuse
new file mode 100755
index 0000000..5c6754a
--- /dev/null
+++ b/scripts/qmp/qom-fuse
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2012
+#
+# Authors:
+#  Anthony Liguori   <address@hidden>
+#
+# 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/scripts/qmp/qom-get b/scripts/qmp/qom-get
new file mode 100755
index 0000000..0172c69
--- /dev/null
+++ b/scripts/qmp/qom-get
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <address@hidden>
+#
+# 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/scripts/qmp/qom-list b/scripts/qmp/qom-list
new file mode 100755
index 0000000..1e7cc6c
--- /dev/null
+++ b/scripts/qmp/qom-list
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <address@hidden>
+#
+# 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/scripts/qmp/qom-set b/scripts/qmp/qom-set
new file mode 100755
index 0000000..54ecfec
--- /dev/null
+++ b/scripts/qmp/qom-set
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <address@hidden>
+#
+# 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])
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]