From a2f3453ebc64b1ebe094aeaf83f9e67896f90ac3 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 27 Apr 2017 16:58:14 -0500 Subject: coccinelle: Add script to remove useless QObject casts We have macros in place to make it less verbose to add a subtype of QObject to both QDict and QList. While we have made cleanups like this in the past (see commit fcfcd8ffc, for example), having it be automated by Coccinelle makes it easier to maintain. The script is separate from the cleanups, for ease of review and backporting. A later patch will then add further possible cleanups. Signed-off-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20170427215821.19397-4-eblake@redhat.com> Signed-off-by: Markus Armbruster --- scripts/coccinelle/qobject.cocci | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 scripts/coccinelle/qobject.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci new file mode 100644 index 0000000..aa899e2 --- /dev/null +++ b/scripts/coccinelle/qobject.cocci @@ -0,0 +1,13 @@ +// Use QDict macros where they make sense +@@ +expression Obj, Key, E; +@@ +- qdict_put_obj(Obj, Key, QOBJECT(E)); ++ qdict_put(Obj, Key, E); + +// Use QList macros where they make sense +@@ +expression Obj, E; +@@ +- qlist_append_obj(Obj, QOBJECT(E)); ++ qlist_append(Obj, E); -- cgit v1.1 From a92c21591b5bb9543996538f14854ca6b528318b Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 27 Apr 2017 16:58:16 -0500 Subject: qobject: Add helper macros for common scalar insertions Rather than making lots of callers wrap a scalar in a QInt, QString, or QBool, provide helper macros that do the wrapping automatically. Update the Coccinelle script to make mass conversions easy, although the conversion itself will be done as a separate patches to ease review and backport efforts. Signed-off-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20170427215821.19397-6-eblake@redhat.com> Signed-off-by: Markus Armbruster --- scripts/coccinelle/qobject.cocci | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'scripts') diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci index aa899e2..97703a4 100644 --- a/scripts/coccinelle/qobject.cocci +++ b/scripts/coccinelle/qobject.cocci @@ -2,12 +2,34 @@ @@ expression Obj, Key, E; @@ +( - qdict_put_obj(Obj, Key, QOBJECT(E)); + qdict_put(Obj, Key, E); +| +- qdict_put(Obj, Key, qint_from_int(E)); ++ qdict_put_int(Obj, Key, E); +| +- qdict_put(Obj, Key, qbool_from_bool(E)); ++ qdict_put_bool(Obj, Key, E); +| +- qdict_put(Obj, Key, qstring_from_str(E)); ++ qdict_put_str(Obj, Key, E); +) // Use QList macros where they make sense @@ expression Obj, E; @@ +( - qlist_append_obj(Obj, QOBJECT(E)); + qlist_append(Obj, E); +| +- qlist_append(Obj, qint_from_int(E)); ++ qlist_append_int(Obj, E); +| +- qlist_append(Obj, qbool_from_bool(E)); ++ qlist_append_bool(Obj, E); +| +- qlist_append(Obj, qstring_from_str(E)); ++ qlist_append_str(Obj, E); +) -- cgit v1.1 From aa3b167f21588a87e7783ac29aa54b0c721eb37a Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 27 Apr 2017 18:36:28 -0400 Subject: qmp-shell: add persistent command history Use the existing readline history function we are utilizing to provide persistent command history across instances of qmp-shell. This assists entering debug commands across sessions that may be interrupted by QEMU sessions terminating, where the qmp-shell has to be relaunched. Signed-off-by: John Snow Message-Id: <20170427223628.20893-1-jsnow@redhat.com> Reviewed-by: Stefan Hajnoczi Reviewed-by: Kashyap Chamarthy Tested-by: Kashyap Chamarthy Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'scripts') diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index eccb88a..6ece6e7 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -70,6 +70,9 @@ import json import ast import readline import sys +import os +import errno +import atexit class QMPCompleter(list): def complete(self, text, state): @@ -109,6 +112,8 @@ class QMPShell(qmp.QEMUMonitorProtocol): self._pretty = pretty self._transmode = False self._actions = list() + self._histfile = os.path.join(os.path.expanduser('~'), + '.qmp-shell_history') def __get_address(self, arg): """ @@ -132,11 +137,27 @@ class QMPShell(qmp.QEMUMonitorProtocol): def __completer_setup(self): self._completer = QMPCompleter() self._fill_completion() + readline.set_history_length(1024) 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('') + try: + readline.read_history_file(self._histfile) + except Exception as e: + if isinstance(e, IOError) and e.errno == errno.ENOENT: + # File not found. No problem. + pass + else: + print "Failed to read history '%s'; %s" % (self._histfile, e) + atexit.register(self.__save_history) + + def __save_history(self): + try: + readline.write_history_file(self._histfile) + except Exception as e: + print "Failed to save history file '%s'; %s" % (self._histfile, e) def __parse_value(self, val): try: -- cgit v1.1 From c5e397df9e247bff2398400864cde94d1b40317c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 4 May 2017 16:54:29 +0400 Subject: qmp-shell: add -N option to skip negotiate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu-ga doesn't have negotiate phase. Signed-off-by: Marc-André Lureau Message-Id: <20170504125432.21653-2-marcandre.lureau@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 6ece6e7..b4d2dbd 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -277,8 +277,8 @@ class QMPShell(qmp.QEMUMonitorProtocol): self._print(resp) return True - def connect(self): - self._greeting = qmp.QEMUMonitorProtocol.connect(self) + def connect(self, negotiate): + self._greeting = qmp.QEMUMonitorProtocol.connect(self, negotiate) self.__completer_setup() def show_banner(self, msg='Welcome to the QMP low-level shell!'): @@ -390,7 +390,7 @@ def die(msg): def fail_cmdline(option=None): if option: sys.stderr.write('ERROR: bad command-line option \'%s\'\n' % option) - sys.stderr.write('qemu-shell [ -v ] [ -p ] [ -H ] < UNIX socket path> | < TCP address:port >\n') + sys.stderr.write('qemu-shell [ -v ] [ -p ] [ -H ] [ -N ] < UNIX socket path> | < TCP address:port >\n') sys.exit(1) def main(): @@ -399,6 +399,7 @@ def main(): hmp = False pretty = False verbose = False + negotiate = True try: for arg in sys.argv[1:]: @@ -408,6 +409,8 @@ def main(): hmp = True elif arg == "-p": pretty = True + elif arg == "-N": + negotiate = False elif arg == "-v": verbose = True else: @@ -425,7 +428,7 @@ def main(): die('bad port number in command-line') try: - qemu.connect() + qemu.connect(negotiate) except qmp.QMPConnectError: die('Didn\'t get QMP greeting message') except qmp.QMPCapabilitiesError: -- cgit v1.1 From daa5a72ebab20345da474ee2f6148a8dacd2cb17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 4 May 2017 16:54:30 +0400 Subject: qmp-shell: Cope with query-commands error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu-ga doesn't implement it. Signed-off-by: Marc-André Lureau Message-Id: <20170504125432.21653-3-marcandre.lureau@redhat.com> Reviewed-by: Eric Blake [Commit message tweaked] Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index b4d2dbd..1182f82 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -131,7 +131,10 @@ class QMPShell(qmp.QEMUMonitorProtocol): return arg def _fill_completion(self): - for cmd in self.cmd('query-commands')['return']: + cmds = self.cmd('query-commands') + if cmds.has_key('error'): + return + for cmd in cmds['return']: self._completer.append(cmd['name']) def __completer_setup(self): -- cgit v1.1 From b13d2ff3de2d1f79107a376e883bcb8336f75d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 4 May 2017 16:54:31 +0400 Subject: qmp-shell: don't show version greeting if unavailable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu-ga doesn't have greeting. Signed-off-by: Marc-André Lureau Message-Id: <20170504125432.21653-4-marcandre.lureau@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 3 +++ 1 file changed, 3 insertions(+) (limited to 'scripts') diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 1182f82..5986e37 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -286,6 +286,9 @@ class QMPShell(qmp.QEMUMonitorProtocol): def show_banner(self, msg='Welcome to the QMP low-level shell!'): print msg + if not self._greeting: + print 'Connected' + return version = self._greeting['QMP']['version']['qemu'] print 'Connected to QEMU %d.%d.%d\n' % (version['major'],version['minor'],version['micro']) -- cgit v1.1 From dcd3b25d656d346205dc0f2254723fccf0264e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 4 May 2017 16:54:32 +0400 Subject: qmp-shell: improve help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Describe the arguments & fix the tool name. Signed-off-by: Marc-André Lureau Message-Id: <20170504125432.21653-5-marcandre.lureau@redhat.com> Reviewed-by: Eric Blake Signed-off-by: Markus Armbruster --- scripts/qmp/qmp-shell | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell index 5986e37..860ffb2 100755 --- a/scripts/qmp/qmp-shell +++ b/scripts/qmp/qmp-shell @@ -396,7 +396,11 @@ def die(msg): def fail_cmdline(option=None): if option: sys.stderr.write('ERROR: bad command-line option \'%s\'\n' % option) - sys.stderr.write('qemu-shell [ -v ] [ -p ] [ -H ] [ -N ] < UNIX socket path> | < TCP address:port >\n') + sys.stderr.write('qmp-shell [ -v ] [ -p ] [ -H ] [ -N ] < UNIX socket path> | < TCP address:port >\n') + sys.stderr.write(' -v Verbose (echo command sent and received)\n') + sys.stderr.write(' -p Pretty-print JSON\n') + sys.stderr.write(' -H Use HMP interface\n') + sys.stderr.write(' -N Skip negotiate (for qemu-ga)\n') sys.exit(1) def main(): -- cgit v1.1