qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/10] QMP queue
@ 2015-05-08 13:34 Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 01/10] monitor: add memory search commands s, sp Luiz Capitulino
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

The following changes since commit f8340b360b9bc29d48716ba8aca79df2b9544979:

  hw/ptimer: Do not artificially limit timers when using icount (2015-05-08 17:15:23 +1000)

are available in the git repository at:

  git://repo.or.cz/qemu/qmp-unstable.git tags/for-upstream

for you to fetch changes up to 07972d16e3343dc62302b81efb018308f99f7a7a:

  scripts: qmp-shell: Add verbose flag (2015-05-08 08:47:01 -0400)

----------------------------------------------------------------
QMP pull request

----------------------------------------------------------------
Claudio Fontana (1):
      monitor: add memory search commands s, sp

Eduardo Habkost (1):
      QJSON: Use OBJECT_CHECK

Eric Blake (1):
      json-parser: Accept 'null' in QMP

John Snow (4):
      scripts: qmp-shell: refactor helpers
      scripts: qmp-shell: Expand support for QMP expressions
      scripts: qmp-shell: add transaction subshell
      scripts: qmp-shell: Add verbose flag

Luiz Capitulino (1):
      MAINTAINERS: New maintainer for QMP and QAPI

Markus Armbruster (2):
      qobject: Clean up around qtype_code
      qobject: Add a special null QObject

 MAINTAINERS                |  18 +++---
 block/qapi.c               |   3 -
 hmp-commands.hx            |  28 +++++++++
 include/hw/qdev-core.h     |   2 +-
 include/qapi/qmp/qobject.h |  13 +++-
 monitor.c                  | 140 ++++++++++++++++++++++++++++++++++++++++++
 qjson.c                    |  10 +--
 qobject/Makefile.objs      |   2 +-
 qobject/json-parser.c      |   2 +
 qobject/qjson.c            |   6 +-
 qobject/qnull.c            |  29 +++++++++
 scripts/qmp/qmp-shell      | 147 +++++++++++++++++++++++++++++++++++----------
 tests/check-qjson.c        |  15 ++++-
 13 files changed, 359 insertions(+), 56 deletions(-)
 create mode 100644 qobject/qnull.c

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 01/10] monitor: add memory search commands s, sp
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 02/10] QJSON: Use OBJECT_CHECK Luiz Capitulino
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: Claudio Fontana <claudio.fontana@huawei.com>

usage is similar to the commands x, xp.

Example with string: looking for "ELF" header in memory:

(qemu) s/1000000cb 0x40001000 "ELF"
searching memory area [0000000040001000-00000000400f5240]
0000000040090001
(qemu) x/20b 0x40090000
0000000040090000: '\x7f' 'E' 'L' 'F' '\x02' '\x01' '\x01' '\x03'
0000000040090008: '\x00' '\x00' '\x00' '\x00' '\x00' '\x00' '\x00' '\x00'
0000000040090010: '\x02' '\x00' '\xb7' '\x00'

Example with value: looking for 64bit variable value 0x990088

(qemu) s/1000000xg 0xffff900042000000 0x990088
searching memory area [ffff900042000000-ffff9000427a1200]
ffff9000424b3000
ffff9000424c1000

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hmp-commands.hx |  28 ++++++++++++
 monitor.c       | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e864a6c..badf1f5 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -430,6 +430,34 @@ Start gdbserver session (default @var{port}=1234)
 ETEXI
 
     {
+        .name       = "s",
+        .args_type  = "fmt:/,addr:l,data:s",
+        .params     = "/fmt addr data",
+        .help       = "search virtual memory starting at 'addr' for 'data'",
+        .mhandler.cmd = hmp_memory_search,
+    },
+
+STEXI
+@item s/fmt @var{addr} @var{data}
+@findex s
+Virtual memory search starting at @var{addr} for data described by @var{data}.
+ETEXI
+
+    {
+        .name       = "sp",
+        .args_type  = "fmt:/,addr:l,data:s",
+        .params     = "/fmt addr data",
+        .help       = "search physical memory starting at 'addr' for 'data'",
+        .mhandler.cmd = hmp_physical_memory_search,
+    },
+
+STEXI
+@item sp/fmt @var{addr} @var{data}
+@findex sp
+Physical memory search starting at @var{addr} for data described by @var{data}.
+ETEXI
+
+    {
         .name       = "x",
         .args_type  = "fmt:/,addr:l",
         .params     = "/fmt addr",
diff --git a/monitor.c b/monitor.c
index 3952d64..9611d4f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1205,6 +1205,124 @@ static void monitor_printc(Monitor *mon, int c)
     monitor_printf(mon, "'");
 }
 
+static void monitor_print_addr(Monitor *mon, hwaddr addr, bool is_physical)
+{
+    if (is_physical) {
+        monitor_printf(mon, TARGET_FMT_plx "\n", addr);
+    } else {
+        monitor_printf(mon, TARGET_FMT_lx "\n", (target_ulong)addr);
+    }
+}
+
+/* simple memory search for a byte sequence. The sequence is generated from
+ * a numeric value to look for in guest memory, or from a string.
+ */
+static void memory_search(Monitor *mon, int count, int format, int wsize,
+                          hwaddr addr, const char *data_str, bool is_physical)
+{
+    int pos, len;              /* pos in the search area, len of area */
+    char *hay;                 /* buffer for haystack */
+    int hay_size;              /* haystack size. Needle size is wsize. */
+    const char *needle = NULL; /* needle to search in the haystack */
+    const char *format_str;    /* numeric input format string */
+    char value_raw[8];         /* numeric input converted to raw data */
+#define MONITOR_S_CHUNK_SIZE 16000
+
+    len = wsize * count;
+    if (len < 1) {
+        monitor_printf(mon, "invalid search area length.\n");
+        return;
+    }
+    switch (format) {
+    case 'i':
+        monitor_printf(mon, "format '%c' not supported.\n", format);
+        return;
+    case 'c':
+        needle = data_str;
+        wsize = strlen(data_str);
+        if (wsize > MONITOR_S_CHUNK_SIZE) {
+            monitor_printf(mon, "search string too long [max %d].\n",
+                           MONITOR_S_CHUNK_SIZE);
+            return;
+        }
+        break;
+    case 'o':
+        format_str = "%" SCNo64;
+        break;
+    default:
+    case 'x':
+        format_str = "%" SCNx64;
+        break;
+    case 'u':
+        format_str = "%" SCNu64;
+        break;
+    case 'd':
+        format_str = "%" SCNd64;
+        break;
+    }
+    if (format != 'c') {
+        uint64_t value;      /* numeric input value */
+        void *from = &value;
+        if (sscanf(data_str, format_str, &value) != 1) {
+            monitor_printf(mon, "could not parse search string "
+                           "\"%s\" as format '%c'.\n", data_str, format);
+            return;
+        }
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+        value = bswap64(value);
+#endif
+#if defined(TARGET_WORDS_BIGENDIAN)
+        from += 8 - wsize;
+#endif
+        memcpy(value_raw, from, wsize);
+        needle = value_raw;
+    }
+    monitor_printf(mon, "searching memory area ");
+    if (is_physical) {
+        monitor_printf(mon, "[" TARGET_FMT_plx "-" TARGET_FMT_plx "]\n",
+                       addr, addr + len);
+    } else {
+        monitor_printf(mon, "[" TARGET_FMT_lx "-" TARGET_FMT_lx "]\n",
+                       (target_ulong)addr, (target_ulong)addr + len);
+    }
+    hay_size = len < MONITOR_S_CHUNK_SIZE ? len : MONITOR_S_CHUNK_SIZE;
+    hay = g_malloc0(hay_size);
+
+    for (pos = 0; pos < len;) {
+        char *mark, *match; /* mark new starting position, eventual match */
+        int l, todo;        /* total length to be processed in current chunk */
+        l = len - pos;
+        if (l > hay_size) {
+            l = hay_size;
+        }
+        if (is_physical) {
+            cpu_physical_memory_read(addr, hay, l);
+        } else if (cpu_memory_rw_debug(ENV_GET_CPU(mon_get_cpu()), addr,
+                                       (uint8_t *)hay, l, 0) < 0) {
+            monitor_printf(mon, " Cannot access memory\n");
+            break;
+        }
+        for (mark = hay, todo = l; todo >= wsize;) {
+            match = memmem(mark, todo, needle, wsize);
+            if (!match) {
+                break;
+            }
+            monitor_print_addr(mon, addr + (match - hay), is_physical);
+            mark = match + 1;
+            todo = mark - hay;
+        }
+        if (pos + l < len) {
+            /* catch potential matches across chunks. */
+            pos += l - (wsize - 1);
+            addr += l - (wsize - 1);
+        } else {
+            pos += l;
+            addr += l;
+        }
+    }
+    g_free(hay);
+}
+
 static void memory_dump(Monitor *mon, int count, int format, int wsize,
                         hwaddr addr, int is_physical)
 {
@@ -1329,6 +1447,28 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
     }
 }
 
+static void hmp_memory_search(Monitor *mon, const QDict *qdict)
+{
+    int count = qdict_get_int(qdict, "count");
+    int format = qdict_get_int(qdict, "format");
+    int size = qdict_get_int(qdict, "size");
+    target_long addr = qdict_get_int(qdict, "addr");
+    const char *data_str = qdict_get_str(qdict, "data");
+
+    memory_search(mon, count, format, size, addr, data_str, false);
+}
+
+static void hmp_physical_memory_search(Monitor *mon, const QDict *qdict)
+{
+    int count = qdict_get_int(qdict, "count");
+    int format = qdict_get_int(qdict, "format");
+    int size = qdict_get_int(qdict, "size");
+    hwaddr addr = qdict_get_int(qdict, "addr");
+    const char *data_str = qdict_get_str(qdict, "data");
+
+    memory_search(mon, count, format, size, addr, data_str, true);
+}
+
 static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
 {
     int count = qdict_get_int(qdict, "count");
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 02/10] QJSON: Use OBJECT_CHECK
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 01/10] monitor: add memory search commands s, sp Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 03/10] qobject: Clean up around qtype_code Luiz Capitulino
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: Eduardo Habkost <ehabkost@redhat.com>

The QJSON code used casts to (QJSON*) directly, instead of OBJECT_CHECK.
There were even some functions using object_dynamic_cast() calls
followed by assert(), which is exactly what OBJECT_CHECK does (by
calling object_dynamic_cast_assert()).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 qjson.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/qjson.c b/qjson.c
index 0cda269..e478802 100644
--- a/qjson.c
+++ b/qjson.c
@@ -24,6 +24,8 @@ struct QJSON {
     bool omit_comma;
 };
 
+#define QJSON(obj) OBJECT_CHECK(QJSON, (obj), TYPE_QJSON)
+
 static void json_emit_element(QJSON *json, const char *name)
 {
     /* Check whether we need to print a , before an element */
@@ -87,7 +89,7 @@ const char *qjson_get_str(QJSON *json)
 
 QJSON *qjson_new(void)
 {
-    QJSON *json = (QJSON *)object_new(TYPE_QJSON);
+    QJSON *json = QJSON(object_new(TYPE_QJSON));
     return json;
 }
 
@@ -98,8 +100,7 @@ void qjson_finish(QJSON *json)
 
 static void qjson_initfn(Object *obj)
 {
-    QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
-    assert(json);
+    QJSON *json = QJSON(obj);
 
     json->str = qstring_from_str("{ ");
     json->omit_comma = true;
@@ -107,9 +108,8 @@ static void qjson_initfn(Object *obj)
 
 static void qjson_finalizefn(Object *obj)
 {
-    QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
+    QJSON *json = QJSON(obj);
 
-    assert(json);
     qobject_decref(QOBJECT(json->str));
 }
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 03/10] qobject: Clean up around qtype_code
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 01/10] monitor: add memory search commands s, sp Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 02/10] QJSON: Use OBJECT_CHECK Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 04/10] qobject: Add a special null QObject Luiz Capitulino
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: Markus Armbruster <armbru@redhat.com>

QTYPE_NONE is a sentinel value.  No QObject has this type code.
Document it properly.

Fix dump_qobject() to abort() on QTYPE_NONE, just like for any other
invalid type code.

Fix to_json() to abort() on all invalid type codes, not just
QTYPE_MAX.

Clean up Property member qtype's type: it's a qtype_code.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 block/qapi.c               | 3 ---
 include/hw/qdev-core.h     | 2 +-
 include/qapi/qmp/qobject.h | 2 +-
 qobject/qjson.c            | 3 +--
 4 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 063dd1b..18d2b95 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -523,9 +523,6 @@ static void dump_qobject(fprintf_function func_fprintf, void *f,
             QDECREF(value);
             break;
         }
-        case QTYPE_NONE:
-            break;
-        case QTYPE_MAX:
         default:
             abort();
     }
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 4e673f9..9a0ee30 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -226,7 +226,7 @@ struct Property {
     PropertyInfo *info;
     int          offset;
     uint8_t      bitnr;
-    uint8_t      qtype;
+    qtype_code   qtype;
     int64_t      defval;
     int          arrayoffset;
     PropertyInfo *arrayinfo;
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index d0bbc7c..0991296 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -36,7 +36,7 @@
 #include <assert.h>
 
 typedef enum {
-    QTYPE_NONE,
+    QTYPE_NONE,    /* sentinel value, no QObject has this type code */
     QTYPE_QINT,
     QTYPE_QSTRING,
     QTYPE_QDICT,
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 12c576d..f2857c1 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -260,9 +260,8 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
     }
     case QTYPE_QERROR:
         /* XXX: should QError be emitted? */
-    case QTYPE_NONE:
         break;
-    case QTYPE_MAX:
+    default:
         abort();
     }
 }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 04/10] qobject: Add a special null QObject
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (2 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 03/10] qobject: Clean up around qtype_code Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 05/10] json-parser: Accept 'null' in QMP Luiz Capitulino
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: Markus Armbruster <armbru@redhat.com>

I'm going to fix the JSON parser to recognize null.  The obvious
representation of JSON null as (QObject *)NULL doesn't work, because
the parser already uses it as an error value.  Perhaps we should
change it to free NULL for null, but that's more than I can do right
now.  Create a special null QObject instead.

The existing QDict, QList, and QString all represent something that
is a pointer in C and could therefore be associated with NULL.  But
right now, all three of these sub-types are always non-null once
created, so the new null sentinel object is intentionally unrelated
to them.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 include/qapi/qmp/qobject.h | 11 ++++++++++-
 qobject/Makefile.objs      |  2 +-
 qobject/qjson.c            |  3 +++
 qobject/qnull.c            | 29 +++++++++++++++++++++++++++++
 4 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 qobject/qnull.c

diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index 0991296..84b2d9f 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -3,7 +3,7 @@
  *
  * Based on ideas by Avi Kivity <avi@redhat.com>
  *
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009, 2015 Red Hat Inc.
  *
  * Authors:
  *  Luiz Capitulino <lcapitulino@redhat.com>
@@ -37,6 +37,7 @@
 
 typedef enum {
     QTYPE_NONE,    /* sentinel value, no QObject has this type code */
+    QTYPE_QNULL,
     QTYPE_QINT,
     QTYPE_QSTRING,
     QTYPE_QDICT,
@@ -110,4 +111,12 @@ static inline qtype_code qobject_type(const QObject *obj)
     return obj->type->code;
 }
 
+extern QObject qnull_;
+
+static inline QObject *qnull(void)
+{
+    qobject_incref(&qnull_);
+    return &qnull_;
+}
+
 #endif /* QOBJECT_H */
diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs
index c9ff59c..f7595f5 100644
--- a/qobject/Makefile.objs
+++ b/qobject/Makefile.objs
@@ -1,3 +1,3 @@
-util-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
+util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
 util-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
 util-obj-y += qerror.o
diff --git a/qobject/qjson.c b/qobject/qjson.c
index f2857c1..846733d 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -127,6 +127,9 @@ static void to_json_list_iter(QObject *obj, void *opaque)
 static void to_json(const QObject *obj, QString *str, int pretty, int indent)
 {
     switch (qobject_type(obj)) {
+    case QTYPE_QNULL:
+        qstring_append(str, "null");
+        break;
     case QTYPE_QINT: {
         QInt *val = qobject_to_qint(obj);
         char buffer[1024];
diff --git a/qobject/qnull.c b/qobject/qnull.c
new file mode 100644
index 0000000..9873e26
--- /dev/null
+++ b/qobject/qnull.c
@@ -0,0 +1,29 @@
+/*
+ * QNull
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * Authors:
+ *  Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later.  See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qapi/qmp/qobject.h"
+
+static void qnull_destroy_obj(QObject *obj)
+{
+    assert(0);
+}
+
+static const QType qnull_type = {
+    .code = QTYPE_QNULL,
+    .destroy = qnull_destroy_obj,
+};
+
+QObject qnull_ = {
+    .type = &qnull_type,
+    .refcnt = 1,
+};
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 05/10] json-parser: Accept 'null' in QMP
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (3 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 04/10] qobject: Add a special null QObject Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 06/10] MAINTAINERS: New maintainer for QMP and QAPI Luiz Capitulino
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: Eric Blake <eblake@redhat.com>

We document that in QMP, the client may send any json-value
for the optional "id" key, and then return that same value
on reply (both success and failures, insofar as the failure
happened after parsing the id).  [Note that the output may
not be identical to the input, as whitespace may change and
since we may reorder keys within a json-object, but that this
still constitutes the same json-value].  However, we were not
handling the JSON literal null, which counts as a json-value
per RFC 7159.

Also, down the road, given the QAPI schema of {'*foo':'str'} or
{'*foo':'ComplexType'}, we could decide to allow the QMP client
to pass { "foo":null } instead of the current representation of
{ } where omitting the key is the only way to get at the default
NULL value.  Such a change might be useful for argument
introspection (if a type in older qemu lacks 'foo' altogether,
then an explicit "foo":null probe will force an easily
distinguished error message for whether the optional "foo" key
is even understood in newer qemu).  And if we add default values
to optional arguments, allowing an explicit null would be
required for getting a NULL value associated with an optional
string that has a non-null default.  But all that can come at a
later day.

The 'check-unit' testsuite is enhanced to test that parsing
produces the same object as explicitly requesting a reference
to the special qnull object.  In addition, I tested with:

$ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults
{"QMP": {"version": {"qemu": {"micro": 91, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}}
{"execute":"qmp_capabilities","id":null}
{"return": {}, "id": null}
{"id":{"a":null,"b":[1,null]},"execute":"quit"}
{"return": {}, "id": {"a": null, "b": [1, null]}}
{"timestamp": {"seconds": 1427742379, "microseconds": 423128}, "event": "SHUTDOWN"}

Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 qobject/json-parser.c |  2 ++
 tests/check-qjson.c   | 15 +++++++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 4288267..717cb8f 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -561,6 +561,8 @@ static QObject *parse_keyword(JSONParserContext *ctxt)
         ret = QOBJECT(qbool_from_int(true));
     } else if (token_is_keyword(token, "false")) {
         ret = QOBJECT(qbool_from_int(false));
+    } else if (token_is_keyword(token, "null")) {
+        ret = qnull();
     } else {
         parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token));
         goto out;
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 95497a0..60e5b22 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -1,6 +1,6 @@
 /*
  * Copyright IBM, Corp. 2009
- * Copyright (c) 2013 Red Hat Inc.
+ * Copyright (c) 2013, 2015 Red Hat Inc.
  *
  * Authors:
  *  Anthony Liguori   <aliguori@us.ibm.com>
@@ -1005,6 +1005,7 @@ static void keyword_literal(void)
 {
     QObject *obj;
     QBool *qbool;
+    QObject *null;
     QString *str;
 
     obj = qobject_from_json("true");
@@ -1041,7 +1042,7 @@ static void keyword_literal(void)
     g_assert(qbool_get_int(qbool) == 0);
 
     QDECREF(qbool);
-    
+
     obj = qobject_from_jsonf("%i", true);
     g_assert(obj != NULL);
     g_assert(qobject_type(obj) == QTYPE_QBOOL);
@@ -1050,6 +1051,16 @@ static void keyword_literal(void)
     g_assert(qbool_get_int(qbool) != 0);
 
     QDECREF(qbool);
+
+    obj = qobject_from_json("null");
+    g_assert(obj != NULL);
+    g_assert(qobject_type(obj) == QTYPE_QNULL);
+
+    null = qnull();
+    g_assert(null == obj);
+
+    qobject_decref(obj);
+    qobject_decref(null);
 }
 
 typedef struct LiteralQDictEntry LiteralQDictEntry;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 06/10] MAINTAINERS: New maintainer for QMP and QAPI
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (4 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 05/10] json-parser: Accept 'null' in QMP Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 07/10] scripts: qmp-shell: refactor helpers Luiz Capitulino
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

Markus is taking over maintership of QMP and the QAPI from
me. Markus has always been a great reviewer and contributor
to those subsystems. In the last few months he's also doing
pull requests that are a lot more relevant than the ones I
was able to do. So, this is a natural move.

I'm still the maintainer of HMP and QObjects, but I'm
looking for someone to take over those too.

PS: This commit also fixes the file listing for the QMP
    entry.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 MAINTAINERS | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0b67c48..d858c49 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -926,20 +926,19 @@ K: srat|SRAT
 T: git git://github.com/ehabkost/qemu.git numa
 
 QAPI
-M: Luiz Capitulino <lcapitulino@redhat.com>
+M: Markus Armbruster <armbru@redhat.com>
 M: Michael Roth <mdroth@linux.vnet.ibm.com>
-S: Maintained
+S: Supported
 F: qapi/
 F: tests/qapi-schema/
-T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
+T: git git://repo.or.cz/qemu/armbru.git qapi-next
 
 QAPI Schema
 M: Eric Blake <eblake@redhat.com>
-M: Luiz Capitulino <lcapitulino@redhat.com>
 M: Markus Armbruster <armbru@redhat.com>
 S: Supported
 F: qapi-schema.json
-T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
+T: git git://repo.or.cz/qemu/armbru.git qapi-next
 
 QObject
 M: Luiz Capitulino <lcapitulino@redhat.com>
@@ -964,13 +963,14 @@ X: qom/cpu.c
 F: tests/qom-test.c
 
 QMP
-M: Luiz Capitulino <lcapitulino@redhat.com>
-S: Maintained
+M: Markus Armbruster <armbru@redhat.com>
+S: Supported
 F: qmp.c
 F: monitor.c
 F: qmp-commands.hx
-F: QMP/
-T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
+F: docs/qmp/
+F: scripts/qmp/
+T: git git://repo.or.cz/qemu/armbru.git qapi-next
 
 SLIRP
 M: Jan Kiszka <jan.kiszka@siemens.com>
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 07/10] scripts: qmp-shell: refactor helpers
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (5 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 06/10] MAINTAINERS: New maintainer for QMP and QAPI Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 08/10] scripts: qmp-shell: Expand support for QMP expressions Luiz Capitulino
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: John Snow <jsnow@redhat.com>

Refactor the qmp-shell command line processing function
into two components. This will be used to allow sub-expressions,
which will assist us in adding transactional support to qmp-shell.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qmp/qmp-shell | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index e0e848b..a9632ec 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -88,16 +88,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         # 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:]:
+    def __cli_expr(self, tokens, parent):
+        for arg in tokens:
             opt = arg.split('=')
             try:
                 if(len(opt) > 2):
@@ -113,7 +105,6 @@ class QMPShell(qmp.QEMUMonitorProtocol):
                 else:
                     value = opt[1]
             optpath = opt[0].split('.')
-            parent = qmpcmd['arguments']
             curpath = []
             for p in optpath[:-1]:
                 curpath.append(p)
@@ -128,6 +119,17 @@ class QMPShell(qmp.QEMUMonitorProtocol):
                 else:
                     raise QMPShellError('Cannot set "%s" multiple times' % opt[0])
             parent[optpath[-1]] = value
+
+    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': {} }
+        self.__cli_expr(cmdargs[1:], qmpcmd['arguments'])
         return qmpcmd
 
     def _execute_cmd(self, cmdline):
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 08/10] scripts: qmp-shell: Expand support for QMP expressions
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (6 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 07/10] scripts: qmp-shell: refactor helpers Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 09/10] scripts: qmp-shell: add transaction subshell Luiz Capitulino
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: John Snow <jsnow@redhat.com>

This includes support for [] expressions, single-quotes in
QMP expressions (which is not strictly a part of JSON), and
the ability to use "True", "False" and "None" literals instead
of JSON's equivalent true, false, and null literals.

qmp-shell currently allows you to describe values as
JSON expressions:
key={"key":{"key2":"val"}}

But it does not currently support arrays, which are needed
for serializing and deserializing transactions:
key=[{"type":"drive-backup","data":{...}}]

qmp-shell also only currently accepts doubly quoted strings
as-per JSON spec, but QMP allows single quotes.

Lastly, python allows you to utilize "True" or "False" as
boolean literals, but JSON expects "true" or "false". Expand
qmp-shell to allow the user to type either, converting to the
correct type.

As a consequence of the above, the key=val parsing is also improved
to give better error messages if a key=val token is not provided.

CAVEAT: The parser is still extremely rudimentary and does not
expect to find spaces in {} nor [] expressions. This patch does
not improve this functionality.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qmp/qmp-shell | 63 ++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 16 deletions(-)

diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index a9632ec..7f2c554 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -32,6 +32,7 @@
 
 import qmp
 import json
+import ast
 import readline
 import sys
 import pprint
@@ -51,6 +52,19 @@ class QMPShellError(Exception):
 class QMPShellBadPort(QMPShellError):
     pass
 
+class FuzzyJSON(ast.NodeTransformer):
+    '''This extension of ast.NodeTransformer filters literal "true/false/null"
+    values in an AST and replaces them by proper "True/False/None" values that
+    Python can properly evaluate.'''
+    def visit_Name(self, node):
+        if node.id == 'true':
+            node.id = 'True'
+        if node.id == 'false':
+            node.id = 'False'
+        if node.id == 'null':
+            node.id = 'None'
+        return node
+
 # TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and
 #       _execute_cmd()). Let's design a better one.
 class QMPShell(qmp.QEMUMonitorProtocol):
@@ -88,23 +102,40 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         # clearing everything as it doesn't seem to matter
         readline.set_completer_delims('')
 
-    def __cli_expr(self, tokens, parent):
-        for arg in tokens:
-            opt = arg.split('=')
+    def __parse_value(self, val):
+        try:
+            return int(val)
+        except ValueError:
+            pass
+
+        if val.lower() == 'true':
+            return True
+        if val.lower() == 'false':
+            return False
+        if val.startswith(('{', '[')):
+            # Try first as pure JSON:
             try:
-                if(len(opt) > 2):
-                    opt[1] = '='.join(opt[1:])
-                value = int(opt[1])
+                return json.loads(val)
             except ValueError:
-                if opt[1] == 'true':
-                    value = True
-                elif opt[1] == 'false':
-                    value = False
-                elif opt[1].startswith('{'):
-                    value = json.loads(opt[1])
-                else:
-                    value = opt[1]
-            optpath = opt[0].split('.')
+                pass
+            # Try once again as FuzzyJSON:
+            try:
+                st = ast.parse(val, mode='eval')
+                return ast.literal_eval(FuzzyJSON().visit(st))
+            except SyntaxError:
+                pass
+            except ValueError:
+                pass
+        return val
+
+    def __cli_expr(self, tokens, parent):
+        for arg in tokens:
+            (key, _, val) = arg.partition('=')
+            if not val:
+                raise QMPShellError("Expected a key=value pair, got '%s'" % arg)
+
+            value = self.__parse_value(val)
+            optpath = key.split('.')
             curpath = []
             for p in optpath[:-1]:
                 curpath.append(p)
@@ -117,7 +148,7 @@ class QMPShell(qmp.QEMUMonitorProtocol):
                 if type(parent[optpath[-1]]) is dict:
                     raise QMPShellError('Cannot use "%s" as both leaf and non-leaf key' % '.'.join(curpath))
                 else:
-                    raise QMPShellError('Cannot set "%s" multiple times' % opt[0])
+                    raise QMPShellError('Cannot set "%s" multiple times' % key)
             parent[optpath[-1]] = value
 
     def __build_cmd(self, cmdline):
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 09/10] scripts: qmp-shell: add transaction subshell
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (7 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 08/10] scripts: qmp-shell: Expand support for QMP expressions Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-08 13:34 ` [Qemu-devel] [PULL 10/10] scripts: qmp-shell: Add verbose flag Luiz Capitulino
  2015-05-11 12:53 ` [Qemu-devel] [PULL 00/10] QMP queue Peter Maydell
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: John Snow <jsnow@redhat.com>

Add a special processing mode to craft transactions.

By entering "transaction(" the shell will enter a special
mode where each subsequent command will be saved as a transaction
instead of executed as an individual command.

The transaction can be submitted by entering ")" on a line by itself.

Examples:

Separate lines:

(QEMU) transaction(
TRANS> block-dirty-bitmap-add node=drive0 name=bitmap1
TRANS> block-dirty-bitmap-clear node=drive0 name=bitmap0
TRANS> )

With a transaction action included on the first line:

(QEMU) transaction( block-dirty-bitmap-add node=drive0 name=bitmap2
TRANS> block-dirty-bitmap-add node=drive0 name=bitmap3
TRANS> )

As a one-liner, with just one transaction action:

(QEMU) transaction( block-dirty-bitmap-add node=drive0 name=bitmap0 )

As a side-effect of this patch, blank lines are now parsed as no-ops,
regardless of which shell mode you are in.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qmp/qmp-shell | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index 7f2c554..1df2ca7 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -73,6 +73,8 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         self._greeting = None
         self._completer = None
         self._pp = pp
+        self._transmode = False
+        self._actions = list()
 
     def __get_address(self, arg):
         """
@@ -159,6 +161,36 @@ class QMPShell(qmp.QEMUMonitorProtocol):
             < command-name > [ arg-name1=arg1 ] ... [ arg-nameN=argN ]
         """
         cmdargs = cmdline.split()
+
+        # Transactional CLI entry/exit:
+        if cmdargs[0] == 'transaction(':
+            self._transmode = True
+            cmdargs.pop(0)
+        elif cmdargs[0] == ')' and self._transmode:
+            self._transmode = False
+            if len(cmdargs) > 1:
+                raise QMPShellError("Unexpected input after close of Transaction sub-shell")
+            qmpcmd = { 'execute': 'transaction',
+                       'arguments': { 'actions': self._actions } }
+            self._actions = list()
+            return qmpcmd
+
+        # Nothing to process?
+        if not cmdargs:
+            return None
+
+        # Parse and then cache this Transactional Action
+        if self._transmode:
+            finalize = False
+            action = { 'type': cmdargs[0], 'data': {} }
+            if cmdargs[-1] == ')':
+                cmdargs.pop(-1)
+                finalize = True
+            self.__cli_expr(cmdargs[1:], action['data'])
+            self._actions.append(action)
+            return self.__build_cmd(')') if finalize else None
+
+        # Standard command: parse and return it to be executed.
         qmpcmd = { 'execute': cmdargs[0], 'arguments': {} }
         self.__cli_expr(cmdargs[1:], qmpcmd['arguments'])
         return qmpcmd
@@ -171,6 +203,9 @@ class QMPShell(qmp.QEMUMonitorProtocol):
             print 'command format: <command-name> ',
             print '[arg-name1=arg1] ... [arg-nameN=argN]'
             return True
+        # For transaction mode, we may have just cached the action:
+        if qmpcmd is None:
+            return True
         resp = self.cmd_obj(qmpcmd)
         if resp is None:
             print 'Disconnected'
@@ -191,6 +226,11 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         version = self._greeting['QMP']['version']['qemu']
         print 'Connected to QEMU %d.%d.%d\n' % (version['major'],version['minor'],version['micro'])
 
+    def get_prompt(self):
+        if self._transmode:
+            return "TRANS> "
+        return "(QEMU) "
+
     def read_exec_command(self, prompt):
         """
         Read and execute a command.
@@ -330,7 +370,7 @@ def main():
         die('Could not connect to %s' % addr)
 
     qemu.show_banner()
-    while qemu.read_exec_command('(QEMU) '):
+    while qemu.read_exec_command(qemu.get_prompt()):
         pass
     qemu.close()
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PULL 10/10] scripts: qmp-shell: Add verbose flag
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (8 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 09/10] scripts: qmp-shell: add transaction subshell Luiz Capitulino
@ 2015-05-08 13:34 ` Luiz Capitulino
  2015-05-11 12:53 ` [Qemu-devel] [PULL 00/10] QMP queue Peter Maydell
  10 siblings, 0 replies; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-08 13:34 UTC (permalink / raw)
  To: peter.maydell; +Cc: qemu-devel

From: John Snow <jsnow@redhat.com>

Add a verbose flag that shows the QMP command that was
constructed, to allow for later copy/pasting, reference,
debugging, etc.

The QMP is converted from a Python literal to JSON first,
to ensure that it is viable input to the actual QMP parser.

As a side-effect, this JSON output will helpfully show all
the necessary conversions that were performed on the input,
illustrating that "True" was transformed back into "true",
literal values are now escaped with "" instead of '', and so on.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Tested-by: Kashyap Chamarthy <kchamart@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 scripts/qmp/qmp-shell | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
index 1df2ca7..65280d2 100755
--- a/scripts/qmp/qmp-shell
+++ b/scripts/qmp/qmp-shell
@@ -195,6 +195,13 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         self.__cli_expr(cmdargs[1:], qmpcmd['arguments'])
         return qmpcmd
 
+    def _print(self, qmp):
+        jsobj = json.dumps(qmp)
+        if self._pp is not None:
+            self._pp.pprint(jsobj)
+        else:
+            print str(jsobj)
+
     def _execute_cmd(self, cmdline):
         try:
             qmpcmd = self.__build_cmd(cmdline)
@@ -206,15 +213,13 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         # For transaction mode, we may have just cached the action:
         if qmpcmd is None:
             return True
+        if self._verbose:
+            self._print(qmpcmd)
         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
+        self._print(resp)
         return True
 
     def connect(self):
@@ -250,6 +255,9 @@ class QMPShell(qmp.QEMUMonitorProtocol):
         else:
             return self._execute_cmd(cmdline)
 
+    def set_verbosity(self, verbose):
+        self._verbose = verbose
+
 class HMPShell(QMPShell):
     def __init__(self, address):
         QMPShell.__init__(self, address)
@@ -327,7 +335,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 [ -p ] [ -H ] < UNIX socket path> | < TCP address:port >\n')
+    sys.stderr.write('qemu-shell [ -v ] [ -p ] [ -H ] < UNIX socket path> | < TCP address:port >\n')
     sys.exit(1)
 
 def main():
@@ -335,6 +343,7 @@ def main():
     qemu = None
     hmp = False
     pp = None
+    verbose = False
 
     try:
         for arg in sys.argv[1:]:
@@ -346,6 +355,8 @@ def main():
                 if pp is not None:
                     fail_cmdline(arg)
                 pp = pprint.PrettyPrinter(indent=4)
+            elif arg == "-v":
+                verbose = True
             else:
                 if qemu is not None:
                     fail_cmdline(arg)
@@ -370,6 +381,7 @@ def main():
         die('Could not connect to %s' % addr)
 
     qemu.show_banner()
+    qemu.set_verbosity(verbose)
     while qemu.read_exec_command(qemu.get_prompt()):
         pass
     qemu.close()
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PULL 00/10] QMP queue
  2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
                   ` (9 preceding siblings ...)
  2015-05-08 13:34 ` [Qemu-devel] [PULL 10/10] scripts: qmp-shell: Add verbose flag Luiz Capitulino
@ 2015-05-11 12:53 ` Peter Maydell
  2015-05-11 13:17   ` Luiz Capitulino
  10 siblings, 1 reply; 14+ messages in thread
From: Peter Maydell @ 2015-05-11 12:53 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: QEMU Developers

On 8 May 2015 at 14:34, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> The following changes since commit f8340b360b9bc29d48716ba8aca79df2b9544979:
>
>   hw/ptimer: Do not artificially limit timers when using icount (2015-05-08 17:15:23 +1000)
>
> are available in the git repository at:
>
>   git://repo.or.cz/qemu/qmp-unstable.git tags/for-upstream
>
> for you to fetch changes up to 07972d16e3343dc62302b81efb018308f99f7a7a:
>
>   scripts: qmp-shell: Add verbose flag (2015-05-08 08:47:01 -0400)
>
> ----------------------------------------------------------------
> QMP pull request

Hi. I'm afraid this doesn't build on win32:
/home/petmay01/linaro/qemu-for-merges/monitor.c: In function ‘memory_search’:
/home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
implicit declaration of function ‘memmem’
/home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning: nested
extern declaration of ‘memmem’
/home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
assignment makes pointer from integer

thanks
-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PULL 00/10] QMP queue
  2015-05-11 12:53 ` [Qemu-devel] [PULL 00/10] QMP queue Peter Maydell
@ 2015-05-11 13:17   ` Luiz Capitulino
  2015-05-12  9:40     ` Peter Maydell
  0 siblings, 1 reply; 14+ messages in thread
From: Luiz Capitulino @ 2015-05-11 13:17 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On Mon, 11 May 2015 13:53:47 +0100
Peter Maydell <peter.maydell@linaro.org> wrote:

> On 8 May 2015 at 14:34, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> > The following changes since commit f8340b360b9bc29d48716ba8aca79df2b9544979:
> >
> >   hw/ptimer: Do not artificially limit timers when using icount (2015-05-08 17:15:23 +1000)
> >
> > are available in the git repository at:
> >
> >   git://repo.or.cz/qemu/qmp-unstable.git tags/for-upstream
> >
> > for you to fetch changes up to 07972d16e3343dc62302b81efb018308f99f7a7a:
> >
> >   scripts: qmp-shell: Add verbose flag (2015-05-08 08:47:01 -0400)
> >
> > ----------------------------------------------------------------
> > QMP pull request
> 
> Hi. I'm afraid this doesn't build on win32:
> /home/petmay01/linaro/qemu-for-merges/monitor.c: In function ‘memory_search’:
> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
> implicit declaration of function ‘memmem’
> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning: nested
> extern declaration of ‘memmem’
> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
> assignment makes pointer from integer

Needless to say that I didn't build for win32. My bad.

Can you try again? I've dropped the offending patch and pushed
the tag again.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PULL 00/10] QMP queue
  2015-05-11 13:17   ` Luiz Capitulino
@ 2015-05-12  9:40     ` Peter Maydell
  0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2015-05-12  9:40 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: QEMU Developers

On 11 May 2015 at 14:17, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> On Mon, 11 May 2015 13:53:47 +0100
> Peter Maydell <peter.maydell@linaro.org> wrote:
>
>> On 8 May 2015 at 14:34, Luiz Capitulino <lcapitulino@redhat.com> wrote:
>> > The following changes since commit f8340b360b9bc29d48716ba8aca79df2b9544979:
>> >
>> >   hw/ptimer: Do not artificially limit timers when using icount (2015-05-08 17:15:23 +1000)
>> >
>> > are available in the git repository at:
>> >
>> >   git://repo.or.cz/qemu/qmp-unstable.git tags/for-upstream
>> >
>> > for you to fetch changes up to 07972d16e3343dc62302b81efb018308f99f7a7a:
>> >
>> >   scripts: qmp-shell: Add verbose flag (2015-05-08 08:47:01 -0400)
>> >
>> > ----------------------------------------------------------------
>> > QMP pull request
>>
>> Hi. I'm afraid this doesn't build on win32:
>> /home/petmay01/linaro/qemu-for-merges/monitor.c: In function ‘memory_search’:
>> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
>> implicit declaration of function ‘memmem’
>> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning: nested
>> extern declaration of ‘memmem’
>> /home/petmay01/linaro/qemu-for-merges/monitor.c:1306: warning:
>> assignment makes pointer from integer
>
> Needless to say that I didn't build for win32. My bad.
>
> Can you try again? I've dropped the offending patch and pushed
> the tag again.

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-05-12  9:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-08 13:34 [Qemu-devel] [PULL 00/10] QMP queue Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 01/10] monitor: add memory search commands s, sp Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 02/10] QJSON: Use OBJECT_CHECK Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 03/10] qobject: Clean up around qtype_code Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 04/10] qobject: Add a special null QObject Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 05/10] json-parser: Accept 'null' in QMP Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 06/10] MAINTAINERS: New maintainer for QMP and QAPI Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 07/10] scripts: qmp-shell: refactor helpers Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 08/10] scripts: qmp-shell: Expand support for QMP expressions Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 09/10] scripts: qmp-shell: add transaction subshell Luiz Capitulino
2015-05-08 13:34 ` [Qemu-devel] [PULL 10/10] scripts: qmp-shell: Add verbose flag Luiz Capitulino
2015-05-11 12:53 ` [Qemu-devel] [PULL 00/10] QMP queue Peter Maydell
2015-05-11 13:17   ` Luiz Capitulino
2015-05-12  9:40     ` Peter Maydell

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).