qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] RFC: Full introspection support for QMP (with draft pat


From: Amos Kong
Subject: Re: [Qemu-devel] RFC: Full introspection support for QMP (with draft patch)
Date: Fri, 7 Jun 2013 18:12:30 +0800
User-agent: Mutt/1.5.21 (2010-09-15)

Sent out a draft patch in the end of this week. It doesn't support:
* output all stuffs in one shot.
* introspect event
* provide metadata date

How can we define a dynamic dict in qmp-schema.json ?

Currently I just output the raw json dict by a string, Libvirt needs
parse two times, convert the string to json format.

qmp-schema.h: auto generated head file by qapi script

Attached some examples.
* query-qmp-schema-no-param.txt
* query-qmp-schema-filter-by-name.txt
* query-qmp-schema-filter-all-command.txt
* query-qmp-schema-filter-all-type.txt
* query-qmp-schema-filter-all-enum.txt

-----

>From 00fe59bde40a8beadf16196db9ed1bac5d862db0 Mon Sep 17 00:00:00 2001
From: Amos Kong <address@hidden>
Date: Fri, 7 Jun 2013 18:02:21 +0800
Subject: [PATCH] full introspection support for QMP

Signed-off-by: Amos Kong <address@hidden>
---
 qapi-schema.json         |  3 +++
 qmp-commands.hx          | 23 +++++++++++++++++++++++
 qmp.c                    | 36 ++++++++++++++++++++++++++++++++++++
 scripts/qapi-commands.py |  2 +-
 scripts/qapi-types.py    | 27 ++++++++++++++++++++++++++-
 scripts/qapi-visit.py    |  2 +-
 scripts/qapi.py          | 13 ++++++++++++-
 7 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index ef1f657..2234e6a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3618,3 +3618,6 @@
             '*cpuid-input-ecx': 'int',
             'cpuid-register': 'X86CPURegister32',
             'features': 'int' } }
+
+{ 'command': 'query-qmp-schema', 'data': { '*type': 'str', '*name': 'str' },
+  'returns': ['str'] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ffd130e..fc56fba 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2932,3 +2932,26 @@ Example:
 <- { "return": {} }
 
 EQMP
+
+    {
+        .name       = "query-qmp-schema",
+        .args_type  = "type:s?,name:s?",
+        .mhandler.cmd_new = qmp_marshal_input_query_qmp_schema,
+    },
+
+
+SQMP
+query-qmp-schema
+----------------
+
+query qmp schema information
+
+Example:
+
+-> { "execute": "query-qmp-schema", "arguments": { "name" : "query-name" }}
+<- { "return": [
+        "{ 'command': 'query-name', 'returns': 'NameInfo' }"
+      ]
+   }
+
+EQMP
\ No newline at end of file
diff --git a/qmp.c b/qmp.c
index 4c149b3..11ce275 100644
--- a/qmp.c
+++ b/qmp.c
@@ -25,6 +25,7 @@
 #include "sysemu/blockdev.h"
 #include "qom/qom-qobject.h"
 #include "hw/boards.h"
+#include "qmp-schema.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -486,6 +487,41 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error 
**errp)
     return arch_query_cpu_definitions(errp);
 }
 
+strList *qmp_query_qmp_schema(bool has_type, const char *type, bool
+                              has_name, const char * name, Error **errp)
+
+{
+    strList *list = NULL, *last_entry, *entry;
+    int i = 0;
+
+    while (qmp_schema_table[i].json_string) {
+        if (has_type && strcmp(type, qmp_schema_table[i].type)) {
+            i++;
+            continue;
+        }
+        if (has_name && strcmp(name, qmp_schema_table[i].name)) {
+            i++;
+            continue;
+        }
+
+        entry = malloc(sizeof(strList *));
+        entry->value = g_strdup(qmp_schema_table[i].json_string);
+        entry->next = NULL;
+
+        if (!list) {
+            list = entry;
+        } else {
+            last_entry->next = entry;
+        }
+        last_entry = entry;
+
+        printf("%d\n", i);
+        i++;
+    }
+
+    return list;
+}
+
 void qmp_add_client(const char *protocol, const char *fdname,
                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
                     Error **errp)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index e06332b..d15d04f 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -437,7 +437,7 @@ except os.error, e:
     if e.errno != errno.EEXIST:
         raise
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin)[0]
 commands = filter(lambda expr: expr.has_key('command'), exprs)
 commands = filter(lambda expr: not expr.has_key('gen'), commands)
 
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index ddcfed9..ce448d8 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -15,6 +15,7 @@ import sys
 import os
 import getopt
 import errno
+import re
 
 def generate_fwd_struct(name, members, builtin_type=False):
     if builtin_type:
@@ -303,7 +304,31 @@ fdecl.write(mcgen('''
 ''',
                   guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs_all = parse_schema(sys.stdin)
+
+schema_table = """
+/* convert qapi-schema.json to a string table */
+
+struct qmp_schem {
+const char *json_string;
+const char *type;
+const char *name;
+} qmp_schema_table[] = {
+"""
+
+for i in exprs_all[1]:
+    print i
+    str = re.sub(r'\n', ' \\\n', i[0].strip())
+    str = re.sub(r' +', ' ', str)
+    schema_table += '{"%s", "%s", "%s"},\n' % (str, i[1], i[2])
+
+schema_table += '{NULL, NULL, NULL } };\n'
+
+f = open("qmp-schema.h", "w")
+f.write(schema_table)
+f.close()
+
+exprs = exprs_all[0]
 exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
 
 fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 6cac05a..70f80eb 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -334,7 +334,7 @@ fdecl.write(mcgen('''
 ''',
                   prefix=prefix, guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin)[0]
 
 # to avoid header dependency hell, we always generate declarations
 # for built-in types in our header files and simply guard them
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 02ad668..46cc2e4 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -80,6 +80,7 @@ def evaluate(string):
 
 def parse_schema(fp):
     exprs = []
+    raw_exprs = []
     expr = ''
     expr_eval = None
 
@@ -91,6 +92,11 @@ def parse_schema(fp):
             expr += line
         elif expr:
             expr_eval = evaluate(expr)
+
+            for name in ['command', 'type', 'enum', 'union']:
+                if expr_eval.has_key(name):
+                    raw_exprs.append([expr, name, expr_eval[name]])
+
             if expr_eval.has_key('enum'):
                 add_enum(expr_eval['enum'])
             elif expr_eval.has_key('union'):
@@ -102,13 +108,18 @@ def parse_schema(fp):
 
     if expr:
         expr_eval = evaluate(expr)
+
+        for name in ['command', 'type', 'enum', 'union']:
+            if expr_eval.has_key(name):
+                raw_exprs.append([expr, name, expr_eval[name]])
+
         if expr_eval.has_key('enum'):
             add_enum(expr_eval['enum'])
         elif expr_eval.has_key('union'):
             add_enum('%sKind' % expr_eval['union'])
         exprs.append(expr_eval)
 
-    return exprs
+    return exprs, raw_exprs
 
 def parse_args(typeinfo):
     for member in typeinfo:
-- 
1.8.1.4

Attachment: qmp-schema.h
Description: Text document


reply via email to

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