From patchwork Wed Nov 10 18:59:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 70681 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 97854B7104 for ; Thu, 11 Nov 2010 06:04:07 +1100 (EST) Received: from localhost ([127.0.0.1]:56984 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PGFxi-0008L3-IU for incoming@patchwork.ozlabs.org; Wed, 10 Nov 2010 14:04:02 -0500 Received: from [140.186.70.92] (port=35630 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PGFtJ-000614-I5 for qemu-devel@nongnu.org; Wed, 10 Nov 2010 13:59:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PGFtH-0003Zx-PZ for qemu-devel@nongnu.org; Wed, 10 Nov 2010 13:59:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:63501) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PGFtH-0003Zc-Id for qemu-devel@nongnu.org; Wed, 10 Nov 2010 13:59:27 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oAAIxQNq000480 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 10 Nov 2010 13:59:26 -0500 Received: from localhost (ovpn-113-58.phx2.redhat.com [10.3.113.58]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oAAIxPut032361; Wed, 10 Nov 2010 13:59:26 -0500 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Wed, 10 Nov 2010 16:59:06 -0200 Message-Id: <1289415546-19105-4-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1289415546-19105-1-git-send-email-lcapitulino@redhat.com> References: <1289415546-19105-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: aliguori@us.ibm.com, armbru@redhat.com Subject: [Qemu-devel] [PATCH 3/3] QMP/qmp-shell: Introduce HMP mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org In which qmp-shell will exclusively use the HMP passthrough feature, this is useful for testing. Example: # ./qmp-shell -H qmp-sock Welcome to the HMP shell! Connected to QEMU 0.13.50 (QEMU) info network VLAN 0 devices: user.0: net=10.0.2.0, restricted=n e1000.0: model=e1000,macaddr=52:54:00:12:34:56 Devices not on any VLAN: (QEMU) Signed-off-by: Luiz Capitulino --- QMP/qmp-shell | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 74 insertions(+), 1 deletions(-) diff --git a/QMP/qmp-shell b/QMP/qmp-shell index 1fb7e76..ce0d259 100755 --- a/QMP/qmp-shell +++ b/QMP/qmp-shell @@ -145,6 +145,72 @@ class QMPShell(qmp.QEMUMonitorProtocol): 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): + return self.cmd_obj({ 'execute': 'hmp_passthrough', 'arguments': + { 'command-line': cmdline, + 'cpu-index': self.__cpu_index } }) + + def _execute_cmd(self, cmdline): + if cmdline.split()[0] == "cpu": + # trap the cpu command, it requires special setting + try: + self.__cpu_index = int(cmdline.split()[1]) + except ValueError: + print 'cpu command takes an integer argument' + return True + resp = self.__cmd_passthrough(cmdline) + 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) @@ -156,9 +222,16 @@ def fail_cmdline(option=None): sys.exit(1) def main(): + addr = '' try: if len(sys.argv) == 2: qemu = QMPShell(sys.argv[1]) + addr = sys.argv[1] + elif len(sys.argv) == 3: + if sys.argv[1] != '-H': + fail_cmdline(sys.argv[1]) + qemu = HMPShell(sys.argv[2]) + addr = sys.argv[2] else: fail_cmdline() except QMPShellBadPort: @@ -171,7 +244,7 @@ def main(): except qmp.QMPCapabilitiesError: die('Could not negotiate capabilities') except qemu.error: - die('Could not connect to %s' % sys.argv[1]) + die('Could not connect to %s' % addr) qemu.show_banner() while qemu.read_exec_command('(QEMU) '):