From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Adam Litke <aglitke@linux.vnet.ibm.com>,
Anthony Liguori <aliguori@us.ibm.com>,
Markus Armbruster <armbru@redhat.com>,
Luiz Capitulino <lcapitulino@redhat.com>
Subject: [Qemu-devel] [PATCH 08/22] qapi: add code generator for qmp-types
Date: Sun, 6 Mar 2011 19:22:50 -0600 [thread overview]
Message-ID: <1299460984-15849-9-git-send-email-aliguori@us.ibm.com> (raw)
In-Reply-To: <1299460984-15849-1-git-send-email-aliguori@us.ibm.com>
Only generate qmp-types.[ch]. These files contain the type definitions for
QMP along with the alloc/free functions for these types. Functions to convert
enum values to integers and vice versa are also included.
qmp-types is used both within QEMU and within libqmp
Special alloc/free functions are provided to ensure that all structures are
padded when allocated. This makes sure that libqmp can provide a forward
compatible interface since all additions to a structure will have a boolean
enable flag.
The free function is convenient since individual structures may have pointers
that also require freeing.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/Makefile b/Makefile
index 6b1d716..6b9fd69 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@ GENERATED_HEADERS = config-host.h trace.h qemu-options.def
ifeq ($(TRACE_BACKEND),dtrace)
GENERATED_HEADERS += trace-dtrace.h
endif
+GENERATED_HEADERS += qmp-types.h
ifneq ($(wildcard config-host.mak),)
# Put the all: rule here so that config-host.mak can contain dependencies.
@@ -146,6 +147,14 @@ trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+qmp-types.c: $(SRC_PATH)/qmp-schema.json $(SRC_PATH)/qmp-gen.py
+ $(call quiet-command,python $(SRC_PATH)/qmp-gen.py --types-body < $< > $@, " GEN $@")
+
+qmp-types.h: $(SRC_PATH)/qmp-schema.json $(SRC_PATH)/qmp-gen.py
+ $(call quiet-command,python $(SRC_PATH)/qmp-gen.py --types-header < $< > $@, " GEN $@")
+
+qmp-types.o: qmp-types.c qmp-types.h
+
version.o: $(SRC_PATH)/version.rc config-host.mak
$(call quiet-command,$(WINDRES) -I. -o $@ $<," RC $(TARGET_DIR)$@")
diff --git a/Makefile.objs b/Makefile.objs
index 69f0383..710d99f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -15,7 +15,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o
-block-obj-y += error.o
+block-obj-y += error.o qmp-types.o
block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/ordereddict.py b/ordereddict.py
new file mode 100644
index 0000000..e17269f
--- /dev/null
+++ b/ordereddict.py
@@ -0,0 +1,128 @@
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+ def __init__(self, *args, **kwds):
+ if len(args) > 1:
+ raise TypeError('expected at most 1 arguments, got %d' % len(args))
+ try:
+ self.__end
+ except AttributeError:
+ self.clear()
+ self.update(*args, **kwds)
+
+ def clear(self):
+ self.__end = end = []
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.__map = {} # key --> [key, prev, next]
+ dict.clear(self)
+
+ def __setitem__(self, key, value):
+ if key not in self:
+ end = self.__end
+ curr = end[1]
+ curr[2] = end[1] = self.__map[key] = [key, curr, end]
+ dict.__setitem__(self, key, value)
+
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
+ key, prev, next = self.__map.pop(key)
+ prev[2] = next
+ next[1] = prev
+
+ def __iter__(self):
+ end = self.__end
+ curr = end[2]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[2]
+
+ def __reversed__(self):
+ end = self.__end
+ curr = end[1]
+ while curr is not end:
+ yield curr[0]
+ curr = curr[1]
+
+ def popitem(self, last=True):
+ if not self:
+ raise KeyError('dictionary is empty')
+ if last:
+ key = reversed(self).next()
+ else:
+ key = iter(self).next()
+ value = self.pop(key)
+ return key, value
+
+ def __reduce__(self):
+ items = [[k, self[k]] for k in self]
+ tmp = self.__map, self.__end
+ del self.__map, self.__end
+ inst_dict = vars(self).copy()
+ self.__map, self.__end = tmp
+ if inst_dict:
+ return (self.__class__, (items,), inst_dict)
+ return self.__class__, (items,)
+
+ def keys(self):
+ return list(self)
+
+ setdefault = DictMixin.setdefault
+ update = DictMixin.update
+ pop = DictMixin.pop
+ values = DictMixin.values
+ items = DictMixin.items
+ iterkeys = DictMixin.iterkeys
+ itervalues = DictMixin.itervalues
+ iteritems = DictMixin.iteritems
+
+ def __repr__(self):
+ if not self:
+ return '%s()' % (self.__class__.__name__,)
+ return '%s(%r)' % (self.__class__.__name__, self.items())
+
+ def copy(self):
+ return self.__class__(self)
+
+ @classmethod
+ def fromkeys(cls, iterable, value=None):
+ d = cls()
+ for key in iterable:
+ d[key] = value
+ return d
+
+ def __eq__(self, other):
+ if isinstance(other, OrderedDict):
+ if len(self) != len(other):
+ return False
+ for p, q in zip(self.items(), other.items()):
+ if p != q:
+ return False
+ return True
+ return dict.__eq__(self, other)
+
+ def __ne__(self, other):
+ return not self == other
+
diff --git a/qmp-gen.py b/qmp-gen.py
new file mode 100644
index 0000000..0889fa3
--- /dev/null
+++ b/qmp-gen.py
@@ -0,0 +1,393 @@
+##
+# QAPI Code Generator
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+# Anthony Liguori <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+##
+import sys
+from ordereddict import OrderedDict
+
+enum_types = []
+event_types = {}
+
+def c_var(name):
+ return '_'.join(name.split('-'))
+
+def genindent(count):
+ ret = ""
+ for i in range(count):
+ ret += " "
+ return ret
+
+def is_dict(obj):
+ if type(obj) in [dict, OrderedDict]:
+ return True
+ return False
+
+def qmp_array_type_to_c(typename):
+ if type(typename) == list or is_dict(typename):
+ return qmp_type_to_c(typename)
+ elif typename == 'int':
+ return 'IntArray *'
+ elif typename == 'str':
+ return 'StringArray *'
+ elif typename == 'bool':
+ return 'BoolArray *'
+ elif typename == 'number':
+ return 'DoubleArray *'
+ else:
+ return qmp_type_to_c(typename)
+
+def qmp_type_should_free(typename):
+ if (type(typename) == list or
+ typename == 'str' or
+ (typename not in ['int', 'bool', 'number'] and
+ typename not in enum_types and not typename.isupper())):
+ return True
+ return False
+
+def qmp_free_func(typename):
+ if type(typename) == list:
+ return qmp_free_func(typename[0])
+ elif typename == 'str':
+ return 'qemu_free'
+ else:
+ return 'qmp_free_%s' % (de_camel_case(typename))
+
+def qmp_type_is_event(typename):
+ if type(typename) == str and typename.isupper():
+ return True
+ return False
+
+def qmp_type_to_c(typename, retval=False, indent=0):
+ if type(typename) == list:
+ return qmp_array_type_to_c(typename[0])
+ elif is_dict(typename):
+ string = 'struct {\n'
+ for key in typename:
+ name = key
+ if key.startswith('*'):
+ name = key[1:]
+ string += "%sbool has_%s;\n" % (genindent(indent + 4), c_var(name))
+ string += "%s%s %s;\n" % (genindent(indent + 4),
+ qmp_type_to_c(typename[key],
+ True,
+ indent=(indent + 4)),
+ c_var(name))
+ string += "%s}" % genindent(indent)
+ return string
+ elif typename == 'int':
+ return 'int64_t'
+ elif not retval and typename == 'str':
+ return 'const char *'
+ elif retval and typename == 'str':
+ return 'char *'
+ elif typename == 'bool':
+ return 'bool'
+ elif typename == 'number':
+ return 'double'
+ elif typename == 'none':
+ return 'void'
+ elif typename in enum_types:
+ return typename
+ elif qmp_type_is_event(typename):
+ return 'struct %s *' % qmp_event_to_c(typename)
+ else:
+ return 'struct %s *' % typename
+
+def qmp_type_to_qobj_ctor(typename):
+ return 'qmp_marshal_type_%s' % typename
+
+def qmp_type_from_qobj(typename):
+ return qobj_to_c(typename)
+
+def parse_args(typeinfo):
+ for member in typeinfo:
+ argname = member
+ argtype = typeinfo[member]
+ optional = False
+ if member.startswith('*'):
+ argname = member[1:]
+ optional = True
+ yield (argname, argtype, optional)
+
+def de_camel_case(name):
+ new_name = ''
+ for ch in name:
+ if ch.isupper() and new_name:
+ new_name += '_'
+ new_name += ch.lower()
+ return new_name
+
+def camel_case(name):
+ new_name = ''
+ first = True
+ for ch in name:
+ if ch == '_':
+ first = True
+ elif first:
+ new_name += ch.upper()
+ first = False
+ else:
+ new_name += ch.lower()
+ return new_name
+
+def qmp_event_to_c(name):
+ return '%sEvent' % camel_case(name)
+
+def qmp_event_func_to_c(name):
+ return '%sFunc' % camel_case(name)
+
+def inprint(string, indent):
+ print '%s%s' % (genindent(indent), string)
+
+def enum_abbreviation(name):
+ ab = ''
+ for ch in name:
+ if ch.isupper():
+ ab += ch
+ return ab
+
+def print_enum_declaration(name, entries):
+ print
+ print 'typedef enum %s {' % name
+ i = 0
+ for entry in entries:
+ print ' %s_%s = %d,' % (enum_abbreviation(name), entry.upper(), i)
+ i += 1
+ print '} %s;' % name
+ print
+ print '%s qmp_type_%s_from_str(const char *str, Error **errp);' % (name, de_camel_case(name))
+ print 'const char *qmp_type_%s_to_str(%s value, Error **errp);' % (de_camel_case(name), name)
+
+def print_enum_definition(name, entries):
+ print '''
+%s qmp_type_%s_from_str(const char *str, Error **errp)
+{''' % (name, de_camel_case(name))
+ first = True
+ for entry in entries:
+ if first:
+ print ' if (strcmp(str, "%s") == 0) {' % entry
+ first = False
+ else:
+ print ' } else if (strcmp(str, "%s") == 0) {' % entry
+ print ' return %s_%s;' % (enum_abbreviation(name), entry.upper())
+ print ''' } else {
+ error_set(errp, QERR_ENUM_VALUE_INVALID, "%s", str);
+ return %s_%s;
+ }
+}''' % (name, enum_abbreviation(name), entries[0].upper())
+
+ print '''
+const char *qmp_type_%s_to_str(%s value, Error **errp)
+{''' % (de_camel_case(name), name)
+ first = True
+ for entry in entries:
+ enum = '%s_%s' % (enum_abbreviation(name), entry.upper())
+ if first:
+ print ' if (value == %s) {' % enum
+ first = False
+ else:
+ print ' } else if (value == %s) {' % enum
+ print ' return "%s";' % entry
+ print ''' } else {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "%%d", value);
+ error_set(errp, QERR_ENUM_VALUE_INVALID, "%s", buf);
+ return NULL;
+ }
+}''' % name
+
+def print_type_declaration(name, typeinfo):
+ if type(typeinfo) == str:
+ print
+ print "typedef %s %s;" % (qmp_type_to_c(typeinfo), name)
+ elif is_dict(typeinfo) and not name.isupper():
+ print
+ print "typedef struct %s %s;" % (name, name)
+ print "struct %s {" % name
+ for key in typeinfo:
+ member = key
+ if key.startswith('*'):
+ member = key[1:]
+ print " bool has_%s;" % c_var(member)
+ print " %s %s;" % (qmp_type_to_c(typeinfo[key], True, indent=4), c_var(member))
+ print " %s *next;" % c_var(name)
+ print "};"
+ print
+ print "%s *qmp_alloc_%s(void);" % (name, de_camel_case(name))
+ print "void qmp_free_%s(%s *obj);" % (de_camel_case(name), name)
+ elif is_dict(typeinfo) and name.isupper():
+ arglist = ['void *opaque']
+ for argname, argtype, optional in parse_args(typeinfo):
+ arglist.append('%s %s' % (qmp_type_to_c(argtype), argname))
+ print
+ print 'typedef void (%s)(%s);' % (qmp_event_func_to_c(name), ', '.join(arglist))
+ print
+ print 'typedef struct %s {' % qmp_event_to_c(name)
+ print ' QmpSignal *signal;'
+ print ' %s *func;' % qmp_event_func_to_c(name)
+ print '} %s;' % qmp_event_to_c(name)
+
+def print_type_free(typeinfo, prefix, indent=4):
+ for argname, argtype, optional in parse_args(typeinfo):
+ if type(argtype) == list:
+ argtype = argtype[0]
+
+ if is_dict(argtype):
+ if optional:
+ inprint('if (%shas_%s) {' % (prefix, argname), indent)
+ print_type_free(argtype, '%s%s.' % (prefix, argname), indent + 4)
+ inprint('}', indent)
+ else:
+ print_type_free(argtype, '%s%s.' % (prefix, argname), indent)
+ elif qmp_type_should_free(argtype):
+ if optional:
+ inprint('if (%shas_%s) {' % (prefix, argname), indent)
+ inprint(' %s(%s%s);' % (qmp_free_func(argtype), prefix, argname), indent)
+ inprint('}', indent)
+ else:
+ inprint('%s(%s%s);' % (qmp_free_func(argtype), prefix, argname), indent)
+
+def print_type_definition(name, typeinfo):
+ if qmp_type_is_event(name):
+ return
+
+ c_var_name = de_camel_case(name)
+
+ print '''
+void qmp_free_%s(%s *obj)
+{
+ if (!obj) {
+ return;
+ }''' % (c_var_name, name)
+
+ print_type_free(typeinfo, 'obj->')
+
+ print '''
+ %s(obj->next);
+ qemu_free(obj);
+}''' % (qmp_free_func(name))
+
+ print '''
+%s *qmp_alloc_%s(void)
+{
+ BUILD_ASSERT(sizeof(%s) < 512);
+ return qemu_mallocz(512);
+}''' % (name, c_var_name, name)
+
+def tokenize(data):
+ while len(data):
+ if data[0] in ['{', '}', ':', ',', '[', ']']:
+ yield data[0]
+ data = data[1:]
+ elif data[0] in ' \n':
+ data = data[1:]
+ elif data[0] == "'":
+ data = data[1:]
+ string = ''
+ while data[0] != "'":
+ string += data[0]
+ data = data[1:]
+ data = data[1:]
+ yield string
+
+def parse_value(tokens):
+ if tokens[0] == '{':
+ ret = OrderedDict()
+ tokens = tokens[1:]
+ while tokens[0] != '}':
+ key = tokens[0]
+ tokens = tokens[1:]
+
+ tokens = tokens[1:] # :
+
+ value, tokens = parse_value(tokens)
+
+ if tokens[0] == ',':
+ tokens = tokens[1:]
+
+ ret[key] = value
+ tokens = tokens[1:]
+ return ret, tokens
+ elif tokens[0] == '[':
+ ret = []
+ tokens = tokens[1:]
+ while tokens[0] != ']':
+ value, tokens = parse_value(tokens)
+ if tokens[0] == ',':
+ tokens = tokens[1:]
+ ret.append(value)
+ tokens = tokens[1:]
+ return ret, tokens
+ else:
+ return tokens[0], tokens[1:]
+
+def ordered_eval(string):
+ return parse_value(map(lambda x: x, tokenize(string)))[0]
+
+if len(sys.argv) == 2:
+ if sys.argv[1] == '--types-body':
+ kind = 'types-body'
+ elif sys.argv[1] == '--types-header':
+ kind = 'types-header'
+
+if kind == 'types-header':
+ print '''/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT */
+#ifndef QMP_TYPES_H
+#define QMP_TYPES_H
+
+#include "qmp-types-core.h"
+
+'''
+elif kind == 'types-body':
+ print '''/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT */
+
+#include "qmp-types.h"
+#include "qemu-common.h"
+'''
+
+exprs = []
+expr = ''
+
+for line in sys.stdin:
+ if line.startswith('#') or line == '\n':
+ continue
+
+ if line.startswith(' '):
+ expr += line
+ elif expr:
+ s = ordered_eval(expr)
+ exprs.append(s)
+ expr = line
+ else:
+ expr += line
+
+if expr:
+ s = ordered_eval(expr)
+ exprs.append(s)
+
+for s in exprs:
+ if is_dict(s):
+ key = s.keys()[0]
+ if is_dict(s[key]):
+ if qmp_type_is_event(key):
+ event_types[key] = s[key]
+ if kind == 'types-body':
+ print_type_definition(key, s[key])
+ elif kind == 'types-header':
+ print_type_declaration(key, s[key])
+ else:
+ enum_types.append(key)
+ if kind == 'types-header':
+ print_enum_declaration(key, s[key])
+ elif kind == 'types-body':
+ print_enum_definition(key, s[key])
+
+if kind.endswith('header'):
+ print '#endif'
diff --git a/qmp-schema.json b/qmp-schema.json
new file mode 100644
index 0000000..e69de29
diff --git a/qmp-types-core.h b/qmp-types-core.h
new file mode 100644
index 0000000..dbf1fd8
--- /dev/null
+++ b/qmp-types-core.h
@@ -0,0 +1,27 @@
+/*
+ * QAPI
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2. See
+ * the COPYING.LIB file in the top-level directory.
+ */
+#ifndef QMP_TYPES_CORE_H
+#define QMP_TYPES_CORE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "error.h"
+
+typedef struct QmpSignal QmpSignal;
+
+#define BUILD_ASSERT(cond) do { \
+ (void)sizeof(int[-1+!!(cond)]); \
+} while (0)
+
+#define BUILD_BUG() BUILD_ASSERT(0)
+
+#endif
--
1.7.0.4
next prev parent reply other threads:[~2011-03-07 1:23 UTC|newest]
Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-07 1:22 [Qemu-devel] [PATCH 00/22] QAPI Round 1 Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 01/22] Add hard build dependency on glib Anthony Liguori
2011-03-07 10:59 ` Daniel P. Berrange
2011-03-07 13:55 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 02/22] qerror: expose a function to format an error Anthony Liguori
2011-03-07 11:14 ` Stefan Hajnoczi
2011-03-07 13:38 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 03/22] qapi: add Error object Anthony Liguori
2011-03-07 11:06 ` Daniel P. Berrange
2011-03-07 13:59 ` Anthony Liguori
2011-03-07 14:24 ` Anthony Liguori
2011-03-07 11:38 ` Stefan Hajnoczi
2011-03-07 13:36 ` Anthony Liguori
2011-03-07 13:55 ` Stefan Hajnoczi
2011-03-07 1:22 ` [Qemu-devel] [PATCH 04/22] qerror: split out the reporting bits of QError Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 05/22] qerror: add new error message for invalid enum values Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 06/22] qapi: add JSON parsing error message Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 07/22] json: propagate error from parser Anthony Liguori
2011-03-07 1:22 ` Anthony Liguori [this message]
2011-03-07 1:57 ` [Qemu-devel] [PATCH 08/22] qapi: add code generator for qmp-types Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 09/22] qapi: add code generator for type marshallers Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 10/22] qapi: add core QMP server support Anthony Liguori
2011-03-07 13:09 ` Stefan Hajnoczi
2011-03-07 13:39 ` Anthony Liguori
2011-03-07 13:46 ` Daniel P. Berrange
2011-03-07 13:54 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 11/22] qapi: add signal support to core QMP server Anthony Liguori
2011-03-07 13:21 ` Stefan Hajnoczi
2011-03-07 13:53 ` Anthony Liguori
2011-03-07 14:36 ` Stefan Hajnoczi
2011-03-07 14:41 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 12/22] qapi: add QAPI module type Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 13/22] qapi: add code generators for QMP command marshaling Anthony Liguori
2011-03-07 13:27 ` Stefan Hajnoczi
2011-03-07 13:44 ` Anthony Liguori
2011-03-07 14:38 ` Stefan Hajnoczi
2011-03-07 1:22 ` [Qemu-devel] [PATCH 14/22] qapi: add query-version QMP command Anthony Liguori
2011-03-07 13:35 ` Stefan Hajnoczi
2011-03-07 13:41 ` Anthony Liguori
2011-03-09 13:28 ` Avi Kivity
2011-03-09 13:44 ` Anthony Liguori
2011-03-09 13:51 ` Avi Kivity
2011-03-09 14:13 ` Anthony Liguori
2011-03-09 13:36 ` Avi Kivity
2011-03-09 14:11 ` Anthony Liguori
2011-03-09 14:37 ` Avi Kivity
2011-03-09 14:47 ` Anthony Liguori
2011-03-10 12:41 ` Avi Kivity
2011-03-10 12:46 ` Avi Kivity
2011-03-10 13:52 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 15/22] qapi: add new QMP server that uses CharDriverState Anthony Liguori
2011-03-07 13:52 ` Stefan Hajnoczi
2011-03-07 14:02 ` Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 16/22] vl: add a new -qmp2 option to expose experimental QMP server Anthony Liguori
2011-03-07 1:22 ` [Qemu-devel] [PATCH 17/22] qapi: add QMP quit command Anthony Liguori
2011-03-07 1:23 ` [Qemu-devel] [PATCH 18/22] qapi: add QMP qmp_capabilities command Anthony Liguori
2011-03-07 1:23 ` [Qemu-devel] [PATCH 19/22] qapi: add QMP put-event command Anthony Liguori
2011-03-09 13:31 ` Avi Kivity
2011-03-09 13:48 ` Anthony Liguori
2011-03-09 13:58 ` Avi Kivity
2011-03-09 14:26 ` Anthony Liguori
2011-03-10 12:39 ` Avi Kivity
2011-03-10 14:12 ` Anthony Liguori
2011-03-10 14:24 ` Avi Kivity
2011-03-10 15:30 ` Avi Kivity
2011-03-10 15:41 ` Anthony Liguori
2011-03-10 15:49 ` Avi Kivity
2011-03-10 16:42 ` Anthony Liguori
2011-03-12 20:37 ` Avi Kivity
2011-03-10 15:33 ` Anthony Liguori
2011-03-10 15:45 ` Avi Kivity
2011-03-10 16:04 ` Anthony Liguori
2011-03-12 20:42 ` Avi Kivity
2011-03-12 23:30 ` Anthony Liguori
2011-03-07 1:23 ` [Qemu-devel] [PATCH 20/22] qapi: add code generator for libqmp Anthony Liguori
2011-03-07 1:23 ` [Qemu-devel] [PATCH 21/22] qapi: add test-libqmp Anthony Liguori
2011-03-07 1:23 ` [Qemu-devel] [PATCH 22/22] qapi: generate HTML report for test-libqmp Anthony Liguori
2011-03-07 2:11 ` Anthony Liguori
2011-03-07 1:26 ` [Qemu-devel] [PATCH] qapi: qmp-types.c and qmp-types.h Anthony Liguori
2011-03-07 1:27 ` [Qemu-devel] [PATCH] qapi: qmp-marshal-types.c and qmp-marshal-types.h Anthony Liguori
2011-03-07 1:28 ` [Qemu-devel] [PATCH] qapi: add qmp-marshal.c and qmp.h Anthony Liguori
2011-03-07 1:29 ` [Qemu-devel] [PATCH] qapi: add libqmp.c and libqmp.h Anthony Liguori
2011-03-07 15:08 ` [Qemu-devel] [PATCH 00/22] QAPI Round 1 Stefan Hajnoczi
2011-03-07 15:59 ` Anthony Liguori
2011-03-08 11:12 ` Avi Kivity
2011-03-08 13:35 ` Anthony Liguori
2011-03-08 13:45 ` Avi Kivity
2011-03-08 13:54 ` Anthony Liguori
2011-03-08 14:00 ` Avi Kivity
2011-03-08 14:10 ` Anthony Liguori
2011-03-08 14:17 ` Avi Kivity
2011-03-08 14:20 ` Anthony Liguori
2011-03-08 14:38 ` Anthony Liguori
2011-03-08 14:52 ` Avi Kivity
2011-03-08 15:03 ` Anthony Liguori
2011-03-08 17:44 ` Avi Kivity
2011-03-08 19:19 ` Anthony Liguori
2011-03-09 8:51 ` Avi Kivity
2011-03-09 13:12 ` Anthony Liguori
2011-03-09 13:14 ` Avi Kivity
2011-03-09 13:51 ` Anthony Liguori
2011-03-09 13:55 ` Avi Kivity
2011-03-09 14:15 ` Anthony Liguori
2011-03-09 13:51 ` Michael Roth
2011-03-07 20:59 ` Anthony Liguori
2011-03-07 22:00 ` Stefan Hajnoczi
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=1299460984-15849-9-git-send-email-aliguori@us.ibm.com \
--to=aliguori@us.ibm.com \
--cc=aglitke@linux.vnet.ibm.com \
--cc=armbru@redhat.com \
--cc=lcapitulino@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).