diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2012-08-23 19:12:28 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2012-08-23 19:12:28 +0100 |
commit | ac963eb7895b8351017bb6005505c2b176202f0e (patch) | |
tree | 90495680f78a96e1a25510a516b3f751bffb29fa | |
parent | 7eaccb3cc3fabdde1fe7ef55300941f5520ca785 (diff) | |
download | xen-ac963eb7895b8351017bb6005505c2b176202f0e.tar.gz xen-ac963eb7895b8351017bb6005505c2b176202f0e.tar.bz2 xen-ac963eb7895b8351017bb6005505c2b176202f0e.zip |
xl: make "xl list -l" proper JSON
Bastian Blank reports that the output of this command is just multiple
JSON objects concatenated and is not a single properly formed JSON
object.
Fix this by wrapping in an array. This turned out to be a bit more
intrusive than I was expecting due to the requirement to keep
supporting the SXP output mode.
Python's json module is happy to parse the result...
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
-rw-r--r-- | tools/libxl/xl_cmdimpl.c | 87 |
1 files changed, 71 insertions, 16 deletions
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index bca74476a8..e825897b43 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -319,23 +319,10 @@ static void dolog(const char *file, int line, const char *func, char *fmt, ...) free(s); } -static void printf_info(enum output_format output_format, - int domid, - libxl_domain_config *d_config) +static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid, + libxl_domain_config *d_config) { - if (output_format == OUTPUT_FORMAT_SXP) - return printf_info_sexp(domid, d_config); - - const char *buf; - libxl_yajl_length len = 0; yajl_gen_status s; - yajl_gen hand; - - hand = libxl_yajl_gen_alloc(NULL); - if (!hand) { - fprintf(stderr, "unable to allocate JSON generator\n"); - return; - } s = yajl_gen_map_open(hand); if (s != yajl_gen_status_ok) @@ -364,6 +351,31 @@ static void printf_info(enum output_format output_format, if (s != yajl_gen_status_ok) goto out; +out: + return s; +} +static void printf_info(enum output_format output_format, + int domid, + libxl_domain_config *d_config) +{ + if (output_format == OUTPUT_FORMAT_SXP) + return printf_info_sexp(domid, d_config); + + const char *buf; + libxl_yajl_length len = 0; + yajl_gen_status s; + yajl_gen hand; + + hand = libxl_yajl_gen_alloc(NULL); + if (!hand) { + fprintf(stderr, "unable to allocate JSON generator\n"); + return; + } + + s = printf_info_one_json(hand, domid, d_config); + if (s != yajl_gen_status_ok) + goto out; + s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &len); if (s != yajl_gen_status_ok) goto out; @@ -2674,6 +2686,24 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) uint8_t *data; int i, len, rc; + yajl_gen hand; + yajl_gen_status s; + const char *buf; + libxl_yajl_length yajl_len = 0; + + if (default_output_format == OUTPUT_FORMAT_JSON) { + hand = libxl_yajl_gen_alloc(NULL); + if (!hand) { + fprintf(stderr, "unable to allocate JSON generator\n"); + return; + } + + s = yajl_gen_array_open(hand); + if (s != yajl_gen_status_ok) + goto out; + } else + s = yajl_gen_status_ok; + for (i = 0; i < nb_domain; i++) { /* no detailed info available on dom0 */ if (info[i].domid == 0) @@ -2684,10 +2714,35 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) CHK_ERRNO(asprintf(&config_source, "<domid %d data>", info[i].domid)); libxl_domain_config_init(&d_config); parse_config_data(config_source, (char *)data, len, &d_config, NULL); - printf_info(default_output_format, info[i].domid, &d_config); + if (default_output_format == OUTPUT_FORMAT_SXP) + printf_info_sexp(domid, &d_config); + else + s = printf_info_one_json(hand, info[i].domid, &d_config); libxl_domain_config_dispose(&d_config); free(data); free(config_source); + if (s != yajl_gen_status_ok) + goto out; + } + + if (default_output_format == OUTPUT_FORMAT_JSON) { + s = yajl_gen_array_close(hand); + if (s != yajl_gen_status_ok) + goto out; + + s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &yajl_len); + if (s != yajl_gen_status_ok) + goto out; + + puts(buf); + } + +out: + if (default_output_format == OUTPUT_FORMAT_JSON) { + yajl_gen_free(hand); + if (s != yajl_gen_status_ok) + fprintf(stderr, + "unable to format domain config as JSON (YAJL:%d)\n", s); } } |