All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V9 0/7] Introduce a QMP client
@ 2011-09-29 11:37 Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 1/7] libxl: Rename libxl.idl to libxl_types.idl Anthony PERARD
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Only the last patch have changed on this series since the v8.
Replace of SOCK_NONBLOCK by a call to fcntl in qmp_open().
The rest of the patch have been acked-by Ian Campbell.


Anthony PERARD (7):
  libxl: Rename libxl.idl to libxl_types.idl.
  libxl: Add get/set_default_namespace in libxltypes.py.
  libxl: Introduce libxl_internal_types.idl.
  libxl: Introduce libxl__realloc.
  libxl: Intruduce libxl__strndup.
  libxl: Introduce JSON parsing stuff.
  libxl: Introduce a QMP client

 README                                     |    1 +
 tools/libxl/Makefile                       |   21 +-
 tools/libxl/gentypes.py                    |    9 +-
 tools/libxl/libxl.c                        |    2 +
 tools/libxl/libxl_create.c                 |    4 +
 tools/libxl/libxl_dm.c                     |   10 +
 tools/libxl/libxl_internal.c               |   34 ++
 tools/libxl/libxl_internal.h               |  122 ++++++
 tools/libxl/libxl_json.c                   |  560 ++++++++++++++++++++++++++
 tools/libxl/libxl_qmp.c                    |  595 ++++++++++++++++++++++++++++
 tools/libxl/{libxl.idl => libxl_types.idl} |    2 +
 tools/libxl/libxl_types_internal.idl       |    9 +
 tools/libxl/libxltypes.py                  |   18 +-
 tools/ocaml/libs/xl/Makefile               |    4 +-
 tools/python/Makefile                      |    4 +-
 15 files changed, 1377 insertions(+), 18 deletions(-)
 create mode 100644 tools/libxl/libxl_json.c
 create mode 100644 tools/libxl/libxl_qmp.c
 rename tools/libxl/{libxl.idl => libxl_types.idl} (99%)
 create mode 100644 tools/libxl/libxl_types_internal.idl

-- 
Anthony PERARD

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

* [PATCH V9 1/7] libxl: Rename libxl.idl to libxl_types.idl.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 2/7] libxl: Add get/set_default_namespace in libxltypes.py Anthony PERARD
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/Makefile                       |   12 ++++++------
 tools/libxl/{libxl.idl => libxl_types.idl} |    0
 tools/ocaml/libs/xl/Makefile               |    4 ++--
 tools/python/Makefile                      |    4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)
 rename tools/libxl/{libxl.idl => libxl_types.idl} (100%)

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 3eeb26f..330ee6e 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -52,8 +52,8 @@ $(XL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h
 $(XL_OBJS): CFLAGS += $(CFLAGS_libxenlight)
 
 testidl.o: CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenlight)
-testidl.c: libxl.idl gentest.py libxl.h
-	$(PYTHON) gentest.py libxl.idl testidl.c.new
+testidl.c: libxl_types.idl gentest.py libxl.h
+	$(PYTHON) gentest.py libxl_types.idl testidl.c.new
 	mv testidl.c.new testidl.c
 
 .PHONY: all
@@ -84,10 +84,10 @@ libxl.h: _libxl_types.h
 
 $(LIBXL_OBJS) $(LIBXLU_OBJS) $(XL_OBJS): libxl.h
 
-_libxl_%.h _libxl_%.c: libxl.idl gen%.py libxl%.py
-	$(PYTHON) gen$*.py libxl.idl __libxl_$*.h __libxl_$*.c
-	$(call move-if-changed,__libxl_$*.h,_libxl_$*.h)
-	$(call move-if-changed,__libxl_$*.c,_libxl_$*.c)
+_libxl_type%.h _libxl_type%.c: libxl_type%.idl gentypes.py libxltypes.py
+	$(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*.c
+	$(call move-if-changed,__libxl_type$*.h,_libxl_type$*.h)
+	$(call move-if-changed,__libxl_type$*.c,_libxl_type$*.c)
 
 libxenlight.so: libxenlight.so.$(MAJOR)
 	ln -sf $< $@
diff --git a/tools/libxl/libxl.idl b/tools/libxl/libxl_types.idl
similarity index 100%
rename from tools/libxl/libxl.idl
rename to tools/libxl/libxl_types.idl
diff --git a/tools/ocaml/libs/xl/Makefile b/tools/ocaml/libs/xl/Makefile
index 342dc35..a1e79a5 100644
--- a/tools/ocaml/libs/xl/Makefile
+++ b/tools/ocaml/libs/xl/Makefile
@@ -45,10 +45,10 @@ xl.mli: xl.mli.in _libxl_types.mli.in
 	  < xl.mli.in > xl.mli.tmp
 	$(Q)mv xl.mli.tmp xl.mli
 
-_libxl_types.ml.in _libxl_types.mli.in _libxl_types.inc: genwrap.py $(XEN_ROOT)/tools/libxl/libxl.idl \
+_libxl_types.ml.in _libxl_types.mli.in _libxl_types.inc: genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \
                 $(XEN_ROOT)/tools/libxl/libxltypes.py
 	PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \
-		$(XEN_ROOT)/tools/libxl/libxl.idl \
+		$(XEN_ROOT)/tools/libxl/libxl_types.idl \
 		_libxl_types.mli.in _libxl_types.ml.in _libxl_types.inc
 
 libs: $(LIBS)
diff --git a/tools/python/Makefile b/tools/python/Makefile
index de44178..b7bc501 100644
--- a/tools/python/Makefile
+++ b/tools/python/Makefile
@@ -10,10 +10,10 @@ genpath-target = $(call buildmakevars2file,$(XENPATH))
 $(eval $(genpath-target))
 
 .PHONY: build
-build: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl.idl \
+build: genpath genwrap.py $(XEN_ROOT)/tools/libxl/libxl_types.idl \
 		$(XEN_ROOT)/tools/libxl/libxltypes.py
 	PYTHONPATH=$(XEN_ROOT)/tools/libxl $(PYTHON) genwrap.py \
-		$(XEN_ROOT)/tools/libxl/libxl.idl \
+		$(XEN_ROOT)/tools/libxl/libxl_types.idl \
 		xen/lowlevel/xl/_pyxl_types.h \
 		xen/lowlevel/xl/_pyxl_types.c
 	CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py build
-- 
Anthony PERARD

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

* [PATCH V9 2/7] libxl: Add get/set_default_namespace in libxltypes.py.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 1/7] libxl: Rename libxl.idl to libxl_types.idl Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 3/7] libxl: Introduce libxl_internal_types.idl Anthony PERARD
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/libxl_types.idl |    2 ++
 tools/libxl/libxltypes.py   |   18 ++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 5b7e731..0d28283 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -3,6 +3,8 @@
 # Builtin libxl types
 #
 
+namespace("libxl_")
+
 libxl_domid = Builtin("domid")
 libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE)
 libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE)
diff --git a/tools/libxl/libxltypes.py b/tools/libxl/libxltypes.py
index f1a4dcf..86ab4b9 100644
--- a/tools/libxl/libxltypes.py
+++ b/tools/libxl/libxltypes.py
@@ -8,10 +8,23 @@ DIR_IN   = 1
 DIR_OUT  = 2
 DIR_BOTH = 3
 
+_default_namespace = ""
+def namespace(s):
+    if type(s) != str:
+        raise TypeError, "Require a string for the default namespace."
+    global _default_namespace
+    _default_namespace = s
+
+def _get_default_namespace():
+    global _default_namespace
+    return _default_namespace
+
+
 class Type(object):
     def __init__(self, typename, **kwargs):
         self.comment = kwargs.setdefault('comment', None)
-        self.namespace = kwargs.setdefault('namespace', "libxl_")
+        self.namespace = kwargs.setdefault('namespace',
+                _get_default_namespace())
         self.dir = kwargs.setdefault('dir', DIR_BOTH)
         if self.dir not in [DIR_NONE, DIR_IN, DIR_OUT, DIR_BOTH]:
             raise ValueError
@@ -256,7 +269,8 @@ def parse(f):
         elif isinstance(t,type(object)) and issubclass(t, Type):
             globs[n] = t
         elif n in ['PASS_BY_REFERENCE', 'PASS_BY_VALUE',
-                   'DIR_NONE', 'DIR_IN', 'DIR_OUT', 'DIR_BOTH']:
+                   'DIR_NONE', 'DIR_IN', 'DIR_OUT', 'DIR_BOTH',
+                   'namespace']:
             globs[n] = t
 
     try:
-- 
Anthony PERARD

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

* [PATCH V9 3/7] libxl: Introduce libxl_internal_types.idl.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 1/7] libxl: Rename libxl.idl to libxl_types.idl Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 2/7] libxl: Add get/set_default_namespace in libxltypes.py Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 4/7] libxl: Introduce libxl__realloc Anthony PERARD
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/Makefile                 |    4 +++-
 tools/libxl/gentypes.py              |    9 +++++----
 tools/libxl/libxl_internal.h         |    1 +
 tools/libxl/libxl_types_internal.idl |    9 +++++++++
 4 files changed, 18 insertions(+), 5 deletions(-)
 create mode 100644 tools/libxl/libxl_types_internal.idl

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 330ee6e..1f6b418 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -35,7 +35,7 @@ LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
 			libxl_internal.o libxl_utils.o libxl_uuid.o $(LIBXL_OBJS-y)
-LIBXL_OBJS += _libxl_types.o libxl_flask.o
+LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
 
@@ -81,8 +81,10 @@ _libxl_paths.h: genpath
 libxl_paths.c: _libxl_paths.h
 
 libxl.h: _libxl_types.h
+libxl_internal.h: _libxl_types_internal.h
 
 $(LIBXL_OBJS) $(LIBXLU_OBJS) $(XL_OBJS): libxl.h
+$(LIBXL_OBJS): libxl_internal.h
 
 _libxl_type%.h _libxl_type%.c: libxl_type%.idl gentypes.py libxltypes.py
 	$(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*.c
diff --git a/tools/libxl/gentypes.py b/tools/libxl/gentypes.py
index c66a33c..ecf5f15 100644
--- a/tools/libxl/gentypes.py
+++ b/tools/libxl/gentypes.py
@@ -150,8 +150,9 @@ if __name__ == '__main__':
 
     f = open(header, "w")
 
-    f.write("""#ifndef __LIBXL_TYPES_H
-#define __LIBXL_TYPES_H
+    header_define = header.upper().replace('.','_')
+    f.write("""#ifndef %s
+#define %s
 
 /*
  * DO NOT EDIT.
@@ -160,7 +161,7 @@ if __name__ == '__main__':
  * "%s"
  */
 
-""" % " ".join(sys.argv))
+""" % (header_define, header_define, " ".join(sys.argv)))
 
     for ty in types:
         f.write(libxl_C_type_define(ty) + ";\n")
@@ -172,7 +173,7 @@ if __name__ == '__main__':
             f.write("extern libxl_enum_string_table %s_string_table[];\n" % (ty.typename))
         f.write("\n")
 
-    f.write("""#endif /* __LIBXL_TYPES_H */\n""")
+    f.write("""#endif /* %s */\n""" % (header_define))
     f.close()
 
     print "outputting libxl type implementations to %s" % impl
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index b431632..29cdba4 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -35,6 +35,7 @@
 
 #include "flexarray.h"
 #include "libxl_utils.h"
+#include "_libxl_types_internal.h"
 
 #define LIBXL_DESTROY_TIMEOUT 10
 #define LIBXL_DEVICE_MODEL_START_TIMEOUT 10
diff --git a/tools/libxl/libxl_types_internal.idl b/tools/libxl/libxl_types_internal.idl
new file mode 100644
index 0000000..20236a6
--- /dev/null
+++ b/tools/libxl/libxl_types_internal.idl
@@ -0,0 +1,9 @@
+namespace("libxl__")
+
+libxl__qmp_message_type  = Enumeration("qmp_message_type", [
+    (1, "QMP"),
+    (2, "return"),
+    (3, "error"),
+    (4, "event"),
+    (5, "invalid"),
+    ])
-- 
Anthony PERARD

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

* [PATCH V9 4/7] libxl: Introduce libxl__realloc.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
                   ` (2 preceding siblings ...)
  2011-09-29 11:37 ` [PATCH V9 3/7] libxl: Introduce libxl_internal_types.idl Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 5/7] libxl: Intruduce libxl__strndup Anthony PERARD
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/libxl_internal.c |   24 ++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |    1 +
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index e259278..c4d54f9 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -102,6 +102,30 @@ void *libxl__calloc(libxl__gc *gc, size_t nmemb, size_t size)
     return ptr;
 }
 
+void *libxl__realloc(libxl__gc *gc, void *ptr, size_t new_size)
+{
+    void *new_ptr = realloc(ptr, new_size);
+    int i = 0;
+
+    if (new_ptr == NULL && new_size != 0) {
+        return NULL;
+    }
+
+    if (ptr == NULL) {
+        libxl__ptr_add(gc, new_ptr);
+    } else if (new_ptr != ptr) {
+        for (i = 0; i < gc->alloc_maxsize; i++) {
+            if (gc->alloc_ptrs[i] == ptr) {
+                gc->alloc_ptrs[i] = new_ptr;
+                break;
+            }
+        }
+    }
+
+
+    return new_ptr;
+}
+
 char *libxl__sprintf(libxl__gc *gc, const char *fmt, ...)
 {
     char *s;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 29cdba4..343c11b 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -145,6 +145,7 @@ _hidden int libxl__ptr_add(libxl__gc *gc, void *ptr);
 _hidden void libxl__free_all(libxl__gc *gc);
 _hidden void *libxl__zalloc(libxl__gc *gc, int bytes);
 _hidden void *libxl__calloc(libxl__gc *gc, size_t nmemb, size_t size);
+_hidden void *libxl__realloc(libxl__gc *gc, void *ptr, size_t new_size);
 _hidden char *libxl__sprintf(libxl__gc *gc, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
 _hidden char *libxl__strdup(libxl__gc *gc, const char *c);
 _hidden char *libxl__dirname(libxl__gc *gc, const char *s);
-- 
Anthony PERARD

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

* [PATCH V9 5/7] libxl: Intruduce libxl__strndup.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
                   ` (3 preceding siblings ...)
  2011-09-29 11:37 ` [PATCH V9 4/7] libxl: Introduce libxl__realloc Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 6/7] libxl: Introduce JSON parsing stuff Anthony PERARD
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/libxl_internal.c |   10 ++++++++++
 tools/libxl/libxl_internal.h |    1 +
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index c4d54f9..0fb2315 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -159,6 +159,16 @@ char *libxl__strdup(libxl__gc *gc, const char *c)
     return s;
 }
 
+char *libxl__strndup(libxl__gc *gc, const char *c, size_t n)
+{
+    char *s = strndup(c, n);
+
+    if (s)
+        libxl__ptr_add(gc, s);
+
+    return s;
+}
+
 char *libxl__dirname(libxl__gc *gc, const char *s)
 {
     char *c;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 343c11b..6ec402e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -148,6 +148,7 @@ _hidden void *libxl__calloc(libxl__gc *gc, size_t nmemb, size_t size);
 _hidden void *libxl__realloc(libxl__gc *gc, void *ptr, size_t new_size);
 _hidden char *libxl__sprintf(libxl__gc *gc, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
 _hidden char *libxl__strdup(libxl__gc *gc, const char *c);
+_hidden char *libxl__strndup(libxl__gc *gc, const char *c, size_t n);
 _hidden char *libxl__dirname(libxl__gc *gc, const char *s);
 
 _hidden char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array, int length);
-- 
Anthony PERARD

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

* [PATCH V9 6/7] libxl: Introduce JSON parsing stuff.
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
                   ` (4 preceding siblings ...)
  2011-09-29 11:37 ` [PATCH V9 5/7] libxl: Intruduce libxl__strndup Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:37 ` [PATCH V9 7/7] libxl: Introduce a QMP client Anthony PERARD
  2011-09-29 15:38 ` [PATCH V9 0/7] " Ian Jackson
  7 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

We use the yajl parser, but we need to make a tree from the parse result
to use it outside the parser.

So this patch include json_object struct that is used to hold the JSON
data.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 README                       |    1 +
 tools/libxl/Makefile         |    5 +-
 tools/libxl/libxl_internal.h |  100 ++++++++
 tools/libxl/libxl_json.c     |  560 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 665 insertions(+), 1 deletions(-)
 create mode 100644 tools/libxl/libxl_json.c

diff --git a/README b/README
index ff154b2..c9bf699 100644
--- a/README
+++ b/README
@@ -47,6 +47,7 @@ provided by your OS distributor:
     * Development install of openssl (e.g., openssl-dev)
     * Development install of x11 (e.g. xorg-x11-dev)
     * Development install of uuid (e.g. uuid-dev)
+    * Development install of yajl (e.g. libyajl-dev)
     * bridge-utils package (/sbin/brctl)
     * iproute package (/sbin/ip)
     * hotplug or udev
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 1f6b418..e50874e 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -32,9 +32,12 @@ endif
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
+LIBXL_LIBS += -lyajl
+
 LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
-			libxl_internal.o libxl_utils.o libxl_uuid.o $(LIBXL_OBJS-y)
+			libxl_internal.o libxl_utils.o libxl_uuid.o libxl_json.o \
+			$(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 6ec402e..66f56f1 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -393,4 +393,104 @@ _hidden int libxl__e820_alloc(libxl_ctx *ctx, uint32_t domid, libxl_domain_confi
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 
+/* from libxl_json */
+#include <yajl/yajl_gen.h>
+
+_hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str);
+
+typedef enum {
+    JSON_ERROR,
+    JSON_NULL,
+    JSON_TRUE,
+    JSON_FALSE,
+    JSON_INTEGER,
+    JSON_DOUBLE,
+    JSON_STRING,
+    JSON_MAP,
+    JSON_ARRAY,
+    JSON_ANY
+} libxl__json_node_type;
+
+typedef struct libxl__json_object {
+    libxl__json_node_type type;
+    union {
+        long i;
+        double d;
+        char *string;
+        /* List of libxl__json_object */
+        flexarray_t *array;
+        /* List of libxl__json_map_node */
+        flexarray_t *map;
+    } u;
+    struct libxl__json_object *parent;
+} libxl__json_object;
+
+typedef struct {
+    char *map_key;
+    libxl__json_object *obj;
+} libxl__json_map_node;
+
+typedef struct libxl__yajl_ctx libxl__yajl_ctx;
+
+static inline bool libxl__json_object_is_string(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_STRING;
+}
+static inline bool libxl__json_object_is_integer(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_INTEGER;
+}
+static inline bool libxl__json_object_is_map(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_MAP;
+}
+static inline bool libxl__json_object_is_array(const libxl__json_object *o)
+{
+    return o != NULL && o->type == JSON_ARRAY;
+}
+
+static inline
+const char *libxl__json_object_get_string(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_string(o))
+        return o->u.string;
+    else
+        return NULL;
+}
+static inline
+flexarray_t *libxl__json_object_get_map(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_map(o))
+        return o->u.map;
+    else
+        return NULL;
+}
+static inline
+flexarray_t *libxl__json_object_get_array(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_array(o))
+        return o->u.array;
+    else
+        return NULL;
+}
+static inline long libxl__json_object_get_integer(const libxl__json_object *o)
+{
+    if (libxl__json_object_is_integer(o))
+        return o->u.i;
+    else
+        return -1;
+}
+
+_hidden libxl__json_object *libxl__json_array_get(const libxl__json_object *o,
+                                                  int i);
+_hidden
+libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
+                                               int i);
+_hidden const libxl__json_object *libxl__json_map_get(const char *key,
+                                          const libxl__json_object *o,
+                                          libxl__json_node_type expected_type);
+_hidden void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj);
+
+_hidden libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s);
+
 #endif
diff --git a/tools/libxl/libxl_json.c b/tools/libxl/libxl_json.c
new file mode 100644
index 0000000..e771925
--- /dev/null
+++ b/tools/libxl/libxl_json.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2011      Citrix Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <yajl/yajl_parse.h>
+#include <yajl/yajl_gen.h>
+
+#include "libxl_internal.h"
+
+/* #define DEBUG_ANSWER */
+
+struct libxl__yajl_ctx {
+    libxl__gc *gc;
+    yajl_handle hand;
+    libxl__json_object *head;
+    libxl__json_object *current;
+#ifdef DEBUG_ANSWER
+    yajl_gen g;
+#endif
+};
+
+#ifdef DEBUG_ANSWER
+#  define DEBUG_GEN_ALLOC(ctx) \
+    if ((ctx)->g == NULL) { \
+        yajl_gen_config conf = { 1, "  " }; \
+        (ctx)->g = yajl_gen_alloc(&conf, NULL); \
+    }
+#  define DEBUG_GEN_FREE(ctx) \
+    if ((ctx)->g) yajl_gen_free((ctx)->g)
+#  define DEBUG_GEN(ctx, type)              yajl_gen_##type(ctx->g)
+#  define DEBUG_GEN_VALUE(ctx, type, value) yajl_gen_##type(ctx->g, value)
+#  define DEBUG_GEN_STRING(ctx, str, n)     yajl_gen_string(ctx->g, str, n)
+#  define DEBUG_GEN_REPORT(yajl_ctx) \
+    do { \
+        const unsigned char *buf = NULL; \
+        unsigned int len = 0; \
+        yajl_gen_get_buf((yajl_ctx)->g, &buf, &len); \
+        LIBXL__LOG(libxl__gc_owner((yajl_ctx)->gc), \
+                   LIBXL__LOG_DEBUG, "response:\n%s", buf); \
+        yajl_gen_free((yajl_ctx)->g); \
+        (yajl_ctx)->g = NULL; \
+    } while (0)
+#else
+#  define DEBUG_GEN_ALLOC(ctx)                  ((void)0)
+#  define DEBUG_GEN_FREE(ctx)                   ((void)0)
+#  define DEBUG_GEN(ctx, type)                  ((void)0)
+#  define DEBUG_GEN_VALUE(ctx, type, value)     ((void)0)
+#  define DEBUG_GEN_STRING(ctx, value, lenght)  ((void)0)
+#  define DEBUG_GEN_REPORT(ctx)                 ((void)0)
+#endif
+
+/*
+ * YAJL Helper
+ */
+
+yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str)
+{
+    return yajl_gen_string(hand, (const unsigned char *)str, strlen(str));
+}
+
+
+/*
+ * libxl__json_object helper functions
+ */
+
+static libxl__json_object *json_object_alloc(libxl__gc *gc,
+                                             libxl__json_node_type type)
+{
+    libxl__json_object *obj;
+
+    obj = calloc(1, sizeof (libxl__json_object));
+    if (obj == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate a libxl__json_object");
+        return NULL;
+    }
+
+    obj->type = type;
+
+    if (type == JSON_MAP || type == JSON_ARRAY) {
+        flexarray_t *array = flexarray_make(1, 1);
+        if (array == NULL) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                             "Failed to allocate a flexarray");
+            free(obj);
+            return NULL;
+        }
+        if (type == JSON_MAP)
+            obj->u.map = array;
+        else
+            obj->u.array = array;
+    }
+
+    return obj;
+}
+
+static int json_object_append_to(libxl__gc *gc,
+                                 libxl__json_object *obj,
+                                 libxl__json_object *dst)
+{
+    assert(dst != NULL);
+
+    switch (dst->type) {
+    case JSON_MAP: {
+        libxl__json_map_node *last;
+
+        if (dst->u.map->count == 0) {
+            LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                       "Try to add a value to an empty map (with no key)");
+            return -1;
+        }
+        flexarray_get(dst->u.map, dst->u.map->count - 1, (void**)&last);
+        last->obj = obj;
+        break;
+    }
+    case JSON_ARRAY:
+        if (flexarray_append(dst->u.array, obj) == 2) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                             "Failed to grow a flexarray");
+            return -1;
+        }
+        break;
+    default:
+        LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                   "Try append an object is not a map/array (%i)\n",
+                   dst->type);
+        return -1;
+    }
+
+    obj->parent = dst;
+    return 0;
+}
+
+void libxl__json_object_free(libxl__gc *gc, libxl__json_object *obj)
+{
+    int index = 0;
+
+    if (obj == NULL)
+        return;
+    switch (obj->type) {
+    case JSON_STRING:
+        free(obj->u.string);
+        break;
+    case JSON_MAP: {
+        libxl__json_map_node *node = NULL;
+
+        for (index = 0; index < obj->u.map->count; index++) {
+            if (flexarray_get(obj->u.map, index, (void**)&node) != 0)
+                break;
+            libxl__json_object_free(gc, node->obj);
+            free(node->map_key);
+            free(node);
+            node = NULL;
+        }
+        flexarray_free(obj->u.map);
+        break;
+    }
+    case JSON_ARRAY: {
+        libxl__json_object *node = NULL;
+        break;
+
+        for (index = 0; index < obj->u.array->count; index++) {
+            if (flexarray_get(obj->u.array, index, (void**)&node) != 0)
+                break;
+            libxl__json_object_free(gc, node);
+            node = NULL;
+        }
+        flexarray_free(obj->u.array);
+        break;
+    }
+    default:
+        break;
+    }
+    free(obj);
+}
+
+libxl__json_object *libxl__json_array_get(const libxl__json_object *o, int i)
+{
+    flexarray_t *array = NULL;
+    libxl__json_object *obj = NULL;
+
+    if ((array = libxl__json_object_get_array(o)) == NULL) {
+        return NULL;
+    }
+
+    if (i >= array->count)
+        return NULL;
+
+    if (flexarray_get(array, i, (void**)&obj) != 0)
+        return NULL;
+
+    return obj;
+}
+
+libxl__json_map_node *libxl__json_map_node_get(const libxl__json_object *o,
+                                               int i)
+{
+    flexarray_t *array = NULL;
+    libxl__json_map_node *obj = NULL;
+
+    if ((array = libxl__json_object_get_map(o)) == NULL) {
+        return NULL;
+    }
+
+    if (i >= array->count)
+        return NULL;
+
+    if (flexarray_get(array, i, (void**)&obj) != 0)
+        return NULL;
+
+    return obj;
+}
+
+const libxl__json_object *libxl__json_map_get(const char *key,
+                                          const libxl__json_object *o,
+                                          libxl__json_node_type expected_type)
+{
+    flexarray_t *maps = NULL;
+    int index = 0;
+
+    if (libxl__json_object_is_map(o)) {
+        libxl__json_map_node *node = NULL;
+
+        maps = o->u.map;
+        for (index = 0; index < maps->count; index++) {
+            if (flexarray_get(maps, index, (void**)&node) != 0)
+                return NULL;
+            if (strcmp(key, node->map_key) == 0) {
+                if (expected_type == JSON_ANY
+                    || (node->obj && node->obj->type == expected_type)) {
+                    return node->obj;
+                } else {
+                    return NULL;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+
+/*
+ * JSON callbacks
+ */
+
+static int json_callback_null(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN(ctx, null);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_NULL)) == NULL)
+        return 0;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_boolean(void *opaque, int boolean)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, bool, boolean);
+
+    if ((obj = json_object_alloc(ctx->gc,
+                                 boolean ? JSON_TRUE : JSON_FALSE)) == NULL)
+        return 0;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_integer(void *opaque, long value)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, integer, value);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_INTEGER)) == NULL)
+        return 0;
+    obj->u.i = value;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_double(void *opaque, double value)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj;
+
+    DEBUG_GEN_VALUE(ctx, double, value);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_DOUBLE)) == NULL)
+        return 0;
+    obj->u.d = value;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_string(void *opaque, const unsigned char *str,
+                                unsigned int len)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    char *t = NULL;
+    libxl__json_object *obj = NULL;
+
+    t = malloc(len + 1);
+    if (t == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate");
+        return 0;
+    }
+
+    DEBUG_GEN_STRING(ctx, str, len);
+
+    strncpy(t, (const char *) str, len);
+    t[len] = 0;
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_STRING)) == NULL) {
+        free(t);
+        return 0;
+    }
+    obj->u.string = t;
+
+    if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+        libxl__json_object_free(ctx->gc, obj);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_map_key(void *opaque, const unsigned char *str,
+                                 unsigned int len)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    char *t = NULL;
+    libxl__json_object *obj = ctx->current;
+
+    t = malloc(len + 1);
+    if (t == NULL) {
+        LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                         "Failed to allocate");
+        return 0;
+    }
+
+    DEBUG_GEN_STRING(ctx, str, len);
+
+    strncpy(t, (const char *) str, len);
+    t[len] = 0;
+
+    if (libxl__json_object_is_map(obj)) {
+        libxl__json_map_node *node = malloc(sizeof (libxl__json_map_node));
+        if (node == NULL) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                             "Failed to allocate");
+            return 0;
+        }
+
+        node->map_key = t;
+        node->obj = NULL;
+
+        if (flexarray_append(obj->u.map, node) == 2) {
+            LIBXL__LOG_ERRNO(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                             "Failed to grow a flexarray");
+            return 0;
+        }
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "Current json object is not a map");
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_start_map(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj = NULL;
+
+    DEBUG_GEN(ctx, map_open);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_MAP)) == NULL)
+        return 0;
+
+    if (ctx->current) {
+        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+            libxl__json_object_free(ctx->gc, obj);
+            return 0;
+        }
+    }
+
+    ctx->current = obj;
+    if (ctx->head == NULL) {
+        ctx->head = obj;
+    }
+
+    return 1;
+}
+
+static int json_callback_end_map(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+
+    DEBUG_GEN(ctx, map_close);
+
+    if (ctx->current) {
+        ctx->current = ctx->current->parent;
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "No current libxl__json_object, cannot use his parent.");
+        return 0;
+    }
+
+    return 1;
+}
+
+static int json_callback_start_array(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+    libxl__json_object *obj = NULL;
+
+    DEBUG_GEN(ctx, array_open);
+
+    if ((obj = json_object_alloc(ctx->gc, JSON_ARRAY)) == NULL)
+        return 0;
+
+    if (ctx->current) {
+        if (json_object_append_to(ctx->gc, obj, ctx->current) == -1) {
+            libxl__json_object_free(ctx->gc, obj);
+            return 0;
+        }
+    }
+
+    ctx->current = obj;
+    if (ctx->head == NULL) {
+        ctx->head = obj;
+    }
+
+    return 1;
+}
+
+static int json_callback_end_array(void *opaque)
+{
+    libxl__yajl_ctx *ctx = opaque;
+
+    DEBUG_GEN(ctx, array_close);
+
+    if (ctx->current) {
+        ctx->current = ctx->current->parent;
+    } else {
+        LIBXL__LOG(libxl__gc_owner(ctx->gc), LIBXL__LOG_ERROR,
+                   "No current libxl__json_object, cannot use his parent.");
+        return 0;
+    }
+
+    return 1;
+}
+
+static yajl_callbacks callbacks = {
+    json_callback_null,
+    json_callback_boolean,
+    json_callback_integer,
+    json_callback_double,
+    NULL,
+    json_callback_string,
+    json_callback_start_map,
+    json_callback_map_key,
+    json_callback_end_map,
+    json_callback_start_array,
+    json_callback_end_array
+};
+
+static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx)
+{
+    if (yajl_ctx->hand) {
+        yajl_free(yajl_ctx->hand);
+        yajl_ctx->hand = NULL;
+    }
+    DEBUG_GEN_FREE(yajl_ctx);
+}
+
+libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s)
+{
+    yajl_status status;
+    libxl__yajl_ctx yajl_ctx;
+
+    memset(&yajl_ctx, 0, sizeof (yajl_ctx));
+    yajl_ctx.gc = gc;
+
+    DEBUG_GEN_ALLOC(&yajl_ctx);
+
+    if (yajl_ctx.hand == NULL) {
+        yajl_parser_config cfg = {
+            .allowComments = 1,
+            .checkUTF8 = 1,
+        };
+        yajl_ctx.hand = yajl_alloc(&callbacks, &cfg, NULL, &yajl_ctx);
+    }
+    status = yajl_parse(yajl_ctx.hand, (const unsigned char *)s, strlen(s));
+    status = yajl_parse_complete(yajl_ctx.hand);
+
+    if (status == yajl_status_ok) {
+        libxl__json_object *o = yajl_ctx.head;
+
+        DEBUG_GEN_REPORT(&yajl_ctx);
+
+        yajl_ctx.head = NULL;
+
+        yajl_ctx_free(&yajl_ctx);
+        return o;
+    } else {
+        unsigned char *str = yajl_get_error(yajl_ctx.hand, 1,
+                                            (const unsigned char *)s,
+                                            strlen(s));
+
+        LIBXL__LOG(libxl__gc_owner(gc), LIBXL__LOG_ERROR,
+                   "yajl error: %s", str);
+        yajl_free_error(yajl_ctx.hand, str);
+
+        libxl__json_object_free(gc, yajl_ctx.head);
+        yajl_ctx_free(&yajl_ctx);
+        return NULL;
+    }
+}
-- 
Anthony PERARD

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

* [PATCH V9 7/7] libxl: Introduce a QMP client
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
                   ` (5 preceding siblings ...)
  2011-09-29 11:37 ` [PATCH V9 6/7] libxl: Introduce JSON parsing stuff Anthony PERARD
@ 2011-09-29 11:37 ` Anthony PERARD
  2011-09-29 11:54   ` Ian Campbell
  2011-09-29 15:38 ` [PATCH V9 0/7] " Ian Jackson
  7 siblings, 1 reply; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 11:37 UTC (permalink / raw)
  To: Xen Devel; +Cc: Ian Campbell, Anthony PERARD, Stefano Stabellini

QMP stands for QEMU Monitor Protocol and it is used to query information
from QEMU or to control QEMU.

This implementation will ask QEMU the list of chardevice and store the
path to serial ports in xenstored. So we will be able to use xl console
with QEMU upstream.

In order to connect to the QMP server, a socket file is created in
/var/run/xen/qmp-libxl-$(domid).

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 tools/libxl/Makefile         |    2 +-
 tools/libxl/libxl.c          |    2 +
 tools/libxl/libxl_create.c   |    4 +
 tools/libxl/libxl_dm.c       |   10 +
 tools/libxl/libxl_internal.h |   19 ++
 tools/libxl/libxl_qmp.c      |  595 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 631 insertions(+), 1 deletions(-)
 create mode 100644 tools/libxl/libxl_qmp.c

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index e50874e..f10c7e8 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -37,7 +37,7 @@ LIBXL_LIBS += -lyajl
 LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
 			libxl_internal.o libxl_utils.o libxl_uuid.o libxl_json.o \
-			$(LIBXL_OBJS-y)
+			libxl_qmp.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
 
 $(LIBXL_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore) $(CFLAGS_libblktapctl)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index ce76cff..0855f59 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -762,6 +762,8 @@ int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force)
     if (dm_present) {
         if (libxl__destroy_device_model(&gc, domid) < 0)
             LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl__destroy_device_model failed for %d", domid);
+
+        libxl__qmp_cleanup(&gc, domid);
     }
     if (libxl__devices_destroy(&gc, domid, force) < 0)
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "libxl_destroy_devices failed for %d", domid);
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index ce76729..c97819a 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -573,6 +573,10 @@ static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
     }
 
     if (dm_starting) {
+        if (dm_info->device_model_version
+            == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
+            libxl__qmp_initializations(ctx, domid);
+        }
         ret = libxl__confirm_device_model_startup(gc, dm_starting);
         if (ret < 0) {
             LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index c575460..7e0616a 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -248,6 +248,16 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
     flexarray_vappend(dm_args, dm,
                       "-xen-domid", libxl__sprintf(gc, "%d", info->domid), NULL);
 
+    flexarray_append(dm_args, "-chardev");
+    flexarray_append(dm_args,
+                     libxl__sprintf(gc, "socket,id=libxl-cmd,"
+                                    "path=%s/qmp-libxl-%d,server,nowait",
+                                    libxl_run_dir_path(),
+                                    info->domid));
+
+    flexarray_append(dm_args, "-mon");
+    flexarray_append(dm_args, "chardev=libxl-cmd,mode=control");
+
     if (info->type == LIBXL_DOMAIN_TYPE_PV) {
         flexarray_append(dm_args, "-xen-attach");
     }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 66f56f1..cef2036 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -393,6 +393,25 @@ _hidden int libxl__e820_alloc(libxl_ctx *ctx, uint32_t domid, libxl_domain_confi
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
 
+/* from libxl_qmp */
+typedef struct libxl__qmp_handler libxl__qmp_handler;
+
+/* Initialise and connect to the QMP socket.
+ *   Return an handler or NULL if there is an error
+ */
+_hidden libxl__qmp_handler *libxl__qmp_initialize(libxl_ctx *ctx,
+                                                  uint32_t domid);
+/* ask to QEMU the serial port information and store it in xenstore. */
+_hidden int libxl__qmp_query_serial(libxl__qmp_handler *qmp);
+/* close and free the QMP handler */
+_hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
+/* remove the socket file, if the file has already been removed,
+ * nothing happen */
+_hidden void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid);
+
+/* this helper calls qmp_initialize, query_serial and qmp_close */
+_hidden int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid);
+
 /* from libxl_json */
 #include <yajl/yajl_gen.h>
 
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
new file mode 100644
index 0000000..8cda29d
--- /dev/null
+++ b/tools/libxl/libxl_qmp.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2011      Citrix Ltd.
+ * Author Anthony PERARD <anthony.perard@citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+/*
+ * This file implement a client for QMP (QEMU Monitor Protocol). For the
+ * Specification, see in the QEMU repository.
+ */
+
+#include <unistd.h>
+#include <sys/un.h>
+#include <sys/queue.h>
+#include <fcntl.h>
+
+#include <yajl/yajl_gen.h>
+
+#include "libxl_internal.h"
+
+/* #define DEBUG_RECEIVED */
+
+#ifdef DEBUG_RECEIVED
+#  define DEBUG_REPORT_RECEIVED(buf, len) \
+    LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "received: '%.*s'", len, buf)
+#else
+#  define DEBUG_REPORT_RECEIVED(buf, len) ((void)0)
+#endif
+
+/*
+ * QMP types & constant
+ */
+
+#define QMP_RECEIVE_BUFFER_SIZE 4096
+
+typedef int (*qmp_callback_t)(libxl__qmp_handler *qmp,
+                              const libxl__json_object *tree);
+
+typedef struct callback_id_pair {
+    int id;
+    qmp_callback_t callback;
+    SIMPLEQ_ENTRY(callback_id_pair) next;
+} callback_id_pair;
+
+struct libxl__qmp_handler {
+    struct sockaddr_un addr;
+    int qmp_fd;
+    bool connected;
+    time_t timeout;
+    /* wait_for_id will be used by the synchronous send function */
+    int wait_for_id;
+
+    char buffer[QMP_RECEIVE_BUFFER_SIZE];
+    libxl__yajl_ctx *yajl_ctx;
+
+    libxl_ctx *ctx;
+    uint32_t domid;
+
+    int last_id_used;
+    SIMPLEQ_HEAD(callback_list, callback_id_pair) callback_list;
+};
+
+static int qmp_send(libxl__qmp_handler *qmp,
+                    const char *cmd, qmp_callback_t callback);
+
+static const int QMP_SOCKET_CONNECT_TIMEOUT = 5;
+
+/*
+ * QMP callbacks functions
+ */
+
+static int store_serial_port_info(libxl__qmp_handler *qmp,
+                                  const char *chardev,
+                                  int port)
+{
+    libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+    char *path = NULL;
+    int ret = 0;
+
+    if (!(chardev && strncmp("pty:", chardev, 4) == 0)) {
+        return -1;
+    }
+
+    path = libxl__xs_get_dompath(&gc, qmp->domid);
+    path = libxl__sprintf(&gc, "%s/serial/%d/tty", path, port);
+
+    ret = libxl__xs_write(&gc, XBT_NULL, path, "%s", chardev + 4);
+
+    libxl__free_all(&gc);
+    return ret;
+}
+
+static int register_serials_chardev_callback(libxl__qmp_handler *qmp,
+                                             const libxl__json_object *o)
+{
+    const libxl__json_object *obj = NULL;
+    const libxl__json_object *label = NULL;
+    const char *s = NULL;
+    int i = 0;
+    const char *chardev = NULL;
+    int ret = 0;
+
+    for (i = 0; (obj = libxl__json_array_get(o, i)); i++) {
+        if (!libxl__json_object_is_map(obj))
+            continue;
+        label = libxl__json_map_get("label", obj, JSON_STRING);
+        s = libxl__json_object_get_string(label);
+
+        if (s && strncmp("serial", s, strlen("serial")) == 0) {
+            const libxl__json_object *filename = NULL;
+            char *endptr = NULL;
+            int port_number;
+
+            filename = libxl__json_map_get("filename", obj, JSON_STRING);
+            chardev = libxl__json_object_get_string(filename);
+
+            s += strlen("serial");
+            port_number = strtol(s, &endptr, 10);
+            if (*s == 0 || *endptr != 0) {
+                LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
+                           "Invalid serial port number: %s", s);
+                return -1;
+            }
+            ret = store_serial_port_info(qmp, chardev, port_number);
+            if (ret) {
+                LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
+                                 "Failed to store serial port information"
+                                 " in xenstore");
+                return ret;
+            }
+        }
+    };
+
+    return ret;
+}
+
+static int qmp_capabilities_callback(libxl__qmp_handler *qmp,
+                                     const libxl__json_object *o)
+{
+    qmp->connected = true;
+
+    return 0;
+}
+
+/*
+ * QMP commands
+ */
+
+static int enable_qmp_capabilities(libxl__qmp_handler *qmp)
+{
+    return qmp_send(qmp, "qmp_capabilities", qmp_capabilities_callback);
+}
+
+/*
+ * Helpers
+ */
+
+static libxl__qmp_message_type qmp_response_type(libxl__qmp_handler *qmp,
+                                                 const libxl__json_object *o)
+{
+    libxl__qmp_message_type type;
+    libxl__json_map_node *node = NULL;
+    int i = 0;
+
+    for (i = 0; (node = libxl__json_map_node_get(o, i)); i++) {
+        if (libxl__qmp_message_type_from_string(node->map_key, &type) == 0)
+            return type;
+    }
+
+    return LIBXL__QMP_MESSAGE_TYPE_INVALID;
+}
+
+static callback_id_pair *qmp_get_callback_from_id(libxl__qmp_handler *qmp,
+                                                  const libxl__json_object *o)
+{
+    const libxl__json_object *id_object = libxl__json_map_get("id", o,
+                                                              JSON_INTEGER);
+    int id = -1;
+    callback_id_pair *pp = NULL;
+
+    if (id_object) {
+        id = libxl__json_object_get_integer(id_object);
+
+        SIMPLEQ_FOREACH(pp, &qmp->callback_list, next) {
+            if (pp->id == id) {
+                return pp;
+            }
+        }
+    }
+    return NULL;
+}
+
+static void qmp_handle_error_response(libxl__qmp_handler *qmp,
+                                      const libxl__json_object *resp)
+{
+    callback_id_pair *pp = qmp_get_callback_from_id(qmp, resp);
+
+    resp = libxl__json_map_get("error", resp, JSON_MAP);
+    resp = libxl__json_map_get("desc", resp, JSON_STRING);
+
+    if (pp) {
+        pp->callback(qmp, NULL);
+        if (pp->id == qmp->wait_for_id) {
+            /* tell that the id have been processed */
+            qmp->wait_for_id = 0;
+        }
+        SIMPLEQ_REMOVE(&qmp->callback_list, pp, callback_id_pair, next);
+        free(pp);
+    }
+
+    LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
+               "received an error message from QMP server: %s",
+               libxl__json_object_get_string(resp));
+}
+
+static int qmp_handle_response(libxl__qmp_handler *qmp,
+                               const libxl__json_object *resp)
+{
+    libxl__qmp_message_type type = LIBXL__QMP_MESSAGE_TYPE_INVALID;
+
+    type = qmp_response_type(qmp, resp);
+    LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG,
+               "message type: %s", libxl__qmp_message_type_to_string(type));
+
+    switch (type) {
+    case LIBXL__QMP_MESSAGE_TYPE_QMP:
+        /* On the greeting message from the server, enable QMP capabilities */
+        enable_qmp_capabilities(qmp);
+        break;
+    case LIBXL__QMP_MESSAGE_TYPE_RETURN: {
+        callback_id_pair *pp = qmp_get_callback_from_id(qmp, resp);
+
+        if (pp) {
+            pp->callback(qmp,
+                         libxl__json_map_get("return", resp, JSON_ANY));
+            if (pp->id == qmp->wait_for_id) {
+                /* tell that the id have been processed */
+                qmp->wait_for_id = 0;
+            }
+            SIMPLEQ_REMOVE(&qmp->callback_list, pp, callback_id_pair, next);
+            free(pp);
+        }
+        break;
+    }
+    case LIBXL__QMP_MESSAGE_TYPE_ERROR:
+        qmp_handle_error_response(qmp, resp);
+        break;
+    case LIBXL__QMP_MESSAGE_TYPE_EVENT:
+        break;
+    case LIBXL__QMP_MESSAGE_TYPE_INVALID:
+        return -1;
+    }
+    return 0;
+}
+
+/*
+ * Handler functions
+ */
+
+static libxl__qmp_handler *qmp_init_handler(libxl_ctx *ctx, uint32_t domid)
+{
+    libxl__qmp_handler *qmp = NULL;
+
+    qmp = calloc(1, sizeof (libxl__qmp_handler));
+    if (qmp == NULL) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                         "Failed to allocate qmp_handler");
+        return NULL;
+    }
+    qmp->ctx = ctx;
+    qmp->domid = domid;
+    qmp->timeout = 5;
+
+    SIMPLEQ_INIT(&qmp->callback_list);
+
+    return qmp;
+}
+
+static int qmp_open(libxl__qmp_handler *qmp, const char *qmp_socket_path,
+                    int timeout)
+{
+    int ret;
+    int flags = 0;
+    int i = 0;
+
+    qmp->qmp_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (qmp->qmp_fd < 0) {
+        return -1;
+    }
+    if ((flags = fcntl(qmp->qmp_fd, F_GETFL)) == 1) {
+        flags = 0;
+    }
+    if (fcntl(qmp->qmp_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+        return -1;
+    }
+
+    memset(&qmp->addr, 0, sizeof (&qmp->addr));
+    qmp->addr.sun_family = AF_UNIX;
+    strncpy(qmp->addr.sun_path, qmp_socket_path,
+            sizeof (qmp->addr.sun_path));
+
+    do {
+        ret = connect(qmp->qmp_fd, (struct sockaddr *) &qmp->addr,
+                      sizeof (qmp->addr));
+        if (ret == 0)
+            break;
+        if (errno == ENOENT || errno == ECONNREFUSED) {
+            /* ENOENT       : Socket may not have shown up yet
+             * ECONNREFUSED : Leftover socket hasn't been removed yet */
+            continue;
+        }
+        return -1;
+    } while ((++i / 5 <= timeout) && (usleep(200 * 1000) <= 0));
+
+    return ret;
+}
+
+static void qmp_close(libxl__qmp_handler *qmp)
+{
+    callback_id_pair *pp = NULL;
+    callback_id_pair *tmp = NULL;
+
+    close(qmp->qmp_fd);
+    SIMPLEQ_FOREACH(pp, &qmp->callback_list, next) {
+        if (tmp)
+            free(tmp);
+        tmp = pp;
+    }
+    if (tmp)
+        free(tmp);
+}
+
+static int qmp_next(libxl__gc *gc, libxl__qmp_handler *qmp)
+{
+    ssize_t rd;
+    char *s = NULL;
+    char *s_end = NULL;
+
+    char *incomplete = NULL;
+    size_t incomplete_size = 0;
+
+    do {
+        fd_set rfds;
+        int ret = 0;
+        struct timeval timeout = {
+            .tv_sec = qmp->timeout,
+            .tv_usec = 0,
+        };
+
+        FD_ZERO(&rfds);
+        FD_SET(qmp->qmp_fd, &rfds);
+
+        ret = select(qmp->qmp_fd + 1, &rfds, NULL, NULL, &timeout);
+        if (ret == 0) {
+            LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR, "timeout");
+            return -1;
+        } else if (ret < 0) {
+            LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR, "Select error");
+            return -1;
+        }
+
+        rd = read(qmp->qmp_fd, qmp->buffer, QMP_RECEIVE_BUFFER_SIZE);
+        if (rd == 0) {
+            continue;
+        } else if (rd < 0) {
+            LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR, "Socket read error");
+            return rd;
+        }
+
+        DEBUG_REPORT_RECEIVED(qmp->buffer, rd);
+
+        do {
+            char *end = NULL;
+            if (incomplete) {
+                size_t current_pos = s - incomplete;
+                incomplete_size += rd;
+                incomplete = libxl__realloc(gc, incomplete,
+                                            incomplete_size + 1);
+                incomplete = strncat(incomplete, qmp->buffer, rd);
+                s = incomplete + current_pos;
+                s_end = incomplete + incomplete_size;
+            } else {
+                incomplete = libxl__strndup(gc, qmp->buffer, rd);
+                incomplete_size = rd;
+                s = incomplete;
+                s_end = s + rd;
+            }
+
+            end = strstr(s, "\r\n");
+            if (end) {
+                libxl__json_object *o = NULL;
+
+                *end = '\0';
+
+                o = libxl__json_parse(gc, s);
+                s = end + 2;
+
+                if (o) {
+                    qmp_handle_response(qmp, o);
+                    libxl__json_object_free(gc, o);
+                } else {
+                    LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
+                               "Parse error of : %s\n", s);
+                    return -1;
+                }
+            } else {
+                break;
+            }
+        } while (s < s_end);
+   } while (s < s_end);
+
+    return 1;
+}
+
+static int qmp_send(libxl__qmp_handler *qmp,
+                    const char *cmd, qmp_callback_t callback)
+{
+    yajl_gen_config conf = { 0, NULL };
+    const unsigned char *buf;
+    unsigned int len = 0;
+    yajl_gen_status s;
+    yajl_gen hand;
+
+    hand = yajl_gen_alloc(&conf, NULL);
+    if (!hand) {
+        return -1;
+    }
+
+    yajl_gen_map_open(hand);
+    libxl__yajl_gen_asciiz(hand, "execute");
+    libxl__yajl_gen_asciiz(hand, cmd);
+    libxl__yajl_gen_asciiz(hand, "id");
+    yajl_gen_integer(hand, ++qmp->last_id_used);
+    yajl_gen_map_close(hand);
+
+    s = yajl_gen_get_buf(hand, &buf, &len);
+
+    if (s) {
+        LIBXL__LOG(qmp->ctx, LIBXL__LOG_ERROR,
+                   "Failed to generate a qmp command");
+        return -1;
+    }
+
+    if (callback) {
+        callback_id_pair *elm = malloc(sizeof (callback_id_pair));
+        if (elm == NULL) {
+            LIBXL__LOG_ERRNO(qmp->ctx, LIBXL__LOG_ERROR,
+                             "Failed to allocate a QMP callback");
+            yajl_gen_free(hand);
+            return -1;
+        }
+        elm->id = qmp->last_id_used;
+        elm->callback = callback;
+        SIMPLEQ_INSERT_TAIL(&qmp->callback_list, elm, next);
+    }
+
+    LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "next qmp command: '%s'", buf);
+
+    if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, buf, len,
+                            "QMP command", "QMP socket"))
+        goto error;
+    if (libxl_write_exactly(qmp->ctx, qmp->qmp_fd, "\r\n", 2,
+                            "CRLF", "QMP socket"))
+        goto error;
+
+    yajl_gen_free(hand);
+
+    return qmp->last_id_used;
+
+error:
+    yajl_gen_free(hand);
+    return -1;
+}
+
+static int qmp_synchronous_send(libxl__qmp_handler *qmp, const char *cmd,
+                                qmp_callback_t callback, int ask_timeout)
+{
+    int id = 0;
+    int ret = 0;
+    libxl__gc gc = LIBXL_INIT_GC(qmp->ctx);
+
+    id = qmp_send(qmp, cmd, callback);
+    if (id <= 0) {
+        return -1;
+    }
+    qmp->wait_for_id = id;
+
+    while (qmp->wait_for_id == id) {
+        if ((ret = qmp_next(&gc, qmp)) < 0) {
+            return ret;
+        }
+    }
+
+    libxl__free_all(&gc);
+
+    return 0;
+}
+
+static void qmp_free_handler(libxl__qmp_handler *qmp)
+{
+    free(qmp);
+}
+
+/*
+ * API
+ */
+
+libxl__qmp_handler *libxl__qmp_initialize(libxl_ctx *ctx, uint32_t domid)
+{
+    int ret = 0;
+    libxl__qmp_handler *qmp = NULL;
+    char *qmp_socket;
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+
+    qmp = qmp_init_handler(ctx, domid);
+
+    qmp_socket = libxl__sprintf(&gc, "%s/qmp-libxl-%d",
+                                libxl_run_dir_path(), domid);
+    if ((ret = qmp_open(qmp, qmp_socket, QMP_SOCKET_CONNECT_TIMEOUT)) < 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Connection error");
+        libxl__free_all(&gc);
+        qmp_free_handler(qmp);
+        return NULL;
+    }
+
+    LIBXL__LOG(qmp->ctx, LIBXL__LOG_DEBUG, "connected to %s", qmp_socket);
+
+    /* Wait for the response to qmp_capabilities */
+    while (!qmp->connected) {
+        if ((ret = qmp_next(&gc, qmp)) < 0) {
+            break;
+        }
+    }
+
+    libxl__free_all(&gc);
+    if (!qmp->connected) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Failed to connect to QMP");
+        libxl__qmp_close(qmp);
+        return NULL;
+    }
+    return qmp;
+}
+
+void libxl__qmp_close(libxl__qmp_handler *qmp)
+{
+    if (!qmp)
+        return;
+    qmp_close(qmp);
+    qmp_free_handler(qmp);
+}
+
+void libxl__qmp_cleanup(libxl__gc *gc, uint32_t domid)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *qmp_socket;
+
+    qmp_socket = libxl__sprintf(gc, "%s/qmp-libxl-%d",
+                                libxl_run_dir_path(), domid);
+    if (unlink(qmp_socket) == -1) {
+        if (errno != ENOENT) {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                             "Failed to remove QMP socket file %s",
+                             qmp_socket);
+        }
+    }
+}
+
+int libxl__qmp_query_serial(libxl__qmp_handler *qmp)
+{
+    return qmp_synchronous_send(qmp, "query-chardev",
+                                register_serials_chardev_callback,
+                                qmp->timeout);
+}
+
+int libxl__qmp_initializations(libxl_ctx *ctx, uint32_t domid)
+{
+    libxl__qmp_handler *qmp = NULL;
+    int ret = 0;
+
+    qmp = libxl__qmp_initialize(ctx, domid);
+    if (!qmp)
+        return -1;
+    ret = libxl__qmp_query_serial(qmp);
+    libxl__qmp_close(qmp);
+    return ret;
+}
-- 
Anthony PERARD

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

* Re: [PATCH V9 7/7] libxl: Introduce a QMP client
  2011-09-29 11:37 ` [PATCH V9 7/7] libxl: Introduce a QMP client Anthony PERARD
@ 2011-09-29 11:54   ` Ian Campbell
  2011-09-29 12:43     ` Anthony PERARD
  0 siblings, 1 reply; 11+ messages in thread
From: Ian Campbell @ 2011-09-29 11:54 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: Xen Devel, Stefano Stabellini

On Thu, 2011-09-29 at 12:37 +0100, Anthony PERARD wrote:
> 
> +    qmp->qmp_fd = socket(AF_UNIX, SOCK_STREAM, 0);
> +    if (qmp->qmp_fd < 0) {
> +        return -1;
> +    } 

Is SOCK_CLOEXEC standard enough to use? Probably not.

We should use FD_CLOEXEC though.

Ian.

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

* Re: Re: [PATCH V9 7/7] libxl: Introduce a QMP client
  2011-09-29 11:54   ` Ian Campbell
@ 2011-09-29 12:43     ` Anthony PERARD
  0 siblings, 0 replies; 11+ messages in thread
From: Anthony PERARD @ 2011-09-29 12:43 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Xen Devel, Stefano Stabellini

On Thu, Sep 29, 2011 at 12:54, Ian Campbell <Ian.Campbell@eu.citrix.com> wrote:
> On Thu, 2011-09-29 at 12:37 +0100, Anthony PERARD wrote:
>>
>> +    qmp->qmp_fd = socket(AF_UNIX, SOCK_STREAM, 0);
>> +    if (qmp->qmp_fd < 0) {
>> +        return -1;
>> +    }
>
> Is SOCK_CLOEXEC standard enough to use? Probably not.
>
> We should use FD_CLOEXEC though.

Ok, I will send a separate patch for this.

-- 
Anthony PERARD

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

* Re: [PATCH V9 0/7] Introduce a QMP client
  2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
                   ` (6 preceding siblings ...)
  2011-09-29 11:37 ` [PATCH V9 7/7] libxl: Introduce a QMP client Anthony PERARD
@ 2011-09-29 15:38 ` Ian Jackson
  7 siblings, 0 replies; 11+ messages in thread
From: Ian Jackson @ 2011-09-29 15:38 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: Ian Campbell, Xen Devel, Stefano Stabellini

Anthony PERARD writes ("[Xen-devel] [PATCH V9 0/7] Introduce a QMP client"):
> Only the last patch have changed on this series since the v8.
> Replace of SOCK_NONBLOCK by a call to fcntl in qmp_open().
> The rest of the patch have been acked-by Ian Campbell.

Thanks, I have applied this whole series.

Ian.

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

end of thread, other threads:[~2011-09-29 15:38 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-29 11:37 [PATCH V9 0/7] Introduce a QMP client Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 1/7] libxl: Rename libxl.idl to libxl_types.idl Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 2/7] libxl: Add get/set_default_namespace in libxltypes.py Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 3/7] libxl: Introduce libxl_internal_types.idl Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 4/7] libxl: Introduce libxl__realloc Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 5/7] libxl: Intruduce libxl__strndup Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 6/7] libxl: Introduce JSON parsing stuff Anthony PERARD
2011-09-29 11:37 ` [PATCH V9 7/7] libxl: Introduce a QMP client Anthony PERARD
2011-09-29 11:54   ` Ian Campbell
2011-09-29 12:43     ` Anthony PERARD
2011-09-29 15:38 ` [PATCH V9 0/7] " Ian Jackson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.