qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Luiz Capitulino <lcapitulino@redhat.com>
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com, armbru@redhat.com, avi@redhat.com
Subject: [Qemu-devel] [PATCH 3/3] QMP/qmp-shell: Introduce HMP mode
Date: Tue, 16 Nov 2010 17:19:44 -0200	[thread overview]
Message-ID: <1289935184-16898-4-git-send-email-lcapitulino@redhat.com> (raw)
In-Reply-To: <1289935184-16898-1-git-send-email-lcapitulino@redhat.com>

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 <lcapitulino@redhat.com>
---
 QMP/qmp-shell |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/QMP/qmp-shell b/QMP/qmp-shell
index 1fb7e76..42dabc8 100755
--- a/QMP/qmp-shell
+++ b/QMP/qmp-shell
@@ -145,6 +145,76 @@ 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, 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)
@@ -156,9 +226,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 +248,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) '):
-- 
1.7.3.2.168.gd6b63

  parent reply	other threads:[~2010-11-16 19:20 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-16 19:19 [Qemu-devel] [PATCH v4 0/3]: QMP: Human Monitor passthrough Luiz Capitulino
2010-11-16 19:19 ` [Qemu-devel] [PATCH 1/3] qemu-char: Introduce Memory driver Luiz Capitulino
2010-11-16 19:19 ` [Qemu-devel] [PATCH 2/3] QMP: Introduce Human Monitor passthrough command Luiz Capitulino
2010-11-16 19:19 ` Luiz Capitulino [this message]
2010-11-17 10:27 ` [Qemu-devel] [PATCH v4 0/3]: QMP: Human Monitor passthrough Markus Armbruster
2010-11-17 12:39   ` Luiz Capitulino
  -- strict thread matches above, loose matches on Subject: below --
2010-11-11 19:31 [Qemu-devel] [PATCH v3 " Luiz Capitulino
2010-11-11 19:31 ` [Qemu-devel] [PATCH 3/3] QMP/qmp-shell: Introduce HMP mode Luiz Capitulino
2010-11-10 18:59 [Qemu-devel] [PATCH v2 0/3]: QMP: Human Monitor passthrough Luiz Capitulino
2010-11-10 18:59 ` [Qemu-devel] [PATCH 3/3] QMP/qmp-shell: Introduce HMP mode Luiz Capitulino
2010-10-29 14:28 [Qemu-devel] [PATCH v1 0/3]: QMP: Human Monitor passthrough Luiz Capitulino
2010-10-29 14:28 ` [Qemu-devel] [PATCH 3/3] QMP/qmp-shell: Introduce HMP mode Luiz Capitulino
2010-11-10 13:22   ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1289935184-16898-4-git-send-email-lcapitulino@redhat.com \
    --to=lcapitulino@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=armbru@redhat.com \
    --cc=avi@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).