qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Luiz Capitulino <lcapitulino@redhat.com>,
	armbru@redhat.com,
	"open list:Block layer core" <qemu-block@nongnu.org>,
	Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: [Qemu-devel] [PATCH v11 21/28] qapi: Convert qtype_code into qapi enum type
Date: Tue, 10 Nov 2015 23:51:23 -0700	[thread overview]
Message-ID: <1447224690-9743-22-git-send-email-eblake@redhat.com> (raw)
In-Reply-To: <1447224690-9743-1-git-send-email-eblake@redhat.com>

What's more meta than using qapi to define qapi? :)

Convert qtype_code into a full-fledged[*] builtin qapi enum type,
so that a subsequent patch can then use it as the discriminator
type of qapi alternate types.  Doing so is easiest when renaming
it to qapi conventions, as QTypeCode.  Fortunately, there are not
many places in the tree that were actually spelling the type name
out, and the judicious use of 'prefix' in the qapi defintion
avoids churn to the spelling of the enum constants.

To avoid circular definitions, we have to flip the order of
inclusion between "qobject.h" vs. "qapi-types.h".  Back in commit
28770e0, we had the latter include the former, so that we could
use 'QObject *' for our implementation of 'any'.  But that usage
also works with only a forward declaration, whereas the
definition of QType requires QTypeCode to be a complete type.

[*] The type has to be builtin, rather than declared in
qapi/common.json, because we want to use it for alternates even
when common.json is not included. But since it is the first
builtin enum type, we have to add special cases to qapi-types
and qapi-visit to only emit definitions once, even when two
qapi files are being compiled into the same binary (the way we
already handled builtin list types like 'intList').  We may
need to revisit how multiple qapi files share common types,
but that's a project for another day.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v11: new patch
---
 block/qapi.c                             |  4 ++--
 docs/qapi-code-gen.txt                   |  1 +
 include/hw/qdev-core.h                   |  2 +-
 include/qapi/qmp/qobject.h               | 19 +++----------------
 qobject/qdict.c                          |  2 +-
 scripts/qapi-types.py                    | 13 ++++++++++---
 scripts/qapi-visit.py                    | 10 ++++++++--
 scripts/qapi.py                          |  7 ++++++-
 tests/qapi-schema/alternate-empty.out    |  2 ++
 tests/qapi-schema/comments.out           |  2 ++
 tests/qapi-schema/empty.out              |  2 ++
 tests/qapi-schema/event-case.out         |  2 ++
 tests/qapi-schema/flat-union-empty.out   |  2 ++
 tests/qapi-schema/ident-with-escape.out  |  2 ++
 tests/qapi-schema/include-relpath.out    |  2 ++
 tests/qapi-schema/include-repetition.out |  2 ++
 tests/qapi-schema/include-simple.out     |  2 ++
 tests/qapi-schema/indented-expr.out      |  2 ++
 tests/qapi-schema/qapi-schema-test.out   |  2 ++
 tests/qapi-schema/union-clash-data.out   |  2 ++
 tests/qapi-schema/union-empty.out        |  2 ++
 21 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index ec0f513..4211f11 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -539,7 +539,7 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
     int i = 0;

     for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
-        qtype_code type = qobject_type(entry->value);
+        QTypeCode type = qobject_type(entry->value);
         bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
         const char *format = composite ? "%*s[%i]:\n" : "%*s[%i]: ";

@@ -557,7 +557,7 @@ static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation,
     const QDictEntry *entry;

     for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
-        qtype_code type = qobject_type(entry->value);
+        QTypeCode type = qobject_type(entry->value);
         bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
         const char *format = composite ? "%*s%s:\n" : "%*s%s: ";
         char key[strlen(entry->key) + 1];
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 54a6a7b..35301c5 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -163,6 +163,7 @@ The following types are predefined, and map to C as follows:
                        accepts size suffixes
   bool      bool       JSON true or false
   any       QObject *  any JSON value
+  QTypeCode QTypeCode  JSON string of enum QTypeCode values


 === Includes ===
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 8057aed..8e7df8e 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -239,7 +239,7 @@ struct Property {
     PropertyInfo *info;
     int          offset;
     uint8_t      bitnr;
-    qtype_code   qtype;
+    QTypeCode    qtype;
     int64_t      defval;
     int          arrayoffset;
     PropertyInfo *arrayinfo;
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index 4b96ed5..8d6322b 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -34,23 +34,10 @@

 #include <stddef.h>
 #include <assert.h>
-
-typedef enum {
-    QTYPE_NONE,    /* sentinel value, no QObject has this type code */
-    QTYPE_QNULL,
-    QTYPE_QINT,
-    QTYPE_QSTRING,
-    QTYPE_QDICT,
-    QTYPE_QLIST,
-    QTYPE_QFLOAT,
-    QTYPE_QBOOL,
-    QTYPE_MAX,
-} qtype_code;
-
-struct QObject;
+#include "qapi-types.h"

 typedef struct QType {
-    qtype_code code;
+    QTypeCode code;
     void (*destroy)(struct QObject *);
 } QType;

@@ -101,7 +88,7 @@ static inline void qobject_decref(QObject *obj)
 /**
  * qobject_type(): Return the QObject's type
  */
-static inline qtype_code qobject_type(const QObject *obj)
+static inline QTypeCode qobject_type(const QObject *obj)
 {
     assert(obj->type != NULL);
     return obj->type->code;
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 2d67bf1..92915f4 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -185,7 +185,7 @@ size_t qdict_size(const QDict *qdict)
  * qdict_get_obj(): Get a QObject of a specific type
  */
 static QObject *qdict_get_obj(const QDict *qdict, const char *key,
-                              qtype_code type)
+                              QTypeCode type)
 {
     QObject *obj;

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2f2f7df..93e905a 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -233,8 +233,14 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
         self.defn += gen_type_cleanup(name)

     def visit_enum_type(self, name, info, values, prefix):
-        self._fwdecl += gen_enum(name, values, prefix)
-        self._fwdefn += gen_enum_lookup(name, values, prefix)
+        # Special case for our lone builtin enum type
+        if name == 'QTypeCode':
+            self._btin += gen_enum(name, values, prefix)
+            if do_builtins:
+                self.defn += gen_enum_lookup(name, values, prefix)
+        else:
+            self._fwdecl += gen_enum(name, values, prefix)
+            self._fwdefn += gen_enum_lookup(name, values, prefix)

     def visit_array_type(self, name, info, element_type):
         if isinstance(element_type, QAPISchemaBuiltinType):
@@ -319,7 +325,8 @@ fdef.write(mcgen('''
 fdecl.write(mcgen('''
 #include <stdbool.h>
 #include <stdint.h>
-#include "qapi/qmp/qobject.h"
+
+typedef struct QObject QObject;
 '''))

 schema = QAPISchema(input_file)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 94cd113..6f0b4e1 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -347,8 +347,14 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
                     isinstance(entity, QAPISchemaObjectType))

     def visit_enum_type(self, name, info, values, prefix):
-        self.decl += gen_visit_decl(name, scalar=True)
-        self.defn += gen_visit_enum(name)
+        # Special case for our lone builtin enum type
+        if name == 'QTypeCode':
+            self._btin += gen_visit_decl(name, scalar=True)
+            if do_builtins:
+                self.defn += gen_visit_enum(name)
+        else:
+            self.decl += gen_visit_decl(name, scalar=True)
+            self.defn += gen_visit_enum(name)

     def visit_array_type(self, name, info, element_type):
         decl = gen_visit_decl(name)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index ed7a32b..d4ef08e 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -33,7 +33,7 @@ builtin_types = {
     'uint32':   'QTYPE_QINT',
     'uint64':   'QTYPE_QINT',
     'size':     'QTYPE_QINT',
-    'any':      None,           # any qtype_code possible, actually
+    'any':      None,           # any QTypeCode possible, actually
 }

 # Whitelist of commands allowed to return a non-dictionary
@@ -1243,6 +1243,11 @@ class QAPISchema(object):
         self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
                                                           [], None)
         self._def_entity(self.the_empty_object_type)
+        self._def_entity(QAPISchemaEnumType('QTypeCode', None,
+                                            ['none', 'qnull', 'qint',
+                                             'qstring', 'qdict', 'qlist',
+                                             'qfloat', 'qbool'],
+                                            'QTYPE'))

     def _make_implicit_enum_type(self, name, info, values):
         name = name + 'Kind'   # Use namespace reserved by add_name()
diff --git a/tests/qapi-schema/alternate-empty.out b/tests/qapi-schema/alternate-empty.out
index 0f153b6..ab5a629 100644
--- a/tests/qapi-schema/alternate-empty.out
+++ b/tests/qapi-schema/alternate-empty.out
@@ -2,3 +2,5 @@ object :empty
 alternate Alt
     case i: int
 enum AltKind ['i']
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 9e2c656..59904ef 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,2 +1,4 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 272b161..42121b5 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1 +1,3 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index cdfd264..5e4d10e 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,2 +1,4 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 event oops None
diff --git a/tests/qapi-schema/flat-union-empty.out b/tests/qapi-schema/flat-union-empty.out
index 0e0665a..2fd07b9 100644
--- a/tests/qapi-schema/flat-union-empty.out
+++ b/tests/qapi-schema/flat-union-empty.out
@@ -2,6 +2,8 @@ object :empty
 object Base
     member type: Empty optional=False
 enum Empty []
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 object Union
     base Base
     tag type
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index f4542b1..523eec9 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,5 +1,7 @@
 object :empty
 object :obj-fooA-arg
     member bar1: str optional=False
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 command fooA :obj-fooA-arg -> None
    gen=True success_response=True
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
index 9e2c656..59904ef 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,2 +1,4 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
index 9e2c656..59904ef 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,2 +1,4 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
index 9e2c656..59904ef 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,2 +1,4 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index 226d300..b7e49fc 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,4 +1,6 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 command eins None -> None
    gen=True success_response=True
 command zwei None -> None
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 786024e..d05fc37 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -101,6 +101,8 @@ object NestedEnumsOne
     member enum4: EnumOne optional=True
 enum QEnumTwo ['value1', 'value2']
     prefix QENUM_TWO
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 object TestStruct
     member integer: int optional=False
     member boolean: bool optional=False
diff --git a/tests/qapi-schema/union-clash-data.out b/tests/qapi-schema/union-clash-data.out
index cea8551..e4a2932 100644
--- a/tests/qapi-schema/union-clash-data.out
+++ b/tests/qapi-schema/union-clash-data.out
@@ -1,6 +1,8 @@
 object :empty
 object :obj-int-wrapper
     member data: int optional=False
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 object TestUnion
     member type: TestUnionKind optional=False
     case data: :obj-int-wrapper
diff --git a/tests/qapi-schema/union-empty.out b/tests/qapi-schema/union-empty.out
index 9c89fd1..5e7764c 100644
--- a/tests/qapi-schema/union-empty.out
+++ b/tests/qapi-schema/union-empty.out
@@ -1,4 +1,6 @@
 object :empty
+enum QTypeCode ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
+    prefix QTYPE
 object Union
     member type: UnionKind optional=False
 enum UnionKind []
-- 
2.4.3

  parent reply	other threads:[~2015-11-11  6:52 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-11  6:51 [Qemu-devel] [PATCH v11 00/28] qapi member collision, alternate layout (post-introspection cleanups, subset D) Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 01/28] qapi: Track simple union tag in object.local_members Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 02/28] qapi-types: Consolidate gen_struct() and gen_union() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 03/28] qapi-types: Simplify gen_struct_field[s] Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 04/28] qapi: Drop obsolete tag value collision assertions Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 05/28] qapi: Simplify QAPISchemaObjectTypeMember.check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 06/28] qapi: Clean up after previous commit Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 07/28] qapi: Fix up commit 7618b91's clash sanity checking change Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 08/28] qapi: Eliminate QAPISchemaObjectType.check() variable members Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 09/28] qapi: Factor out QAPISchemaObjectTypeMember.check_clash() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 10/28] qapi: Simplify QAPISchemaObjectTypeVariants.check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 11/28] qapi: Check for qapi collisions of flat union branches Eric Blake
2015-11-11 13:42   ` Markus Armbruster
2015-11-11 15:49     ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 12/28] qapi: Factor out QAPISchemaObjectType.check_clash() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 13/28] qapi: Hoist tag collision check to Variants.check() Eric Blake
2015-11-11 13:56   ` Markus Armbruster
2015-11-11 16:11     ` Eric Blake
2015-11-11 17:03       ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 14/28] qapi: Remove outdated tests related to QMP/branch collisions Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 15/28] qapi: Track owner of each object member Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 16/28] qapi: Detect collisions in C member names Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 17/28] cpu: Convert CpuInfo into flat union Eric Blake
2015-11-11 14:13   ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 18/28] qerror: more error_setg() usage Eric Blake
2015-11-11 13:26   ` Andreas Färber
2015-11-11 14:21   ` Markus Armbruster
2015-11-11 14:23     ` Andreas Färber
2015-11-11 15:51       ` Eric Blake
2015-11-11 16:19     ` Eric Blake
2015-11-11 17:31       ` Markus Armbruster
2015-11-11 17:44         ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 19/28] qapi: Change munging of CamelCase enum values Eric Blake
2015-11-11 13:29   ` Andreas Färber
2015-11-11 14:50   ` Markus Armbruster
2015-11-11 16:03     ` Eric Blake
2015-11-11 17:11       ` Markus Armbruster
2015-11-12  8:34         ` Gerd Hoffmann
2015-11-12 11:16           ` Markus Armbruster
2015-11-12  8:29       ` Gerd Hoffmann
2015-11-11 16:06     ` Eric Blake
2015-11-13 17:46   ` Eric Blake
2015-11-13 18:13     ` Markus Armbruster
2015-11-13 21:37       ` Eric Blake
2015-11-16 14:30         ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 20/28] qapi: Forbid case-insensitive clashes Eric Blake
2015-11-11 14:53   ` Markus Armbruster
2015-11-13  5:32     ` Eric Blake
2015-11-11  6:51 ` Eric Blake [this message]
2015-11-11 16:42   ` [Qemu-devel] [PATCH v11 21/28] qapi: Convert qtype_code into qapi enum type Markus Armbruster
2015-11-11 17:03     ` Eric Blake
2015-11-12 13:16       ` Markus Armbruster
2015-11-18  6:27         ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 22/28] qapi: Simplify visiting of alternate types Eric Blake
2015-11-12 14:21   ` Markus Armbruster
2015-11-12 15:54   ` Markus Armbruster
2015-11-13 23:54   ` Eric Blake
2015-11-16 14:31     ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 23/28] qapi: Fix alternates that accept 'number' but not 'int' Eric Blake
2015-11-12 15:01   ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 24/28] qapi: Add positive tests to qapi-schema-test Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 25/28] qapi: Simplify visits of optional fields Eric Blake
2015-11-12 15:11   ` Markus Armbruster
2015-11-12 15:30     ` Eric Blake
2015-11-12 16:20       ` Markus Armbruster
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 26/28] qapi: Move duplicate member checks to schema check() Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 27/28] qapi: Move duplicate enum value " Eric Blake
2015-11-12 15:46   ` Markus Armbruster
2015-11-12 16:08     ` Eric Blake
2015-11-18  6:48     ` Eric Blake
2015-11-11  6:51 ` [Qemu-devel] [PATCH v11 28/28] qapi: Detect base class loops Eric Blake
2015-11-12 16:06   ` Markus Armbruster

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1447224690-9743-22-git-send-email-eblake@redhat.com \
    --to=eblake@redhat.com \
    --cc=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-block@nongnu.org \
    --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).