libxl: support json for pretty printing objects
PATCH v2 1/1 libxl: support json for pretty printing objects
Now that Anthony's QMP series is in we can build upon the use of YAJL to add support for pretty printing libxl objects as JSON.
Also includes a user in xl (to print disks on dry run) and an associated fix to the check-xl-disk-parse test script.
This is the second posting. A subset of the patches have been applied so I have rebased. I have also addressed most of Ian J's review comments on "libxl: IDL: autogenerate functions to produce JSON from libxl data structures":
- wrap python code to 80 columns
- fixup quoting (although I had to add another case in \"%s=%#x\" because "%s=%#x" was confusing emacs' syntax highlighting due to the # being treated as a comment and hiding the closing ".
- remove leftover cruft
- added libxl__yagl_gen_enum helper
- autogenerate *_gen_json prototypes for builtins instead of handcoding them.
I didn't address the cpuid related comments.
I switched to using "xl" not "/usr/sbin/xl" in that patch.
PATCH v2 1/1 libxl: IDL: autogenerate functions to produce JSON from libxl data structures
# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1317981945 -3600
# Node ID 75a0a29cccbfce75ba3087cdaf53adfd1b377a11
# Parent 43b99763284fa639e47dbeb9245f0ebd1d4f2dad
libxl: IDL: autogenerate functions to produce JSON from libxl data structures.
Two functions are provided. TYPE_gen_json exposes an interface which is compatible with the YAGL generator infrastructure. TYPE_to_string uses this to produce a pretty printed string.
The TYPE_gen_json functions are defined in a new header libxl_json.h which is not exposed via libxl.h due to the use of YAGL datatypes to avoid poluting the namespace us libxl users which don't use the library themselves. If a libxl user is interested in integrating at the YAGL level then it should #include this file itself.
Also update testidl to generate a random version of each IDL datastructure and convert it to JSON. Unfortunately this requires a libxl_ctx and therefore the test must be run on a Xen system now.
tools/libxl/Makefile +6 -3
@@ -84,14 +84,17 @@ _libxl_paths.h: genpath libxl_paths.c: _libxl_paths.h libxl.h: _libxl_types.h +libxl_json.h: _libxl_types_json.h libxl_internal.h: _libxl_types_internal.h +libxl_internal_json.h: _libxl_types_internal_json.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 +_libxl_type%.h _libxl_type%_json.h _libxl_type%.c: libxl_type%.idl gentypes.py libxltypes.py + $(PYTHON) gentypes.py libxl_type$*.idl __libxl_type$*.h __libxl_type$*_json.h __libxl_type$*.c $(call move-if-changed,__libxl_type$*.h,_libxl_type$*.h) + $(call move-if-changed,__libxl_type$*_json.h,_libxl_type$*_json.h) $(call move-if-changed,__libxl_type$*.c,_libxl_type$*.c) libxenlight.so: libxenlight.so.$(MAJOR)
@@ -140,7 +143,7 @@ install: all ln -sf libxlutil.so.$(XLUMAJOR).$(XLUMINOR) $(DESTDIR)$(LIBDIR)/libxlutil.so.$(XLUMAJOR) ln -sf libxlutil.so.$(XLUMAJOR) $(DESTDIR)$(LIBDIR)/libxlutil.so $(INSTALL_DATA) libxlutil.a $(DESTDIR)$(LIBDIR) - $(INSTALL_DATA) libxl.h _libxl_types.h libxl_utils.h libxl_uuid.h $(DESTDIR)$(INCLUDEDIR) + $(INSTALL_DATA) libxl.h libxl_json.h _libxl_types.h _libxl_types_json.h libxl_utils.h libxl_uuid.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) bash-completion $(DESTDIR)$(BASH_COMPLETION_DIR)/xl.sh .PHONY: clean
tools/libxl/gentest.py +245 -8
294 lines not on this page · raw message
tools/libxl/gentypes.py +96 -6
146 lines not on this page · raw message
tools/libxl/idl.txt +9 -0
@@ -49,6 +49,15 @@ Type.autogenerate_destructor: (default: Indicates if the above named Type.destructor_fn should be autogenerated. +Type.json_fn: (default: typename + "_gen_json" or None if type == None) + + The name of the C function which will generate a YAJL data structure + representing this type. + +Type.autogenerate_json: (default: True) + + Indicates if the above named Type.json_fn should be autogenerated. + Other simple type-Classes -------------------------
tools/libxl/libxl.h +2 -2
@@ -199,10 +199,10 @@ typedef struct {int v; } libxl_enum_string_table; +typedef struct libxl__ctx libxl_ctx ; +#include "_libxl_types.h" -typedef struct libxl__ctx libxl_ctx ; -const libxl_version_info *libxl_get_version_info (libxl_ctx *ctx); typedef struct {
tools/libxl/libxl_internal.h +11 -0
@@ -35,7 +35,9 @@#include "flexarray.h" #include "libxl_utils.h" +#include "_libxl_types_internal.h" +#include "libxl_json.h" #define LIBXL_DESTROY_TIMEOUT 10#define LIBXL_DEVICE_MODEL_START_TIMEOUT 10
@@ -362,6 +364,14 @@ _hidden char *libxl__cpupoolid_to_name(l _hidden int libxl__enum_from_string(const libxl_enum_string_table *t,const char *s,int *e); +_hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str); + +_hidden yajl_gen_status libxl__string_gen_json(yajl_gen hand, const char *p); + +typedef yajl_gen_status (*libxl__gen_json_callback )(yajl_gen hand,void *); +_hidden char *libxl__object_to_json(libxl_ctx *ctx, const char *type, +libxl__gen_json_callback gen,void *p); +/* holds the CPUID response for a single CPUID leaf * input contains the value of the EAX and ECX register, * and each policy string contains a filter to apply to
@@ -447,6 +457,7 @@ _hidden int libxl__qmp_initializations(l#include <yajl/yajl_gen.h> _hidden yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str); +_hidden yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str); typedef enum { JSON_ERROR,
tools/libxl/libxl_json.c +276 -0
291 lines not on this page · raw message
tools/libxl/libxl_json.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* 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. +*/ + +#ifndef LIBXL_JSON_H +#define LIBXL_JSON_H + +#include <yajl/yajl_gen.h> + +#include <_libxl_types_json.h> +#include <_libxl_types_internal_json.h> + +#endif /* LIBXL_JSON_H */
tools/libxl/libxl_types.idl +2 -2
@@ -5,7 +5,7 @@ namespace("libxl_") -libxl_domid = Builtin("domid") +libxl_domid = Builtin("domid", json_fn = "yajl_gen_integer", autogenerate_json = False) libxl_uuid = Builtin("uuid", passby=PASS_BY_REFERENCE) libxl_mac = Builtin("mac", passby=PASS_BY_REFERENCE) libxl_cpumap = Builtin("cpumap", destructor_fn="libxl_cpumap_destroy", passby=PASS_BY_REFERENCE)
@@ -16,7 +16,7 @@ libxl_string_list = Builtin("string_list libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE) libxl_file_reference = Builtin("file_reference", destructor_fn="libxl_file_reference_destroy", passby=PASS_BY_REFERENCE) -libxl_hwcap = Builtin("hwcap") +libxl_hwcap = Builtin("hwcap", passby=PASS_BY_REFERENCE) # # Constants / Enumerations
tools/libxl/libxltypes.py +18 -2
@@ -50,6 +50,13 @@ class Type(object): self.autogenerate_destructor = kwargs.setdefault('autogenerate_destructor', True) + if self.typename is not None: + self.json_fn = kwargs.setdefault('json_fn', self.typename + "_gen_json") + else: + self.json_fn = kwargs.setdefault('json_fn', None) + + self.autogenerate_json = kwargs.setdefault('autogenerate_json', True) + def marshal_in(self): return self.dir in [DIR_IN, DIR_BOTH] def marshal_out(self):
@@ -83,6 +90,7 @@ class Builtin(Type): def __init__(self, typename, **kwargs): kwargs.setdefault('destructor_fn', None) kwargs.setdefault('autogenerate_destructor', False) + kwargs.setdefault('autogenerate_json', False) Type.__init__(self, typename, **kwargs) class Number(Builtin):
@@ -90,6 +98,7 @@ class Number(Builtin): kwargs.setdefault('namespace', None) kwargs.setdefault('destructor_fn', None) kwargs.setdefault('signed', False) + kwargs.setdefault('json_fn', "yajl_gen_integer") self.signed = kwargs['signed'] Builtin.__init__(self, ctype, **kwargs)
@@ -163,6 +172,8 @@ class Aggregate(Type): comment = None else: n,t,const,comment = f + if n is None: + raise ValueError self.fields.append(Field(t,n,const=const,comment=comment)) # Returns a tuple (stem, field-expr)
@@ -220,7 +231,10 @@ class KeyedUnion(Aggregate): # void = Builtin("void *", namespace = None) -bool = Builtin("bool", namespace = None) +bool = Builtin("bool", namespace = None, + json_fn = "yajl_gen_bool", + autogenerate_json = False) + size_t = Number("size_t", namespace = None) integer = Number("int", namespace = None, signed = True)
@@ -230,7 +244,9 @@ uint16 = UInt(16) uint32 = UInt(32) uint64 = UInt(64) -string = Builtin("char *", namespace = None, destructor_fn = "free") +string = Builtin("char *", namespace = None, destructor_fn = "free", + json_fn = "libxl__string_gen_json", + autogenerate_json = False) class OrderedDict(dict): """A dictionary which remembers insertion order.
PATCH v2 1/1 xl: allow check-xl-disk-parse to run against installed xl as well as build dir
In reply to Ian Campbell# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1317981947 -3600
# Node ID 347c7631c123af9abdc5d6dbe10ea32cf5804aab
# Parent 75a0a29cccbfce75ba3087cdaf53adfd1b377a11
xl: allow check-xl-disk-parse to run against installed xl as well as build dir
I can't run from the current directory since my build box isn't running Xen so if ./xl doesn't exist use the installed version on the assumption that I've copied the script to a test host.
I think running from the build dir needs the blktap2 libraries, so update LD_LIBRARY_PATH as appropriate.
tools/libxl/check-xl-disk-parse +8 -2
@@ -2,6 +2,13 @@ set -e +if [ -x ./xl ] ; then + export LD_LIBRARY_PATH=.:../libxc:../xenstore:../blktap2/control + XL=./xl +else + XL=xl +fi + fprefix=tmp.check-xl-disk-parse expected () {
@@ -14,8 +21,7 @@ one () { expected_rc=$1; shift printf "test case %s...\n" "$*" set +e - LD_LIBRARY_PATH=.:../libxc:../xenstore \ - ./xl -N block-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null + ${XL} -N block-attach 0 "$@" </dev/null >$fprefix.actual 2>/dev/null actual_rc=$? diff -u $fprefix.expected $fprefix.actual diff_rc=$?
PATCH v2 1/1 xl: use libxl_device_disk_to_json to pretty print disk configuration
In reply to Ian Campbell# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1317982001 -3600
# Node ID 7dc93b06164542f06958a181c4747770a5552457
# Parent 347c7631c123af9abdc5d6dbe10ea32cf5804aab
xl: use libxl_device_disk_to_json to pretty print disk configuration
tools/libxl/check-xl-disk-parse +24 -18
@@ -51,15 +51,18 @@ expected </dev/null one $e foo expected <<END -disk.backend_domid = 0 -disk.pdev_path = /dev/vg/guest-volume -disk.vdev = hda -disk.backend = 0 -disk.format = 4 -disk.script = (null) -disk.removable = 0 -disk.readwrite = 1 -disk.is_cdrom = 0 +disk: { + "backend_domid": 0, + "pdev_path": "/dev/vg/guest-volume", + "vdev": "hda", + "backend": "unknown", + "format": "raw", + "script": null, + "removable": 0, + "readwrite": 1, + "is_cdrom": 0 +} + END one 0 /dev/vg/guest-volume,,hda one 0 /dev/vg/guest-volume,raw,hda,rw
@@ -68,15 +71,18 @@ one 0 format=raw vdev=hda access=rw one 0 raw:/dev/vg/guest-volume,hda,w expected <<END -disk.backend_domid = 0 -disk.pdev_path = /root/image.iso -disk.vdev = hdc -disk.backend = 0 -disk.format = 4 -disk.script = (null) -disk.removable = 1 -disk.readwrite = 0 -disk.is_cdrom = 1 +disk: { + "backend_domid": 0, + "pdev_path": "/root/image.iso", + "vdev": "hdc", + "backend": "unknown", + "format": "raw", + "script": null, + "removable": 1, + "readwrite": 0, + "is_cdrom": 1 +} + END one 0 /root/image.iso,,hdc,cdrom one 0 /root/image.iso,,hdc,,cdrom
tools/libxl/xl_cmdimpl.c +3 -11
@@ -4112,17 +4112,9 @@ int main_blockattach(int argc, char **ar disk.backend_domid = be_domid;if (dryrun_only) { -/* fixme: this should be generated from the idl */ -/* fixme: enums (backend, format) should be converted to strings */ -printf ("disk.backend_domid = %" PRIx32"\n" , disk.backend_domid); -printf ("disk.pdev_path = %s\n" , disk.pdev_path); -printf ("disk.vdev = %s\n" , disk.vdev); -printf ("disk.backend = %d\n" , disk.backend); -printf ("disk.format = %d\n" , disk.format); -printf ("disk.script = %s\n" , disk.script); -printf ("disk.removable = %d\n" , disk.removable); -printf ("disk.readwrite = %d\n" , disk.readwrite); -printf ("disk.is_cdrom = %d\n" , disk.is_cdrom); +char *json =libxl_device_disk_to_json (ctx, &disk); +printf ("disk: %s\n" , json); +free (json);if (ferror (stdout) ||fflush (stdout)) {perror ("stdout" );exit (-1 ); }return 0 ; }
PATCH v2 1/1 libxl: add a test case for correct parsing of disk "backendtype" field
In reply to Ian Campbell# HG changeset patch
# User Ian Campbell <[email protected]>
# Date 1317983222 -3600
# Node ID e530b4b35d3872d93013daa4233cc467a89a1bac
# Parent 7dc93b06164542f06958a181c4747770a5552457
libxl: add a test case for correct parsing of disk "backendtype" field
tools/libxl/check-xl-disk-parse +16 -0
@@ -91,4 +91,20 @@ one 0 "format=raw, vdev=hdc, access=ro, one 0 format=raw vdev=hdc access=ro devtype=cdrom target=/root/image.iso one 0 raw:/root/image.iso,hdc:cdrom,ro +expected <<EOF +disk: { + "backend_domid": 0, + "pdev_path": "/dev/vg/guest-volume", + "vdev": "xvdb", + "backend": "phy", + "format": "raw", + "script": null, + "removable": 0, + "readwrite": 1, + "is_cdrom": 0 +} + +EOF +one 0 backendtype=phy,vdev=xvdb,access=w,target=/dev/vg/guest-volume + complete
Quoted 5 lines · Ian Campbell
Now that Anthony's QMP series is in we can build upon the use of YAJL to add support for pretty printing libxl objects as JSON.
Also includes a user in xl (to print disks on dry run) and an associated fix to the check-xl-disk-parse test script.
In my V1 posting of this series I also included "libxl: probe disk backend type in libxl_device_disk_add" but forgot it in the repost, so here is patch 5/4:
# HG changeset patch
# User Ian Campbell <[email protected]> # Date 1318498260 -3600
# Node ID 29bd271877873f4a38217de89f8f4f74405496b5 # Parent 98cb420b606bf69e3e3177ebe8b16b529c5ed0ed
libxl: probe disk backend type in libxl_device_disk_add
Without this "xl block-attach" does not work. On create do_domain_create already catches this.
tools/libxl/libxl.c +3 -0
@@ -929,6 +929,9 @@ int libxl_device_disk_add(libxl_ctx *ctx rc =libxl__device_disk_set_backend (&gc, disk);if (rc) goto out; + rc =libxl__device_disk_set_backend (&gc, disk); +if (rc) goto out; + front =flexarray_make (16 ,1 );if (!front) { rc =ERROR_NOMEM ;
Ian Campbell writes ("[Xen-devel] Re: [PATCH 0 of 4 v2] libxl: support json for > In my V1 posting of this series I also included "libxl: probe disk
Quoted 2 lines
backend type in
libxl_device_disk_add" but forgot it in the repost, so here is patch 5/4:
Thanks, acked and applied all 5.
Ian.