* [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl
@ 2025-08-08 14:55 Anthony PERARD
2025-08-08 14:55 ` [XEN PATCH 01/11] xl: move printf_info prototype to an header Anthony PERARD
` (11 more replies)
0 siblings, 12 replies; 34+ messages in thread
From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw)
To: xen-devel
Cc: Anthony PERARD, Juergen Gross, Roger Pau Monné,
Andrew Cooper, Jan Beulich, Community Manager, Stefano Stabellini,
Julien Grall, Michal Orzel, Oleksii Kurochko
From: Anthony PERARD <anthony.perard@vates.tech>
Patch series available in this git branch:
https://xenbits.xenproject.org/git-http/people/aperard/xen-unstable.git br.libxl-libjsonc-v1
Hi,
The library YAJL has been unmaintained for several years, without an obvious
fork to pick.
On the other and the library json-c is been maintained and use by several other
project, it's probably already installed on your machine. So this patch series
intend to allow to build the Xen toolstack again json-c, and forgo yajl.
Just in case, YAJL is can still be used.
There's bit of libxl API that exposes YAJL, mainly so it can be used by `xl` to
call libxl_domain_config_gen_json(). It was exposed via the "libxl_json.h"
headers. This functions and others won't be available when libxl is build
against json-c.
Cheers,
Anthony PERARD (11):
xl: move printf_info prototype to an header
libxl: Remove duplicate libxl_domain_config_gen_json prototype
libxl: remove duplicated libxl__yajl_gen_asciiz() prototype
tools/configure: Introduce deps on json-c lib for libxl
libxl: Convert libxl__json_parse() to use json-c
libxl: convert libxl__json_object_to_yajl_gen to
libxl__json_object_to_libjsonc_object
libxl: libxl__object_to_json() to json-c
libxl: convert libxl__json_object_to_json() to json_object
tools/libxenstat: Use json-c when available
configure: Use json-c by default, fallback to yajl
Update CHANGELOG and README with dependency on json-c
CHANGELOG.md | 2 +
README | 2 +-
config/Tools.mk.in | 2 +
tools/config.h.in | 3 +
tools/configure | 136 +++++-
tools/configure.ac | 10 +-
tools/include/libxl_json.h | 30 +-
tools/libs/light/Makefile | 7 +-
tools/libs/light/gentypes.py | 160 ++++++-
tools/libs/light/idl.py | 7 +-
tools/libs/light/libxl_cpuid.c | 119 +++++
tools/libs/light/libxl_internal.h | 25 +-
tools/libs/light/libxl_json.c | 557 +++++++++++++++++++++-
tools/libs/light/libxl_qmp.c | 53 ++
tools/libs/light/libxl_types.idl | 7 +-
tools/libs/light/libxl_types_internal.idl | 3 +-
tools/libs/stat/Makefile | 3 +-
tools/libs/stat/xenstat_qmp.c | 126 ++++-
tools/xl/Makefile | 2 +-
tools/xl/xl.h | 3 +
tools/xl/xl_info.c | 105 +++-
tools/xl/xl_misc.c | 3 -
22 files changed, 1313 insertions(+), 52 deletions(-)
--
Anthony PERARD
^ permalink raw reply [flat|nested] 34+ messages in thread* [XEN PATCH 01/11] xl: move printf_info prototype to an header 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 14:55 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype Anthony PERARD ` (10 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD From: Anthony PERARD <anthony.perard@vates.tech> In a single place. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/xl/xl.h | 3 +++ tools/xl/xl_info.c | 3 --- tools/xl/xl_misc.c | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tools/xl/xl.h b/tools/xl/xl.h index 45745f0dbb..9000df00de 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -310,6 +310,9 @@ extern void printf_info_sexp(int domid, libxl_domain_config *d_config, FILE *fh) extern void apply_global_affinity_masks(libxl_domain_type type, libxl_bitmap *vcpu_affinity_array, unsigned int size); +void printf_info(enum output_format output_format, + int domid, + libxl_domain_config *d_config, FILE *fh); #define XL_GLOBAL_CONFIG XEN_CONFIG_DIR "/xl.conf" #define XL_LOCK_FILE XEN_LOCK_DIR "/xl" diff --git a/tools/xl/xl_info.c b/tools/xl/xl_info.c index eb019e3ee9..3fbc0698b7 100644 --- a/tools/xl/xl_info.c +++ b/tools/xl/xl_info.c @@ -96,9 +96,6 @@ static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid, return s; } -void printf_info(enum output_format output_format, - int domid, - libxl_domain_config *d_config, FILE *fh); void printf_info(enum output_format output_format, int domid, libxl_domain_config *d_config, FILE *fh) diff --git a/tools/xl/xl_misc.c b/tools/xl/xl_misc.c index 08f0fb6dc9..f0167e1603 100644 --- a/tools/xl/xl_misc.c +++ b/tools/xl/xl_misc.c @@ -256,9 +256,6 @@ int main_dump_core(int argc, char **argv) return EXIT_SUCCESS; } -extern void printf_info(enum output_format output_format, - int domid, - libxl_domain_config *d_config, FILE *fh); int main_config_update(int argc, char **argv) { uint32_t domid; -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 01/11] xl: move printf_info prototype to an header 2025-08-08 14:55 ` [XEN PATCH 01/11] xl: move printf_info prototype to an header Anthony PERARD @ 2025-08-27 14:55 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 14:55 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > In a single place. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 01/11] xl: move printf_info prototype to an header Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 14:55 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype Anthony PERARD ` (9 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> Since f9e681d3d1b8, the prototype of libxl_domain_config_gen_json is generated from IDL in _libxl_types_json.h. Fixes: f9e681d3d1b8 ("libxl: move definition of libxl_domain_config into the IDL") Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/include/libxl_json.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h index 260783bfde..3f97267eae 100644 --- a/tools/include/libxl_json.h +++ b/tools/include/libxl_json.h @@ -90,7 +90,4 @@ static inline yajl_gen libxl_yajl_gen_alloc(const yajl_alloc_funcs *allocFuncs) #endif /* !HAVE_YAJL_V2 */ -yajl_gen_status libxl_domain_config_gen_json(yajl_gen hand, - libxl_domain_config *p); - #endif /* LIBXL_JSON_H */ -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype 2025-08-08 14:55 ` [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype Anthony PERARD @ 2025-08-27 14:55 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 14:55 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > Since f9e681d3d1b8, the prototype of libxl_domain_config_gen_json is > generated from IDL in _libxl_types_json.h. > > Fixes: f9e681d3d1b8 ("libxl: move definition of libxl_domain_config into the IDL") > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 01/11] xl: move printf_info prototype to an header Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 14:56 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl Anthony PERARD ` (8 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/libs/light/libxl_internal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index 2a5b233caa..4b6587a27a 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -1993,8 +1993,6 @@ _hidden char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid); _hidden int libxl__enum_from_string(const libxl_enum_string_table *t, const char *s, int *e) NN(2); -_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 *); -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype 2025-08-08 14:55 ` [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype Anthony PERARD @ 2025-08-27 14:56 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 14:56 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (2 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-11 10:48 ` Andrew Cooper 2025-08-27 15:01 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c Anthony PERARD ` (7 subsequent siblings) 11 siblings, 2 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> To replace yajl. Introduce YAJL_LIBS variable, to be able to remove "-lyajl" later. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- config/Tools.mk.in | 2 + tools/config.h.in | 3 ++ tools/configure | 107 +++++++++++++++++++++++++++++++++++++- tools/configure.ac | 6 ++- tools/libs/light/Makefile | 5 +- tools/xl/Makefile | 2 +- 6 files changed, 119 insertions(+), 6 deletions(-) diff --git a/config/Tools.mk.in b/config/Tools.mk.in index e47ac23d11..c2201021d1 100644 --- a/config/Tools.mk.in +++ b/config/Tools.mk.in @@ -65,6 +65,8 @@ EXTFS_LIBS := @EXTFS_LIBS@ CURSES_LIBS := @CURSES_LIBS@ TINFO_LIBS := @TINFO_LIBS@ ARGP_LDFLAGS := @argp_ldflags@ +LIBJSONC_LIBS := @libjsonc_LIBS@ +YAJL_LIBS := @YAJL_LIBS@ FILE_OFFSET_BITS := @FILE_OFFSET_BITS@ diff --git a/tools/config.h.in b/tools/config.h.in index fe2a94cfc4..ed0042018d 100644 --- a/tools/config.h.in +++ b/tools/config.h.in @@ -27,6 +27,9 @@ /* Define to 1 if you have the `fdt' library (-lfdt). */ #undef HAVE_LIBFDT +/* Use library json-c */ +#undef HAVE_LIBJSONC + /* Define to 1 if you have the `lzma' library (-llzma). */ #undef HAVE_LIBLZMA diff --git a/tools/configure b/tools/configure index 5abd44e21e..edd1701b2d 100755 --- a/tools/configure +++ b/tools/configure @@ -660,6 +660,9 @@ libnl LIBNL3_LIBS LIBNL3_CFLAGS argp_ldflags +YAJL_LIBS +libjsonc_LIBS +libjsonc_CFLAGS PTHREAD_LIBS PTHREAD_LDFLAGS PTHREAD_CFLAGS @@ -882,6 +885,8 @@ pixman_CFLAGS pixman_LIBS libzstd_CFLAGS libzstd_LIBS +libjsonc_CFLAGS +libjsonc_LIBS LIBNL3_CFLAGS LIBNL3_LIBS SYSTEMD_SLEEP_DIR' @@ -1633,6 +1638,10 @@ Some influential environment variables: C compiler flags for libzstd, overriding pkg-config libzstd_LIBS linker flags for libzstd, overriding pkg-config + libjsonc_CFLAGS + C compiler flags for libjsonc, overriding pkg-config + libjsonc_LIBS + linker flags for libjsonc, overriding pkg-config LIBNL3_CFLAGS C compiler flags for LIBNL3, overriding pkg-config LIBNL3_LIBS linker flags for LIBNL3, overriding pkg-config @@ -9624,6 +9633,99 @@ printf "%s\n" "$ax_cv_pthread_flags" >&6; } + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libjsonc" >&5 +printf %s "checking for libjsonc... " >&6; } + +if test -n "$libjsonc_CFLAGS"; then + pkg_cv_libjsonc_CFLAGS="$libjsonc_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json-c\""; } >&5 + ($PKG_CONFIG --exists --print-errors "json-c") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libjsonc_CFLAGS=`$PKG_CONFIG --cflags "json-c" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libjsonc_LIBS"; then + pkg_cv_libjsonc_LIBS="$libjsonc_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json-c\""; } >&5 + ($PKG_CONFIG --exists --print-errors "json-c") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libjsonc_LIBS=`$PKG_CONFIG --libs "json-c" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libjsonc_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "json-c" 2>&1` + else + libjsonc_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "json-c" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libjsonc_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (json-c) were not met: + +$libjsonc_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables libjsonc_CFLAGS +and libjsonc_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables libjsonc_CFLAGS +and libjsonc_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/>. +See \`config.log' for more details" "$LINENO" 5; } +else + libjsonc_CFLAGS=$pkg_cv_libjsonc_CFLAGS + libjsonc_LIBS=$pkg_cv_libjsonc_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_LIBJSONC 1" >>confdefs.h + +fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for yajl_alloc in -lyajl" >&5 printf %s "checking for yajl_alloc in -lyajl... " >&6; } if test ${ac_cv_lib_yajl_yajl_alloc+y} @@ -9661,9 +9763,10 @@ fi printf "%s\n" "$ac_cv_lib_yajl_yajl_alloc" >&6; } if test "x$ac_cv_lib_yajl_yajl_alloc" = xyes then : - printf "%s\n" "#define HAVE_LIBYAJL 1" >>confdefs.h + YAJL_LIBS=-lyajl - LIBS="-lyajl $LIBS" + +printf "%s\n" "#define HAVE_LIBYAJL 1" >>confdefs.h else $as_nop as_fn_error $? "Could not find yajl" "$LINENO" 5 diff --git a/tools/configure.ac b/tools/configure.ac index dada1c3b15..bb40b5b3f0 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -424,7 +424,11 @@ AC_SUBST([ZLIB_CFLAGS]) AC_SUBST([ZLIB_LIBS]) AX_CHECK_EXTFS AX_CHECK_PTHREAD -AC_CHECK_LIB([yajl], [yajl_alloc], [], +PKG_CHECK_MODULES([libjsonc], [json-c], + [AC_DEFINE([HAVE_LIBJSONC], [1], [Use library json-c])]) +AC_CHECK_LIB([yajl], [yajl_alloc], + [AC_SUBST([YAJL_LIBS],[-lyajl]) + AC_DEFINE([HAVE_LIBYAJL],[1],[Define to 1 if you have the `yajl' library (-lyajl).])], [AC_MSG_ERROR([Could not find yajl])]) AC_CHECK_LIB([z], [deflateCopy], [], [AC_MSG_ERROR([Could not find zlib])]) AC_CHECK_HEADER([argp.h], [ diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index b690d92159..fa2a338c2b 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -166,7 +166,8 @@ LDLIBS-$(CONFIG_Linux) += -luuid LDLIBS-$(CONFIG_Linux) += -lrt LDLIBS-$(CONFIG_ARM) += -lfdt LDLIBS-y += $(PTHREAD_LIBS) -LDLIBS-y += -lyajl +LDLIBS-y += $(YAJL_LIBS) +LDLIBS-y += $(LIBJSONC_LIBS) LDLIBS += $(LDLIBS-y) $(OBJS-y) $(PIC_OBJS) $(LIBXL_TEST_OBJS): CFLAGS += $(CFLAGS_LIBXL) -include $(XEN_ROOT)/tools/config.h @@ -246,7 +247,7 @@ libxenlight_test.so: $(PIC_OBJS) $(LIBXL_TEST_OBJS) $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS) $(APPEND_LDFLAGS) test_%: test_%.o test_common.o libxenlight_test.so - $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) $(YAJL_LIBS) $(LIBJSONC_LIBS) $(APPEND_LDFLAGS) libxl-save-helper: $(SAVE_HELPER_OBJS) libxenlight.so $(CC) $(LDFLAGS) -o $@ $(SAVE_HELPER_OBJS) $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxentoolcore) $(APPEND_LDFLAGS) diff --git a/tools/xl/Makefile b/tools/xl/Makefile index ad577cdd70..ff7a5aee94 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -33,7 +33,7 @@ $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs i all: xl xl: $(XL_OBJS) - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(YAJL_LIBS) $(LIBJSONC_LIBS) $(APPEND_LDFLAGS) .PHONY: install install: all -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-08 14:55 ` [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl Anthony PERARD @ 2025-08-11 10:48 ` Andrew Cooper 2025-08-13 15:42 ` Anthony PERARD 2025-08-27 15:01 ` Jason Andryuk 1 sibling, 1 reply; 34+ messages in thread From: Andrew Cooper @ 2025-08-11 10:48 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 08/08/2025 3:55 pm, Anthony PERARD wrote: > diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile > index b690d92159..fa2a338c2b 100644 > --- a/tools/libs/light/Makefile > +++ b/tools/libs/light/Makefile > @@ -166,7 +166,8 @@ LDLIBS-$(CONFIG_Linux) += -luuid > LDLIBS-$(CONFIG_Linux) += -lrt > LDLIBS-$(CONFIG_ARM) += -lfdt > LDLIBS-y += $(PTHREAD_LIBS) > -LDLIBS-y += -lyajl > +LDLIBS-y += $(YAJL_LIBS) > +LDLIBS-y += $(LIBJSONC_LIBS) > LDLIBS += $(LDLIBS-y) > > $(OBJS-y) $(PIC_OBJS) $(LIBXL_TEST_OBJS): CFLAGS += $(CFLAGS_LIBXL) -include $(XEN_ROOT)/tools/config.h > @@ -246,7 +247,7 @@ libxenlight_test.so: $(PIC_OBJS) $(LIBXL_TEST_OBJS) > $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS) $(APPEND_LDFLAGS) > > test_%: test_%.o test_common.o libxenlight_test.so > - $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) -lyajl $(APPEND_LDFLAGS) > + $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) $(YAJL_LIBS) $(LIBJSONC_LIBS) $(APPEND_LDFLAGS) > > libxl-save-helper: $(SAVE_HELPER_OBJS) libxenlight.so > $(CC) $(LDFLAGS) -o $@ $(SAVE_HELPER_OBJS) $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxentoolcore) $(APPEND_LDFLAGS) > diff --git a/tools/xl/Makefile b/tools/xl/Makefile > index ad577cdd70..ff7a5aee94 100644 > --- a/tools/xl/Makefile > +++ b/tools/xl/Makefile > @@ -33,7 +33,7 @@ $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs i > all: xl > > xl: $(XL_OBJS) > - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) -lyajl $(APPEND_LDFLAGS) > + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(YAJL_LIBS) $(LIBJSONC_LIBS) $(APPEND_LDFLAGS) > > .PHONY: install > install: all Specifying both isn't entirely great when one is supposed to be empty. Could we not have XEN_JSON_LIB(s) which is set to either $YAJL_LIBS or $LIBJSONC_LIBS as appropriate? ~Andrew ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-11 10:48 ` Andrew Cooper @ 2025-08-13 15:42 ` Anthony PERARD 0 siblings, 0 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-13 15:42 UTC (permalink / raw) To: Andrew Cooper; +Cc: xen-devel, Anthony PERARD, Juergen Gross On Mon, Aug 11, 2025 at 11:48:19AM +0100, Andrew Cooper wrote: > On 08/08/2025 3:55 pm, Anthony PERARD wrote: > > xl: $(XL_OBJS) > > - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) -lyajl $(APPEND_LDFLAGS) > > + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(YAJL_LIBS) $(LIBJSONC_LIBS) $(APPEND_LDFLAGS) > > > > .PHONY: install > > install: all > > Specifying both isn't entirely great when one is supposed to be empty. > > Could we not have XEN_JSON_LIB(s) which is set to either $YAJL_LIBS or > $LIBJSONC_LIBS as appropriate? Yes, that sounds good. Thanks, -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-08 14:55 ` [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl Anthony PERARD 2025-08-11 10:48 ` Andrew Cooper @ 2025-08-27 15:01 ` Jason Andryuk 2025-08-29 13:17 ` Anthony PERARD 1 sibling, 1 reply; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 15:01 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > To replace yajl. > > Introduce YAJL_LIBS variable, to be able to remove "-lyajl" later. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Should the two configure changes be merged and placed at the end of the series? That avoids a half implemented conversion in between. I think Andrew's XEN_JSON_LIBS suggestion is a good one. Regards, Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-27 15:01 ` Jason Andryuk @ 2025-08-29 13:17 ` Anthony PERARD 2025-08-31 14:42 ` Jason Andryuk 0 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-29 13:17 UTC (permalink / raw) To: Jason Andryuk; +Cc: xen-devel, Anthony PERARD, Juergen Gross On Wed, Aug 27, 2025 at 11:01:59AM -0400, Jason Andryuk wrote: > On 2025-08-08 10:55, Anthony PERARD wrote: > > From: Anthony PERARD <anthony.perard@vates.tech> > > > > To replace yajl. > > > > Introduce YAJL_LIBS variable, to be able to remove "-lyajl" later. > > > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > > Should the two configure changes be merged and placed at the end of the > series? That avoids a half implemented conversion in between. It might be half-converted, but it's fully working. Every single patch introduce changes that can be use right away. I've actually make use of this possibility. On every single patch, we can run ./testidl, which will exercise both lib against each other. ./testidl does LibxlObj-to-JSONstring and back and forth. So on the next commit, we would have JSON generated with json-c, which is then parsed with YAJL, to finally be generated to JSON with json-c again, then both JSON output are compared. I've actually prepared the patch "libxl: Convert libxl__json_parse() to use json-c' last, then put it in front and check that ./testidl was still working. This help me be confident enough that the conversion to json-c was correct. So if we squash both config change, every patch until the config change would only introduce dead code. Cheers, -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl 2025-08-29 13:17 ` Anthony PERARD @ 2025-08-31 14:42 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-31 14:42 UTC (permalink / raw) To: Anthony PERARD; +Cc: xen-devel, Anthony PERARD, Juergen Gross On 2025-08-29 09:17, Anthony PERARD wrote: > On Wed, Aug 27, 2025 at 11:01:59AM -0400, Jason Andryuk wrote: >> On 2025-08-08 10:55, Anthony PERARD wrote: >>> From: Anthony PERARD <anthony.perard@vates.tech> >>> >>> To replace yajl. >>> >>> Introduce YAJL_LIBS variable, to be able to remove "-lyajl" later. >>> >>> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> >> >> Should the two configure changes be merged and placed at the end of the >> series? That avoids a half implemented conversion in between. > > It might be half-converted, but it's fully working. Every single patch > introduce changes that can be use right away. I've actually make use of > this possibility. On every single patch, we can run ./testidl, which > will exercise both lib against each other. > > ./testidl does LibxlObj-to-JSONstring and back and forth. So on the next > commit, we would have JSON generated with json-c, which is then parsed > with YAJL, to finally be generated to JSON with json-c again, then both > JSON output are compared. > > I've actually prepared the patch "libxl: Convert libxl__json_parse() to > use json-c' last, then put it in front and check that ./testidl was > still working. > > This help me be confident enough that the conversion to json-c was > correct. > > So if we squash both config change, every patch until the config change > would only introduce dead code. Oh, I didn't realize that. Yes, your approach sounds great. Thanks, Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (3 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 15:20 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object Anthony PERARD ` (6 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> This reuse the "json_callback_*" implemented for the yajl parser as they don't really need to be changed. It's just awkward to have to cast between `unsigned char` and `char.` Replace few strncpy() by memcpy() to let the compiler know we want to copy the string without the terminating nul, as we are adding it just after. Also, it should be possible to keep using YAJL parser when json-c library isn't available. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/include/libxl_json.h | 4 ++ tools/libs/light/libxl_json.c | 120 ++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h index 3f97267eae..f0b4871e0e 100644 --- a/tools/include/libxl_json.h +++ b/tools/include/libxl_json.h @@ -42,6 +42,7 @@ yajl_gen_status libxl_ms_vm_genid_gen_json(yajl_gen hand, libxl_ms_vm_genid *p); # define HAVE_YAJL_V2 1 #endif +#ifdef HAVE_LIBYAJL #ifdef HAVE_YAJL_V2 typedef size_t libxl_yajl_length; @@ -89,5 +90,8 @@ static inline yajl_gen libxl_yajl_gen_alloc(const yajl_alloc_funcs *allocFuncs) } #endif /* !HAVE_YAJL_V2 */ +#else +typedef size_t libxl_yajl_length; +#endif /* !HAVE_LIBYAJL */ #endif /* LIBXL_JSON_H */ diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index 9b8ef2cab9..44ee6e213f 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -16,7 +16,25 @@ #include <math.h> +#ifdef HAVE_LIBJSONC +#include <json-c/json.h> +#define USE_LIBJSONC_PARSER +#endif + +#ifdef HAVE_LIBYAJL +# ifndef USE_LIBJSONC_PARSER +# define USE_LIBYAJL_PARSER +# endif +#endif + + +#ifdef USE_LIBJSONC_PARSER +#include <json-c/json_visit.h> +#endif + +#ifdef USE_LIBYAJL_PARSER #include <yajl/yajl_parse.h> +#endif #include <yajl/yajl_gen.h> #include "libxl_internal.h" @@ -25,7 +43,9 @@ typedef struct libxl__yajl_ctx { libxl__gc *gc; +#ifdef USE_LIBYAJL_PARSER yajl_handle hand; +#endif libxl__json_object *head; libxl__json_object *current; #ifdef DEBUG_ANSWER @@ -33,7 +53,7 @@ typedef struct libxl__yajl_ctx { #endif } libxl__yajl_ctx; -#ifdef DEBUG_ANSWER +#if defined(DEBUG_ANSWER) && defined(USE_LIBYAJL_PARSER) #if YAJL_VERSION < 20000 # define DEBUG_GEN_ALLOC(ctx) \ if ((ctx)->g == NULL) { \ @@ -759,7 +779,7 @@ static int json_callback_number(void *opaque, const char *s, libxl_yajl_length l obj = libxl__json_object_alloc(ctx->gc, JSON_NUMBER); t = libxl__zalloc(ctx->gc, len + 1); - strncpy(t, s, len); + memcpy(t, s, len); t[len] = 0; obj->u.string = t; @@ -806,7 +826,7 @@ static int json_callback_map_key(void *opaque, const unsigned char *str, DEBUG_GEN_STRING(ctx, str, len); - strncpy(t, (const char *) str, len); + memcpy(t, (const char *) str, len); t[len] = 0; if (libxl__json_object_is_map(obj)) { @@ -890,6 +910,7 @@ static int json_callback_end_array(void *opaque) return 1; } +#ifdef USE_LIBYAJL_PARSER static yajl_callbacks callbacks = { json_callback_null, json_callback_boolean, @@ -903,28 +924,111 @@ static yajl_callbacks callbacks = { json_callback_start_array, json_callback_end_array }; +#endif static void yajl_ctx_free(libxl__yajl_ctx *yajl_ctx) { +#ifdef USE_LIBYAJL_PARSER if (yajl_ctx->hand) { yajl_free(yajl_ctx->hand); yajl_ctx->hand = NULL; } +#endif DEBUG_GEN_FREE(yajl_ctx); } +#ifdef USE_LIBJSONC_PARSER +static int jso_visiter(json_object *jso, + int flags, + json_object *parent_jso, + const char *jso_key, + size_t *jso_index, + void *userarg) +{ + enum json_type type; + int r; + + if (jso_key && flags != JSON_C_VISIT_SECOND) { + json_callback_map_key(userarg, (const unsigned char*)jso_key, strlen(jso_key)); + } + type = json_object_get_type(jso); + switch (type) { + case json_type_null: + r = json_callback_null(userarg); + break; + case json_type_boolean: + r = json_callback_boolean(userarg, json_object_get_boolean(jso)); + break; + case json_type_int: + case json_type_double: { + // it might be better to use on of + // json_object_get_{int,int64,uint64,double} instead. + // but would need to replace json_callback_number(). + const char *s = json_object_get_string(jso); + r = json_callback_number(userarg, s, strlen(s)); + break; + } + case json_type_object: + if (flags != JSON_C_VISIT_SECOND) { + r = json_callback_start_map(userarg); + } else { + r = json_callback_end_map(userarg); + } + break; + case json_type_array: + if (flags != JSON_C_VISIT_SECOND) { + r = json_callback_start_array(userarg); + } else { + r = json_callback_end_array(userarg); + } + break; + case json_type_string: { + const char *s = json_object_get_string(jso); + const int len = json_object_get_string_len(jso); + r = json_callback_string(userarg, (const unsigned char*)s, len); + break; + } + default: + /* error */ + r = 0; + } + if (r == 0) + return JSON_C_VISIT_RETURN_ERROR; + return JSON_C_VISIT_RETURN_CONTINUE; +} +#endif + libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) { +#ifdef USE_LIBYAJL_PARSER yajl_status status; + unsigned char *str = NULL; +#endif libxl__yajl_ctx yajl_ctx; libxl__json_object *o = NULL; - unsigned char *str = NULL; +#ifdef USE_LIBJSONC_PARSER + json_object *jso; + enum json_tokener_error error; + + jso = json_tokener_parse_verbose(s, &error); + if (!jso) { + LOG(ERROR, "json-c parse error: %s", json_tokener_error_desc(error)); + goto out; + } +#endif memset(&yajl_ctx, 0, sizeof (yajl_ctx)); yajl_ctx.gc = gc; DEBUG_GEN_ALLOC(&yajl_ctx); +#ifdef USE_LIBJSONC_PARSER + int r = json_c_visit(jso, 0, jso_visiter, &yajl_ctx); + if (r < 0) { + LOG(ERROR, "json_c_visit failed"); + goto out; + } +#elif defined(USE_LIBYAJL_PARSER) if (yajl_ctx.hand == NULL) { yajl_ctx.hand = libxl__yajl_alloc(&callbacks, NULL, &yajl_ctx); } @@ -935,6 +1039,7 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) status = yajl_complete_parse(yajl_ctx.hand); if (status != yajl_status_ok) goto out; +#endif o = yajl_ctx.head; @@ -943,13 +1048,20 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) yajl_ctx.head = NULL; yajl_ctx_free(&yajl_ctx); +#ifdef USE_LIBJSONC_PARSER + json_object_put(jso); +#endif return o; out: +#ifdef USE_LIBJSONC_PARSER + json_object_put(jso); +#elif defined(USE_LIBYAJL_PARSER) 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); +#endif yajl_ctx_free(&yajl_ctx); return NULL; } -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c 2025-08-08 14:55 ` [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c Anthony PERARD @ 2025-08-27 15:20 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 15:20 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > This reuse the "json_callback_*" implemented for the yajl parser as > they don't really need to be changed. It's just awkward to have to > cast between `unsigned char` and `char.` > > Replace few strncpy() by memcpy() to let the compiler know we want to > copy the string without the terminating nul, as we are adding it just > after. > > Also, it should be possible to keep using YAJL parser when json-c > library isn't available. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (4 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 15:37 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c Anthony PERARD ` (5 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> Convert yajl_gen to json_object from lib json-c. And make use of it in qmp_prepare_cmd(), which can be compiled with either lib. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/include/libxl_json.h | 6 ++ tools/libs/light/libxl_internal.h | 7 +++ tools/libs/light/libxl_json.c | 95 +++++++++++++++++++++++++++++++ tools/libs/light/libxl_qmp.c | 53 +++++++++++++++++ 4 files changed, 161 insertions(+) diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h index f0b4871e0e..e2ef8151f0 100644 --- a/tools/include/libxl_json.h +++ b/tools/include/libxl_json.h @@ -15,12 +15,18 @@ #ifndef LIBXL_JSON_H #define LIBXL_JSON_H +#ifdef HAVE_LIBJSONC +#include <json-c/json.h> +#endif + +#ifdef HAVE_LIBYAJL #include <yajl/yajl_gen.h> #include <yajl/yajl_parse.h> #ifdef HAVE_YAJL_YAJL_VERSION_H # include <yajl/yajl_version.h> #endif +#endif yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val); yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p); diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index 4b6587a27a..b66aaa779d 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -2234,9 +2234,16 @@ _hidden const libxl__json_object *libxl__json_map_get(const char *key, */ _hidden libxl__json_object *libxl__json_object_alloc(libxl__gc *gc_opt, libxl__json_node_type type); +#ifdef HAVE_LIBJSONC +_hidden int libxl__json_object_to_json_object(libxl__gc *gc, + json_object **jso_out, + const libxl__json_object *obj); +#endif +#ifdef HAVE_LIBYAJL _hidden yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc_opt, yajl_gen hand, const libxl__json_object *param); +#endif _hidden void libxl__json_object_free(libxl__gc *gc_opt, libxl__json_object *obj); diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index 44ee6e213f..b26ac901d6 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -631,6 +631,100 @@ const libxl__json_object *libxl__json_map_get(const char *key, return NULL; } +#ifdef HAVE_LIBJSONC +int libxl__json_object_to_json_object(libxl__gc *gc, + json_object **jso_out, + const libxl__json_object *obj) +{ + int idx = 0; + int rc, r; + + switch (obj->type) { + case JSON_NULL: + *jso_out = json_object_new_null(); + return 0; + case JSON_BOOL: + *jso_out = json_object_new_boolean(obj->u.b); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_INTEGER: + *jso_out = json_object_new_int64(obj->u.i); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_DOUBLE: + *jso_out = json_object_new_double(obj->u.d); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_NUMBER: + *jso_out = json_object_new_string(obj->u.string); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_STRING: + *jso_out = json_object_new_string(obj->u.string); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_MAP: { + libxl__json_map_node *node = NULL; + json_object *map_root = json_object_new_object(); + json_object *node_value; + + for (idx = 0; idx < obj->u.map->count; idx++) { + if (flexarray_get(obj->u.map, idx, (void**)&node) != 0) + break; + + rc = libxl__json_object_to_json_object(gc, &node_value, node->obj); + if (rc) { + json_object_put(map_root); + return rc; + } + + r = json_object_object_add(map_root, node->map_key, node_value); + if (r < 0) { + json_object_put(node_value); + json_object_put(map_root); + return ERROR_FAIL; + } + } + *jso_out = map_root; + return 0; + } + case JSON_ARRAY: { + libxl__json_object *node = NULL; + json_object *array_root = json_object_new_array_ext(obj->u.array->count); + json_object *node_value; + + for (idx = 0; idx < obj->u.array->count; idx++) { + if (flexarray_get(obj->u.array, idx, (void**)&node) != 0) + break; + + rc = libxl__json_object_to_json_object(gc, &node_value, node); + if (rc) { + json_object_put(array_root); + return rc; + } + r = json_object_array_add(array_root, node_value); + if (r < 0) { + json_object_put(node_value); + json_object_put(array_root); + return ERROR_FAIL; + } + } + *jso_out = array_root; + return 0; + } + case JSON_ANY: + default: + /* JSON_ANY is not a valid value for obj->type. */ + return ERROR_FAIL; + } +} +#endif +#ifdef HAVE_LIBYAJL yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc, yajl_gen hand, const libxl__json_object *obj) @@ -698,6 +792,7 @@ yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc, abort(); #undef CONVERT_YAJL_GEN_TO_STATUS } +#endif /* diff --git a/tools/libs/light/libxl_qmp.c b/tools/libs/light/libxl_qmp.c index 84740bd4b3..94b6fdb559 100644 --- a/tools/libs/light/libxl_qmp.c +++ b/tools/libs/light/libxl_qmp.c @@ -61,7 +61,11 @@ #include <sys/un.h> +#ifdef HAVE_LIBJSONC +#include <json-c/json.h> +#elif defined(HAVE_LIBYAJL) #include <yajl/yajl_gen.h> +#endif #include "xen_list.h" #include "libxl_internal.h" @@ -481,13 +485,56 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const char *cmd, const libxl__json_object *args, int id) { +#ifdef HAVE_LIBJSONC + json_object *jso = NULL; + json_object *jso_value = NULL; + /* memory for 'buf' is owned by 'jso' */ + const char *buf; + int rc, r; +#elif defined(HAVE_LIBYAJL) yajl_gen hand = NULL; /* memory for 'buf' is owned by 'hand' */ const unsigned char *buf; libxl_yajl_length len; yajl_gen_status s; +#else +# error Missing JSON library +#endif char *ret = NULL; +#ifdef HAVE_LIBJSONC + jso = json_object_new_object(); + if (!jso) + goto out; + + jso_value = json_object_new_string(cmd); + if (!jso_value) + goto out; + r = json_object_object_add(jso, "execute", jso_value); + if (r < 0) + goto out; + jso_value = json_object_new_int(id); + if (!jso_value) + goto out; + r = json_object_object_add(jso, "id", jso_value); + if (r < 0) + goto out; + /* `jso_value` now part of `jso`, shouldn't free it anymore */ + jso_value = NULL; + if (args) { + rc = libxl__json_object_to_json_object(gc, &jso_value, args); + if (rc) + goto out; + r = json_object_object_add(jso, "arguments", jso_value); + if (r < 0) + goto out; + jso_value = NULL; + } + + buf = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PLAIN); + ret = libxl__sprintf(gc, "%s\r\n", buf); + +#elif defined(HAVE_LIBYAJL) hand = libxl_yajl_gen_alloc(NULL); if (!hand) { @@ -516,9 +563,15 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const char *cmd, goto out; ret = libxl__sprintf(gc, "%*.*s\r\n", (int)len, (int)len, buf); +#endif out: +#ifdef HAVE_LIBJSONC + json_object_put(jso_value); + json_object_put(jso); +#elif defined(HAVE_LIBYAJL) yajl_gen_free(hand); +#endif return ret; } -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object 2025-08-08 14:55 ` [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object Anthony PERARD @ 2025-08-27 15:37 ` Jason Andryuk 2025-08-29 13:56 ` Anthony PERARD 0 siblings, 1 reply; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 15:37 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > Convert yajl_gen to json_object from lib json-c. > > And make use of it in qmp_prepare_cmd(), which can be compiled with > either lib. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > --- > diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c > index 44ee6e213f..b26ac901d6 100644 > --- a/tools/libs/light/libxl_json.c > +++ b/tools/libs/light/libxl_json.c > @@ -631,6 +631,100 @@ const libxl__json_object *libxl__json_map_get(const char *key, > return NULL; > } > > +#ifdef HAVE_LIBJSONC > +int libxl__json_object_to_json_object(libxl__gc *gc, > + json_object **jso_out, > + const libxl__json_object *obj) > +{ > + int idx = 0; > + int rc, r; > + > + switch (obj->type) { > + case JSON_NULL: > + *jso_out = json_object_new_null(); > + return 0; > + case JSON_BOOL: > + *jso_out = json_object_new_boolean(obj->u.b); > + if (!*jso_out) > + return ERROR_NOMEM; > + return 0; > + case JSON_INTEGER: > + *jso_out = json_object_new_int64(obj->u.i); > + if (!*jso_out) > + return ERROR_NOMEM; > + return 0; > + case JSON_DOUBLE: > + *jso_out = json_object_new_double(obj->u.d); > + if (!*jso_out) > + return ERROR_NOMEM; > + return 0; > + case JSON_NUMBER: > + *jso_out = json_object_new_string(obj->u.string); Is JSON_NUMBER calling json_object_new_string() correct? It looks like the yajl code falls back to a string, so that is okay but surprising. So I just want to double check. If so: Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> Thanks, Jason > + if (!*jso_out) > + return ERROR_NOMEM; > + return 0; ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object 2025-08-27 15:37 ` Jason Andryuk @ 2025-08-29 13:56 ` Anthony PERARD 2025-08-31 14:51 ` Jason Andryuk 0 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-29 13:56 UTC (permalink / raw) To: Jason Andryuk; +Cc: xen-devel, Anthony PERARD, Juergen Gross On Wed, Aug 27, 2025 at 11:37:07AM -0400, Jason Andryuk wrote: > On 2025-08-08 10:55, Anthony PERARD wrote: > > + case JSON_NUMBER: > > + *jso_out = json_object_new_string(obj->u.string); > > Is JSON_NUMBER calling json_object_new_string() correct? It looks like the > yajl code falls back to a string, so that is okay but surprising. Yeah, I think that's correct. :-( maybe not. Even if we have these too comments: In libxl_internal.h, enum libxl__json_node_type: /* number is store in string, it's too big to be a long long or a double */ JSON_NUMBER = (1 << 4), In json_callback_number(): /* If the conversion fail, we just store the original string. */ With yajl, we call yajl_gen_number(), which probably write 2^128 as: 340282366920938463463374607431768211456 but this new json-c generator would write instead: "340282366920938463463374607431768211456" I guess we might be able to replicate the same behavior by using json_object_set_serializer() or json_object_new_double_s() (which use the former). But I don't know if it is worth the effort. I hope we won't have int bigger than 64 bits. And there's probably no tests for JSON_NUMBERs. So I guess first step would be to write a test that have numbers that can't be converted to `long long` and see what happens. Thanks, -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object 2025-08-29 13:56 ` Anthony PERARD @ 2025-08-31 14:51 ` Jason Andryuk 2025-09-29 9:52 ` Anthony PERARD 0 siblings, 1 reply; 34+ messages in thread From: Jason Andryuk @ 2025-08-31 14:51 UTC (permalink / raw) To: Anthony PERARD; +Cc: xen-devel, Anthony PERARD, Juergen Gross On 2025-08-29 09:56, Anthony PERARD wrote: > On Wed, Aug 27, 2025 at 11:37:07AM -0400, Jason Andryuk wrote: >> On 2025-08-08 10:55, Anthony PERARD wrote: >>> + case JSON_NUMBER: >>> + *jso_out = json_object_new_string(obj->u.string); >> >> Is JSON_NUMBER calling json_object_new_string() correct? It looks like the >> yajl code falls back to a string, so that is okay but surprising. > > Yeah, I think that's correct. > :-( maybe not. Even if we have these too comments: > > In libxl_internal.h, enum libxl__json_node_type: > /* number is store in string, it's too big to be a long long or a double */ > JSON_NUMBER = (1 << 4), > > In json_callback_number(): > /* If the conversion fail, we just store the original string. */ > > With yajl, we call yajl_gen_number(), which probably write 2^128 as: > > 340282366920938463463374607431768211456 > > but this new json-c generator would write instead: > > "340282366920938463463374607431768211456" > > I guess we might be able to replicate the same behavior by using > json_object_set_serializer() or json_object_new_double_s() (which use > the former). But I don't know if it is worth the effort. I hope we won't > have int bigger than 64 bits. I didn't check, but I thought uint64_t is the biggest size libxl uses. Regards, Jason ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object 2025-08-31 14:51 ` Jason Andryuk @ 2025-09-29 9:52 ` Anthony PERARD 0 siblings, 0 replies; 34+ messages in thread From: Anthony PERARD @ 2025-09-29 9:52 UTC (permalink / raw) To: Jason Andryuk; +Cc: xen-devel, Anthony PERARD, Juergen Gross On Sun, Aug 31, 2025 at 10:51:53AM -0400, Jason Andryuk wrote: > On 2025-08-29 09:56, Anthony PERARD wrote: > > On Wed, Aug 27, 2025 at 11:37:07AM -0400, Jason Andryuk wrote: > > > On 2025-08-08 10:55, Anthony PERARD wrote: > > > > + case JSON_NUMBER: > > > > + *jso_out = json_object_new_string(obj->u.string); > > > > > > Is JSON_NUMBER calling json_object_new_string() correct? It looks like the > > > yajl code falls back to a string, so that is okay but surprising. > > > > Yeah, I think that's correct. > > :-( maybe not. Even if we have these too comments: > > > > In libxl_internal.h, enum libxl__json_node_type: > > /* number is store in string, it's too big to be a long long or a double */ > > JSON_NUMBER = (1 << 4), > > > > In json_callback_number(): > > /* If the conversion fail, we just store the original string. */ > > > > With yajl, we call yajl_gen_number(), which probably write 2^128 as: > > > > 340282366920938463463374607431768211456 > > > > but this new json-c generator would write instead: > > > > "340282366920938463463374607431768211456" > > > > I guess we might be able to replicate the same behavior by using > > json_object_set_serializer() or json_object_new_double_s() (which use > > the former). But I don't know if it is worth the effort. I hope we won't > > have int bigger than 64 bits. > > I didn't check, but I thought uint64_t is the biggest size libxl uses. Yes, but we also parse json that are produce else where. (could be file saved by libxl, but also json produced by QEMU) Anywhy, I investitaged this a bit, and it's very unlikely that a `JSON_NUMBER` would be created, so it's even less likely that this `case` would happen. But I've change the call to `json_object_new_string` by: /* * Use json_object_new_double_s() to rewrite the number exactly as * we parsed it. When generating the JSON string the value `0` will * be ignored and `obj->u.string` will be written instead. */ *jso_out = json_object_new_double_s(0, obj->u.string); That way, we get the same json blob, with both library. Cheers, -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (5 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 17:51 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object Anthony PERARD ` (4 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> - libxl changes: While doing so, we rename all "*_gen_json" function to "*_gen_jso" as they have different prototype. All the function pointer are been cast to (libxl__gen_json_callback) by "gentypes.py" when generating "*_to_json()" functions. We also introduce a few more "*_gen_jso" functions for "int" and "bool" because we can't use json_object_*() functions from json-c directly like it's done with yajl. To make the generation of _libxl_types*json.[ch] with both YAJL and json-c we add "--libjsonc" to gentypes.py so it can generate functions/types for both. Also introducing "jsonc_json_gen_fn" in the IDL, to be able to point to a different function when using json-c. Also, don't export any of the new *_gen_jso() function, at the cost of having "_hidden" macro in semi-public headers. - xl changes: Also, rework the implementation of printf_info() in `xl` to avoid using libxl_domain_config_gen_json() which isn't available without YAJL. The implementation using "json_object" call libxl_domain_config_to_json() which generate a plain string of JSON, which we parse to add it to our own json; this avoid a dependency on the json library used by libxl. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/include/libxl_json.h | 17 ++ tools/libs/light/Makefile | 2 +- tools/libs/light/gentypes.py | 160 ++++++++++- tools/libs/light/idl.py | 7 +- tools/libs/light/libxl_cpuid.c | 119 ++++++++ tools/libs/light/libxl_internal.h | 16 +- tools/libs/light/libxl_json.c | 316 ++++++++++++++++++++++ tools/libs/light/libxl_types.idl | 7 +- tools/libs/light/libxl_types_internal.idl | 3 +- tools/xl/xl_info.c | 102 ++++++- 10 files changed, 729 insertions(+), 20 deletions(-) diff --git a/tools/include/libxl_json.h b/tools/include/libxl_json.h index e2ef8151f0..c130e88a5e 100644 --- a/tools/include/libxl_json.h +++ b/tools/include/libxl_json.h @@ -28,6 +28,22 @@ #endif #endif +#ifdef HAVE_LIBJSONC +#ifndef _hidden +#define _hidden +#endif +_hidden int libxl__uint64_gen_jso(json_object **jso_r, uint64_t val); +_hidden int libxl_defbool_gen_jso(json_object **jso_r, libxl_defbool *p); +_hidden int libxl_uuid_gen_jso(json_object **jso_r, libxl_uuid *p); +_hidden int libxl_mac_gen_jso(json_object **jso_r, libxl_mac *p); +_hidden int libxl_bitmap_gen_jso(json_object **jso_r, libxl_bitmap *p); +_hidden int libxl_cpuid_policy_list_gen_jso(json_object **jso_r,libxl_cpuid_policy_list *p); +_hidden int libxl_string_list_gen_jso(json_object **jso_r,libxl_string_list *p); +_hidden int libxl_key_value_list_gen_jso(json_object **jso_r, libxl_key_value_list *p); +_hidden int libxl_hwcap_gen_jso(json_object **jso_r, libxl_hwcap *p); +_hidden int libxl_ms_vm_genid_gen_jso(json_object **jso_r, libxl_ms_vm_genid *p); +#endif +#if defined(HAVE_LIBYAJL) yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val); yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *p); yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *p); @@ -40,6 +56,7 @@ yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand, libxl_key_value_list *p); yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, libxl_hwcap *p); yajl_gen_status libxl_ms_vm_genid_gen_json(yajl_gen hand, libxl_ms_vm_genid *p); +#endif #include <_libxl_types_json.h> diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index fa2a338c2b..c59c2cf198 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -227,7 +227,7 @@ testidl.o: $(XEN_INCLUDE)/libxl.h # This exploits the 'multi-target pattern rule' trick. # gentypes.py should be executed only once to make all the targets. _libxl_type%.h _libxl_type%_json.h _libxl_type%_private.h _libxl_type%.c: libxl_type%.idl gentypes.py idl.py - $(PYTHON) gentypes.py libxl_type$(*F).idl __libxl_type$(*F).h __libxl_type$(*F)_private.h \ + $(PYTHON) gentypes.py $(if $(LIBJSONC_LIBS),--libjsonc) libxl_type$(*F).idl __libxl_type$(*F).h __libxl_type$(*F)_private.h \ __libxl_type$(*F)_json.h __libxl_type$(*F).c $(call move-if-changed,__libxl_type$(*F).h,_libxl_type$(*F).h) $(call move-if-changed,__libxl_type$(*F)_private.h,_libxl_type$(*F)_private.h) diff --git a/tools/libs/light/gentypes.py b/tools/libs/light/gentypes.py index 3fe3873242..006bea170a 100644 --- a/tools/libs/light/gentypes.py +++ b/tools/libs/light/gentypes.py @@ -256,6 +256,30 @@ def libxl_C_type_member_init(ty, field): s += "\n" return s +# For json-c gen_jso functions +def libxl_C_type_gen_jso_map_key(f, parent, indent, scope_object, sub_scope_object): + s = "" + if isinstance(f.type, idl.KeyedUnion): + s += "switch (%s) {\n" % (parent + f.type.keyvar.name) + for x in f.type.fields: + v = f.type.keyvar.name + "." + x.name + s += "case %s:\n" % x.enumname + s += " if (json_object_object_add(%s, \"%s\", %s)) {\n" % (scope_object, v, sub_scope_object) + s += " json_object_put(%s);\n" % (sub_scope_object) + s += " goto out;\n" + s += " }\n" + s += " break;\n" + s += "}\n" + else: + s += "if (json_object_object_add(%s, \"%s\", %s)) {\n" % (scope_object, f.name, sub_scope_object) + s += " json_object_put(%s);\n" % (sub_scope_object) + s += " goto out;\n" + s += "}\n" + if s != "": + s = indent + s + return s.replace("\n", "\n%s" % indent).rstrip(indent) + +# For YAJL gen_json functions def libxl_C_type_gen_map_key(f, parent, indent = ""): s = "" if isinstance(f.type, idl.KeyedUnion): @@ -352,6 +376,86 @@ def get_default_expr(f, nparent, fexpr): return "%s" % fexpr +# For json-c gen_json functions +def libxl_C_type_gen_jso(ty, v, indent = " ", parent = None, scope_object = "jso"): + s = "" + if parent is None: + s += "json_object *jso;\n" + s += "int rc;\n" + sub_scope_object = "jso_sub_1" + else: + sub_scope_object = "jso_sub_%d" % (1+int(scope_object.removeprefix("jso_sub_"))) + + if isinstance(ty, idl.Array): + if parent is None: + raise Exception("Array type must have a parent") + s += "{\n" + s += " int i;\n" + s += " %s = json_object_new_array_ext(%s);\n" % (scope_object, parent + ty.lenvar.name) + s += " if (!%s)\n" % (scope_object) + s += " goto out;\n" + s += " for (i=0; i<%s; i++) {\n" % (parent + ty.lenvar.name) + s += " json_object *%s;\n" % (sub_scope_object) + # remove some indent, it's over indented at least in one case libxl_vcpu_sched_params_gen_json + s += libxl_C_type_gen_jso(ty.elem_type, v+"[i]", + indent + " ", parent, sub_scope_object) + s += " if (json_object_array_add(%s, %s)) {\n" % (scope_object, sub_scope_object) + s += " json_object_put(%s);\n" % (sub_scope_object) + s += " goto out;\n" + s += " }\n" + s += " }\n" + s += "}\n" + elif isinstance(ty, idl.Enumeration): + s += "rc = libxl__enum_gen_jso(&%s, %s_to_string(%s));\n" % (scope_object, ty.typename, ty.pass_arg(v, parent is None)) + s += "if (rc)\n" + s += " goto out;\n" + elif isinstance(ty, idl.KeyedUnion): + if parent is None: + raise Exception("KeyedUnion type must have a parent") + s += "switch (%s) {\n" % (parent + ty.keyvar.name) + for f in ty.fields: + (nparent,fexpr) = ty.member(v, f, parent is None) + s += "case %s:\n" % f.enumname + if f.type is not None: + s += libxl_C_type_gen_jso(f.type, fexpr, indent + " ", nparent, scope_object) + else: + s += " %s = json_object_new_object();\n" % (scope_object) + s += " if (!%s)\n" % (scope_object) + s += " goto out;\n" + s += " break;\n" + s += "}\n" + elif isinstance(ty, idl.Struct) and (parent is None or ty.json_gen_fn is None): + s += "%s = json_object_new_object();\n" % (scope_object) + s += "if (!%s)\n" % (scope_object) + s += " goto out;\n" + for f in [f for f in ty.fields if not f.const and not f.type.private]: + (nparent,fexpr) = ty.member(v, f, parent is None) + default_expr = get_default_expr(f, nparent, fexpr) + s += "if (%s) {\n" % default_expr + s += " json_object *%s = NULL;\n" % (sub_scope_object) + s += libxl_C_type_gen_jso(f.type, fexpr, " ", nparent, sub_scope_object) + s += libxl_C_type_gen_jso_map_key(f, nparent, " ", scope_object, sub_scope_object) + + s += "}\n" + + else: + if ty.json_gen_fn is not None: + s += "rc = %s(&%s, %s);\n" % (ty.json_gen_fn, scope_object, ty.pass_arg(v, parent is None)) + s += "if (rc)\n" + s += " goto out;\n" + + if parent is None: + s += "*jso_r = jso;\n" + s += "return 0;\n" + s += "out:\n" + s += "json_object_put(jso);\n" + s += "return ERROR_FAIL;\n" + + if s != "": + s = indent + s + return s.replace("\n", "\n%s" % indent).rstrip(indent) + +# For YAJL gen_json functions def libxl_C_type_gen_json(ty, v, indent = " ", parent = None): s = "" if parent is None: @@ -426,9 +530,9 @@ def libxl_C_type_gen_json(ty, v, indent = " ", parent = None): s = indent + s return s.replace("\n", "\n%s" % indent).rstrip(indent) -def libxl_C_type_to_json(ty, v, indent = " "): +def libxl_C_type_to_json(ty, v, indent = " ", fn_ptr_type="libxl__gen_json_callback", fn_suffix="_gen_json"): s = "" - gen = "(libxl__gen_json_callback)&%s_gen_json" % ty.typename + gen = "(%s)&%s%s" % (fn_ptr_type, ty.typename, fn_suffix) s += "return libxl__object_to_json(ctx, \"%s\", %s, (void *)%s);\n" % (ty.typename, gen, ty.pass_arg(v, passby=idl.PASS_BY_REFERENCE)) if s != "": @@ -589,14 +693,38 @@ def clean_header_define(header_path): if __name__ == '__main__': + opt_libjsonc = False + if len(sys.argv) == 7: + if sys.argv.pop(1) == "--libjsonc": + opt_libjsonc = True if len(sys.argv) != 6: print("Usage: gentypes.py <idl> <header> <header-private> <header-json> <implementation>", file=sys.stderr) sys.exit(1) (_, idlname, header, header_private, header_json, impl) = sys.argv + # Overwrite `json_gen_fn` for standard types + if opt_libjsonc: + idl.bool.json_gen_fn = "libxl__boolean_gen_jso" + idl.size_t.json_gen_fn = "libxl__int_gen_jso" + idl.integer .json_gen_fn = "libxl__int_gen_jso" + idl.uint8.json_gen_fn = "libxl__int_gen_jso" + idl.uint16.json_gen_fn = "libxl__int_gen_jso" + idl.uint32.json_gen_fn = "libxl__int_gen_jso" + idl.uint64.json_gen_fn = "libxl__uint64_gen_jso" + idl.string.json_gen_fn = "libxl__string_gen_jso" + (builtins,types) = idl.parse(idlname) + # Overwrite `json_gen_fn` with `jsonc_json_gen_fn` for types from the IDL + if opt_libjsonc: + for t in builtins: + if t.jsonc_json_gen_fn is not None: + t.json_gen_fn = t.jsonc_json_gen_fn + for t in types: + if t.jsonc_json_gen_fn is not None: + t.json_gen_fn = t.jsonc_json_gen_fn + print("outputting libxl type definitions to %s" % header) f = open(header, "w") @@ -665,7 +793,11 @@ if __name__ == '__main__': """ % (header_json_define, header_json_define, " ".join(sys.argv))) for ty in [ty for ty in types if ty.json_gen_fn is not None]: - f.write("%syajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) + if opt_libjsonc: + # Always hide JSON generators base on json-c + f.write("%sint %s_gen_jso(json_object **jso_r, %s);\n" % ("_hidden ", ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) + else: + f.write("%syajl_gen_status %s_gen_json(yajl_gen hand, %s);\n" % (ty.hidden(), ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) f.write("\n") f.write("""#endif /* %s */\n""" % header_json_define) @@ -769,15 +901,25 @@ if __name__ == '__main__': f.write("\n") for ty in [t for t in types if t.json_gen_fn is not None]: - f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) - f.write("{\n") - f.write(libxl_C_type_gen_json(ty, "p")) - f.write("}\n") - f.write("\n") + if opt_libjsonc: + f.write("int %s_gen_jso(json_object **jso_r, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) + f.write("{\n") + f.write(libxl_C_type_gen_jso(ty, "p")) + f.write("}\n") + f.write("\n") + else: + f.write("yajl_gen_status %s_gen_json(yajl_gen hand, %s)\n" % (ty.typename, ty.make_arg("p", passby=idl.PASS_BY_REFERENCE))) + f.write("{\n") + f.write(libxl_C_type_gen_json(ty, "p")) + f.write("}\n") + f.write("\n") f.write("char *%s_to_json(libxl_ctx *ctx, %s)\n" % (ty.typename, ty.make_arg("p"))) f.write("{\n") - f.write(libxl_C_type_to_json(ty, "p")) + if opt_libjsonc: + f.write(libxl_C_type_to_json(ty, "p", fn_ptr_type="libxl__gen_json_callback", fn_suffix="_gen_jso")) + else: + f.write(libxl_C_type_to_json(ty, "p", fn_ptr_type="libxl__gen_json_callback", fn_suffix="_gen_json")) f.write("}\n") f.write("\n") diff --git a/tools/libs/light/idl.py b/tools/libs/light/idl.py index d7367503b4..61c8e14004 100644 --- a/tools/libs/light/idl.py +++ b/tools/libs/light/idl.py @@ -79,6 +79,7 @@ class Type(object): if self.typename is not None and not self.private: self.json_gen_fn = kwargs.setdefault('json_gen_fn', self.typename + "_gen_json") + self.jsonc_json_gen_fn = kwargs.setdefault('jsonc_json_gen_fn', self.typename + "_gen_jso") self.json_parse_type = kwargs.setdefault('json_parse_type', "JSON_ANY") if self.namespace is not None: self.json_parse_fn = kwargs.setdefault('json_parse_fn', @@ -88,6 +89,7 @@ class Type(object): self.typename + "_parse_json") else: self.json_gen_fn = kwargs.setdefault('json_gen_fn', None) + self.jsonc_json_gen_fn = kwargs.setdefault('jsonc_json_gen_fn', None) self.json_parse_type = kwargs.setdefault('json_parse_type', None) self.json_parse_fn = kwargs.setdefault('json_parse_fn', None) @@ -142,6 +144,7 @@ class Number(Builtin): kwargs.setdefault('copy_fn', None) kwargs.setdefault('signed', False) kwargs.setdefault('json_gen_fn', "yajl_gen_integer") + kwargs.setdefault('jsonc_json_gen_fn', "libxl__int_gen_jso") kwargs.setdefault('json_parse_type', "JSON_INTEGER") # json_parse_fn might be overriden on specific type kwargs.setdefault('json_parse_fn', "libxl__int_parse_json") @@ -290,6 +293,7 @@ void = Builtin("void *", namespace = None) bool = Builtin("bool", namespace = None, copy_fn=None, json_gen_fn = "yajl_gen_bool", + jsonc_json_gen_fn = "libxl__boolean_gen_jso", json_parse_type = "JSON_BOOL", json_parse_fn = "libxl__bool_parse_json", autogenerate_json = False) @@ -301,10 +305,11 @@ integer = Number("int", namespace = None, signed = True) uint8 = UInt(8) uint16 = UInt(16) uint32 = UInt(32) -uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json") +uint64 = UInt(64, json_gen_fn = "libxl__uint64_gen_json", jsonc_json_gen_fn = "libxl__uint64_gen_jso") string = Builtin("char *", namespace = None, copy_fn = "libxl_string_copy", dispose_fn = "free", json_gen_fn = "libxl__string_gen_json", + jsonc_json_gen_fn = "libxl__string_gen_jso", json_parse_type = "JSON_STRING | JSON_NULL", json_parse_fn = "libxl__string_parse_json", autogenerate_json = False, diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c index f738e17b19..8420b2465f 100644 --- a/tools/libs/light/libxl_cpuid.c +++ b/tools/libs/light/libxl_cpuid.c @@ -545,6 +545,124 @@ static const char *policy_names[4] = { "eax", "ebx", "ecx", "edx" }; * } */ +#ifdef HAVE_LIBJSONC +int libxl_cpuid_policy_list_gen_jso(json_object **jso_r, libxl_cpuid_policy_list *pl) +{ + libxl_cpuid_policy_list policy = *pl; + struct xc_xend_cpuid *cpuid; + const struct xc_msr *msr; + json_object *jso_outer; + json_object *jso_array; + int i, j; + int r; + int rc = ERROR_FAIL; + + jso_outer = json_object_new_object(); + if (!jso_outer) goto out; + + jso_array = json_object_new_array(); + if (!jso_array) goto out; + + r = json_object_object_add(jso_outer, "cpuid", jso_array); + if (r < 0) { + json_object_put(jso_array); + goto out; + } + + if (policy == NULL || policy->cpuid == NULL) goto empty; + cpuid = policy->cpuid; + + for (i = 0; cpuid[i].input[0] != XEN_CPUID_INPUT_UNUSED; i++) { + json_object *jso_inner; + jso_inner = json_object_new_object(); + if (!jso_inner) goto out; + + r = json_object_array_add(jso_array, jso_inner); + if (r < 0) { + json_object_put(jso_inner); + goto out; + } + + for (j = 0; j < 2; j++) { + if (cpuid[i].input[j] != XEN_CPUID_INPUT_UNUSED) { + json_object *jso_value = json_object_new_int(cpuid[i].input[j]); + if (!jso_value) goto out; + r = json_object_object_add(jso_inner, input_names[j], jso_value); + if (r < 0) { + json_object_put(jso_value); + goto out; + } + } + } + + for (j = 0; j < 4; j++) { + if (cpuid[i].policy[j] != NULL) { + json_object *jso_value = json_object_new_string_len(cpuid[i].policy[j], 32); + if (!jso_value) goto out; + r = json_object_object_add(jso_inner, policy_names[j], jso_value); + if (r < 0) { + json_object_put(jso_value); + goto out; + } + } + } + } + +empty: + + jso_array = json_object_new_array(); + if (!jso_array) goto out; + + r = json_object_object_add(jso_outer, "msr", jso_array); + if (r < 0) { + json_object_put(jso_array); + goto out; + } + + if (!policy || !policy->msr) goto done; + msr = policy->msr; + + for (i = 0; msr[i].index != XC_MSR_INPUT_UNUSED; i++) { + json_object *jso_inner; + json_object *jso_value; + + jso_inner = json_object_new_object(); + if (!jso_inner) goto out; + + r = json_object_array_add(jso_array, jso_inner); + if (r < 0) { + json_object_put(jso_inner); + goto out; + } + + jso_value = json_object_new_int(msr[i].index); + if (!jso_value) goto out; + r = json_object_object_add(jso_inner, "index", jso_value); + if (r < 0) { + json_object_put(jso_value); + goto out; + } + + jso_value = json_object_new_string_len(msr[i].policy, 64); + if (!jso_value) goto out; + r = json_object_object_add(jso_inner, "policy", jso_value); + if (r < 0) { + json_object_put(jso_value); + goto out; + } + } + +done: + *jso_r = jso_outer; + jso_outer = NULL; + rc = 0; +out: + json_object_put(jso_outer); + return rc; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand, libxl_cpuid_policy_list *pl) { @@ -630,6 +748,7 @@ yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand, out: return s; } +#endif int libxl__cpuid_policy_list_parse_json(libxl__gc *gc, const libxl__json_object *o, diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h index b66aaa779d..0f707e4204 100644 --- a/tools/libs/light/libxl_internal.h +++ b/tools/libs/light/libxl_internal.h @@ -1993,9 +1993,11 @@ _hidden char *libxl__cpupoolid_to_name(libxl__gc *gc, uint32_t poolid); _hidden int libxl__enum_from_string(const libxl_enum_string_table *t, const char *s, int *e) NN(2); -_hidden yajl_gen_status libxl__string_gen_json(yajl_gen hand, const char *p); - +#ifdef HAVE_LIBJSONC +typedef int (*libxl__gen_json_callback)(json_object **jso_r, void *); +#elif defined(HAVE_LIBYAJL) typedef yajl_gen_status (*libxl__gen_json_callback)(yajl_gen hand, void *); +#endif _hidden char *libxl__object_to_json(libxl_ctx *ctx, const char *type, libxl__gen_json_callback gen, void *p); @@ -2084,11 +2086,21 @@ int libxl__recvmsg_fds(libxl__gc *gc, int carrier, void *databuf, size_t datalen, int nfds, int fds[], const char *what); +#ifdef HAVE_LIBJSONC +_hidden int libxl__enum_gen_jso(json_object **jso_r, const char *str); +_hidden int libxl__int_gen_jso(json_object **jso_r, int i); +_hidden int libxl__boolean_gen_jso(json_object **jso_r, bool b); +_hidden int libxl__string_gen_jso(json_object **jso_r, const char *p); +#endif + +#ifdef HAVE_LIBYAJL /* from libxl_json */ #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); +_hidden yajl_gen_status libxl__string_gen_json(yajl_gen hand, const char *p); +#endif typedef enum { JSON_NULL = (1 << 0), diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index b26ac901d6..01944ef94d 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -19,12 +19,16 @@ #ifdef HAVE_LIBJSONC #include <json-c/json.h> #define USE_LIBJSONC_PARSER +#define USE_LIBJSONC_GEN #endif #ifdef HAVE_LIBYAJL # ifndef USE_LIBJSONC_PARSER # define USE_LIBYAJL_PARSER # endif +# ifndef USE_LIBJSONC_GEN +# define USE_LIBYAJL_GEN +# endif #endif @@ -35,7 +39,9 @@ #ifdef USE_LIBYAJL_PARSER #include <yajl/yajl_parse.h> #endif +#ifdef USE_LIBYAJL_GEN #include <yajl/yajl_gen.h> +#endif #include "libxl_internal.h" @@ -103,6 +109,21 @@ yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str) return yajl_gen_string(hand, (const unsigned char *)str, strlen(str)); } +#ifdef HAVE_LIBJSONC +int libxl__enum_gen_jso(json_object **jso_r, const char *str) +{ + if (str) { + *jso_r = json_object_new_string(str); + if (!*jso_r) + return ERROR_FAIL; + } else { + *jso_r = json_object_new_null(); + } + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str) { if (str) @@ -110,15 +131,28 @@ yajl_gen_status libxl__yajl_gen_enum(yajl_gen hand, const char *str) else return yajl_gen_null(hand); } +#endif /* * YAJL generators for builtin libxl types. */ +#ifdef HAVE_LIBJSONC +int libxl_defbool_gen_jso(json_object **jso_r, libxl_defbool *db) +{ + *jso_r = json_object_new_string(libxl_defbool_to_string(*db)); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_defbool_gen_json(yajl_gen hand, libxl_defbool *db) { return libxl__yajl_gen_asciiz(hand, libxl_defbool_to_string(*db)); } +#endif int libxl__defbool_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_defbool *p) @@ -145,6 +179,16 @@ int libxl__defbool_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl__boolean_gen_jso(json_object **jso_r, bool b) +{ + *jso_r = json_object_new_boolean(b); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o, bool *p) { @@ -156,6 +200,19 @@ int libxl__bool_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl_uuid_gen_jso(json_object **jso_r, libxl_uuid *uuid) +{ + char buf[LIBXL_UUID_FMTLEN+1]; + snprintf(buf, sizeof(buf), LIBXL_UUID_FMT, LIBXL_UUID_BYTES((*uuid))); + *jso_r = json_object_new_string_len(buf, LIBXL_UUID_FMTLEN); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, libxl_uuid *uuid) { @@ -163,6 +220,7 @@ yajl_gen_status libxl_uuid_gen_json(yajl_gen hand, snprintf(buf, sizeof(buf), LIBXL_UUID_FMT, LIBXL_UUID_BYTES((*uuid))); return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_UUID_FMTLEN); } +#endif int libxl__uuid_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_uuid *p) @@ -173,6 +231,39 @@ int libxl__uuid_parse_json(libxl__gc *gc, const libxl__json_object *o, return libxl_uuid_from_string(p, o->u.string); } +#ifdef HAVE_LIBJSONC +int libxl_bitmap_gen_jso(json_object **jso_r, libxl_bitmap *bitmap) +{ + json_object *jso; + int i; + int r; + int rc = ERROR_FAIL; + + jso = json_object_new_array(); + if (!jso) goto out; + + libxl_for_each_bit(i, *bitmap) { + if (libxl_bitmap_test(bitmap, i)) { + json_object *jso_value = json_object_new_int(i); + if (!jso_value) goto out; + r = json_object_array_add(jso, jso_value); + if (r) { + json_object_put(jso_value); + goto out; + } + } + } + + *jso_r = jso; + jso = NULL; + rc = 0; +out: + json_object_put(jso); + return rc; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand, libxl_bitmap *bitmap) { @@ -192,6 +283,7 @@ yajl_gen_status libxl_bitmap_gen_json(yajl_gen hand, out: return s; } +#endif int libxl__bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_bitmap *p) @@ -227,6 +319,42 @@ int libxl__bitmap_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl_key_value_list_gen_jso(json_object **jso_r, libxl_key_value_list *pkvl) +{ + libxl_key_value_list kvl = *pkvl; + json_object *jso; + int i; + + jso = json_object_new_object(); + if (!jso) goto out; + + if (!kvl) goto empty; + + for (i = 0; kvl[i] != NULL; i += 2) { + json_object *jso_value; + if (kvl[i + 1]) { + jso_value = json_object_new_string(kvl[i+1]); + if (!jso_value) goto out; + } else { + jso_value = json_object_new_null(); + } + int r = json_object_object_add(jso, kvl[i], jso_value); + if (r) { + json_object_put(jso_value); + goto out; + } + } +empty: + *jso_r = jso; + return 0; +out: + json_object_put(jso); + return ERROR_FAIL; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand, libxl_key_value_list *pkvl) { @@ -253,6 +381,7 @@ yajl_gen_status libxl_key_value_list_gen_json(yajl_gen hand, out: return s; } +#endif int libxl__key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_key_value_list *p) @@ -289,6 +418,39 @@ int libxl__key_value_list_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl_string_list_gen_jso(json_object **jso_r, libxl_string_list *pl) +{ + libxl_string_list l = *pl; + json_object *jso; + int i; + int rc = ERROR_FAIL; + + jso = json_object_new_array(); + if (!jso) goto out; + + if (!l) goto empty; + + for (i = 0; l[i] != NULL; i++) { + json_object *jso_value = json_object_new_string(l[i]); + if (!jso_value) goto out; + int r = json_object_array_add(jso, jso_value); + if (r) { + json_object_put(jso_value); + goto out; + } + } +empty: + *jso_r = jso; + jso = NULL; + rc = 0; +out: + json_object_put(jso); + return rc; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *pl) { libxl_string_list l = *pl; @@ -309,6 +471,7 @@ yajl_gen_status libxl_string_list_gen_json(yajl_gen hand, libxl_string_list *pl) out: return s; } +#endif int libxl__string_list_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_string_list *p) @@ -342,12 +505,26 @@ int libxl__string_list_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl_mac_gen_jso(json_object **jso_r, libxl_mac *mac) +{ + char buf[LIBXL_MAC_FMTLEN+1]; + snprintf(buf, sizeof(buf), LIBXL_MAC_FMT, LIBXL_MAC_BYTES((*mac))); + *jso_r = json_object_new_string_len(buf, LIBXL_MAC_FMTLEN); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_mac_gen_json(yajl_gen hand, libxl_mac *mac) { char buf[LIBXL_MAC_FMTLEN+1]; snprintf(buf, sizeof(buf), LIBXL_MAC_FMT, LIBXL_MAC_BYTES((*mac))); return yajl_gen_string(hand, (const unsigned char *)buf, LIBXL_MAC_FMTLEN); } +#endif int libxl__mac_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_mac *p) @@ -358,6 +535,36 @@ int libxl__mac_parse_json(libxl__gc *gc, const libxl__json_object *o, return libxl__parse_mac(libxl__json_object_get_string(o), *p); } +#ifdef HAVE_LIBJSONC +int libxl_hwcap_gen_jso(json_object **jso_r, libxl_hwcap *p) +{ + json_object *jso; + int i; + int rc = ERROR_FAIL; + + jso = json_object_new_array(); + if (!jso) goto out; + + for(i=0; i<4; i++) { + json_object *jso_value = json_object_new_int((*p)[i]); + if (!jso_value) + goto out; + int r = json_object_array_add(jso, jso_value); + if (r) { + json_object_put(jso_value); + goto out; + } + } + *jso_r = jso; + jso = NULL; + rc = 0; +out: + json_object_put(jso); + return rc; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, libxl_hwcap *p) { @@ -375,6 +582,7 @@ yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, out: return s; } +#endif int libxl__hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_hwcap *p) @@ -397,6 +605,37 @@ int libxl__hwcap_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl_ms_vm_genid_gen_jso(json_object **jso_r, libxl_ms_vm_genid *p) +{ + json_object *jso; + int i; + int rc = ERROR_FAIL; + + jso = json_object_new_array_ext(LIBXL_MS_VM_GENID_LEN); + if (!jso) goto out; + + for (i = 0; i < LIBXL_MS_VM_GENID_LEN; i++) { + json_object *jso_value = json_object_new_int(p->bytes[i]); + if (!jso_value) + goto out; + int r = json_object_array_add(jso, jso_value); + if (r) { + json_object_put(jso_value); + goto out; + } + } + + *jso_r = jso; + jso = NULL; + rc = 0; +out: + json_object_put(jso); + return rc; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl_ms_vm_genid_gen_json(yajl_gen hand, libxl_ms_vm_genid *p) { yajl_gen_status s; @@ -414,6 +653,7 @@ yajl_gen_status libxl_ms_vm_genid_gen_json(yajl_gen hand, libxl_ms_vm_genid *p) return yajl_gen_array_close(hand); } +#endif int libxl__ms_vm_genid_parse_json(libxl__gc *gc, const libxl__json_object *o, libxl_ms_vm_genid *p) @@ -436,6 +676,21 @@ int libxl__ms_vm_genid_parse_json(libxl__gc *gc, const libxl__json_object *o, return 0; } +#ifdef HAVE_LIBJSONC +int libxl__string_gen_jso(json_object **jso_r, const char *p) +{ + if (p) { + *jso_r = json_object_new_string(p); + if (!*jso_r) + return ERROR_FAIL; + } else { + *jso_r = json_object_new_null(); + } + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl__string_gen_json(yajl_gen hand, const char *p) { @@ -444,6 +699,7 @@ yajl_gen_status libxl__string_gen_json(yajl_gen hand, else return yajl_gen_null(hand); } +#endif int libxl__string_parse_json(libxl__gc *gc, const libxl__json_object *o, char **p) @@ -1161,6 +1417,7 @@ libxl__json_object *libxl__json_parse(libxl__gc *gc, const char *s) return NULL; } +#ifdef USE_LIBYAJL_GEN static const char *yajl_gen_status_to_string(yajl_gen_status s) { switch (s) { @@ -1185,7 +1442,43 @@ static const char *yajl_gen_status_to_string(yajl_gen_status s) return "unknown error"; } } +#endif +#ifdef USE_LIBJSONC_GEN +char *libxl__object_to_json(libxl_ctx *ctx, const char *type, + libxl__gen_json_callback gen, void *p) +{ + const char *buf; + char *ret = NULL; + json_object *jso = NULL; + int rc; + + rc = gen(&jso, p); + if (rc) + goto out; + + buf = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY); + if (!buf) + goto out; + ret = strdup((const char *)buf); + +out: + json_object_put(jso); + + if (rc) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to convert %s to JSON representation. ", + type); + } else if (!ret) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "unable to allocate space for to JSON representation of %s", + type); + } + + return ret; +} + +#elif defined(USE_LIBYAJL_GEN) char *libxl__object_to_json(libxl_ctx *ctx, const char *type, libxl__gen_json_callback gen, void *p) { @@ -1224,6 +1517,7 @@ char *libxl__object_to_json(libxl_ctx *ctx, const char *type, return ret; } +#endif char *libxl__json_object_to_json(libxl__gc *gc, const libxl__json_object *args) @@ -1257,6 +1551,17 @@ char *libxl__json_object_to_json(libxl__gc *gc, return ret; } +#ifdef HAVE_LIBJSONC +int libxl__uint64_gen_jso(json_object **jso_r, uint64_t val) +{ + *jso_r = json_object_new_uint64(val); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + +#ifdef HAVE_LIBYAJL yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val) { char *num; @@ -1277,6 +1582,7 @@ yajl_gen_status libxl__uint64_gen_json(yajl_gen hand, uint64_t val) out: return s; } +#endif int libxl__object_from_json(libxl_ctx *ctx, const char *type, libxl__json_parse_callback parse, @@ -1308,6 +1614,16 @@ int libxl__object_from_json(libxl_ctx *ctx, const char *type, return rc; } +#ifdef HAVE_LIBJSONC +int libxl__int_gen_jso(json_object **jso_r, int i) +{ + *jso_r = json_object_new_int(i); + if (!*jso_r) + return ERROR_FAIL; + return 0; +} +#endif + int libxl__int_parse_json(libxl__gc *gc, const libxl__json_object *o, void *p) { diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index a6030a2dbd..caeddbcdc0 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -7,9 +7,9 @@ namespace("libxl_") libxl_defbool = Builtin("defbool", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, copy_fn=None, check_default_fn="libxl__defbool_is_default") -libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__uint32_parse_json", +libxl_domid = Builtin("domid", json_gen_fn = "yajl_gen_integer", jsonc_json_gen_fn = "libxl__uint64_gen_jso", json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER", autogenerate_json = False, copy_fn=None) -libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", json_parse_fn = "libxl__int_parse_json", +libxl_devid = Builtin("devid", json_gen_fn = "yajl_gen_integer", jsonc_json_gen_fn = "libxl__int_gen_jso", json_parse_fn = "libxl__int_parse_json", json_parse_type = "JSON_INTEGER", autogenerate_json = False, signed = True, init_val="-1", copy_fn=None) libxl_uuid = Builtin("uuid", json_parse_type="JSON_STRING", passby=PASS_BY_REFERENCE, check_default_fn="libxl_uuid_is_nil", @@ -37,7 +37,8 @@ libxl_ms_vm_genid = Builtin("ms_vm_genid", passby=PASS_BY_REFERENCE, check_defau # Specific integer types # -MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", json_gen_fn = "libxl__uint64_gen_json") +MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT", + json_gen_fn = "libxl__uint64_gen_json", jsonc_json_gen_fn = "libxl__uint64_gen_jso") # # Constants / Enumerations diff --git a/tools/libs/light/libxl_types_internal.idl b/tools/libs/light/libxl_types_internal.idl index 0425e9b6b0..ab4ee92870 100644 --- a/tools/libs/light/libxl_types_internal.idl +++ b/tools/libs/light/libxl_types_internal.idl @@ -1,7 +1,8 @@ namespace("libxl__") hidden(True) -libxl_domid = Builtin("domid", namespace="libxl_", json_gen_fn = "yajl_gen_integer", +libxl_domid = Builtin("domid", namespace="libxl_", + json_gen_fn = "yajl_gen_integer", jsonc_json_gen_fn = "libxl__uint64_gen_jso", json_parse_fn = "libxl__uint32_parse_json", json_parse_type = "JSON_INTEGER", autogenerate_json = False, copy_fn = None) diff --git a/tools/xl/xl_info.c b/tools/xl/xl_info.c index 3fbc0698b7..18cfd3c217 100644 --- a/tools/xl/xl_info.c +++ b/tools/xl/xl_info.c @@ -60,6 +60,48 @@ static int maybe_printf(const char *fmt, ...) return count; } + +#ifdef HAVE_LIBJSONC +static int printf_info_one_json(json_object **jso_r, int domid, + libxl_domain_config *d_config) +{ + json_object *jso = NULL; + json_object *jso_config = NULL; + enum json_tokener_error error; + char *s = NULL; + int r = EXIT_FAILURE; + + s = libxl_domain_config_to_json(ctx, d_config); + jso_config = json_tokener_parse_verbose(s, &error); + if (!jso_config) { + fprintf(stderr, "fail to parse JSON from libxl_domain_config_to_json(): %s\n", + json_tokener_error_desc(error)); + goto out; + } + + jso = json_object_new_object(); + if (domid != -1) + json_object_object_add(jso, "domid", json_object_new_int(domid)); + else + json_object_object_add(jso, "domid", json_object_new_null()); + + + json_object_object_add(jso, "config", jso_config); + jso_config = NULL; + + *jso_r = jso; + jso = NULL; + r = EXIT_SUCCESS; + +out: + free(s); + json_object_put(jso); + json_object_put(jso_config); + return r; +} + +#elif defined(HAVE_LIBYAJL) + static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid, libxl_domain_config *d_config) { @@ -95,6 +137,7 @@ static yajl_gen_status printf_info_one_json(yajl_gen hand, int domid, out: return s; } +#endif void printf_info(enum output_format output_format, int domid, @@ -103,6 +146,27 @@ void printf_info(enum output_format output_format, if (output_format == OUTPUT_FORMAT_SXP) return printf_info_sexp(domid, d_config, fh); +#ifdef HAVE_LIBJSONC + int r; + const char *buf; + json_object *jso; + + r = printf_info_one_json(&jso, domid, d_config); + if (r) + goto out; + + buf = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY); + if (!buf) + goto out; + + fputs(buf, fh); + +out: + json_object_put(jso); + flush_stream(fh); + return; + +#elif defined(HAVE_LIBYAJL) const char *buf; libxl_yajl_length len = 0; yajl_gen_status s; @@ -132,6 +196,7 @@ void printf_info(enum output_format output_format, "unable to format domain config as JSON (YAJL:%d)\n", s); flush_stream(fh); +#endif } static void output_xeninfo(void) @@ -475,11 +540,20 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) int i, rc; + const char *buf; +#ifdef HAVE_LIBJSONC + json_object *jso = NULL; +#elif defined(HAVE_LIBYAJL) yajl_gen hand = NULL; yajl_gen_status s; - const char *buf; libxl_yajl_length yajl_len = 0; +#endif +#ifdef HAVE_LIBJSONC + if (default_output_format == OUTPUT_FORMAT_JSON) { + jso = json_object_new_array(); + } +#elif defined(HAVE_LIBYAJL) if (default_output_format == OUTPUT_FORMAT_JSON) { hand = libxl_yajl_gen_alloc(NULL); if (!hand) { @@ -492,6 +566,7 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) goto out; } else s = yajl_gen_status_ok; +#endif for (i = 0; i < nb_domain; i++) { libxl_domain_config_init(&d_config); @@ -499,16 +574,32 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) &d_config, NULL); if (rc) continue; - if (default_output_format == OUTPUT_FORMAT_JSON) + if (default_output_format == OUTPUT_FORMAT_JSON) { +#ifdef HAVE_LIBJSONC + json_object *jso_value; + rc = printf_info_one_json(&jso_value, info[i].domid, &d_config); + json_object_array_add(jso, jso_value); +#elif defined(HAVE_LIBYAJL) s = printf_info_one_json(hand, info[i].domid, &d_config); - else +#endif + } else printf_info_sexp(info[i].domid, &d_config, stdout); libxl_domain_config_dispose(&d_config); +#ifdef HAVE_LIBJSONC + if (rc) + goto out; +#elif defined(HAVE_LIBYAJL) if (s != yajl_gen_status_ok) goto out; +#endif } if (default_output_format == OUTPUT_FORMAT_JSON) { +#ifdef HAVE_LIBJSONC + buf = json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PRETTY); + if (!buf) + goto out; +#elif defined(HAVE_LIBYAJL) s = yajl_gen_array_close(hand); if (s != yajl_gen_status_ok) goto out; @@ -516,16 +607,21 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain) s = yajl_gen_get_buf(hand, (const unsigned char **)&buf, &yajl_len); if (s != yajl_gen_status_ok) goto out; +#endif puts(buf); } out: if (default_output_format == OUTPUT_FORMAT_JSON) { +#ifdef HAVE_LIBJSONC + json_object_put(jso); +#elif defined(HAVE_LIBYAJL) yajl_gen_free(hand); if (s != yajl_gen_status_ok) fprintf(stderr, "unable to format domain config as JSON (YAJL:%d)\n", s); +#endif } } -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c 2025-08-08 14:55 ` [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c Anthony PERARD @ 2025-08-27 17:51 ` Jason Andryuk 2025-08-27 17:59 ` Andrew Cooper 0 siblings, 1 reply; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 17:51 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > - libxl changes: > > While doing so, we rename all "*_gen_json" function to "*_gen_jso" as > they have different prototype. All the function pointer are been cast > to (libxl__gen_json_callback) by "gentypes.py" when generating > "*_to_json()" functions. > > We also introduce a few more "*_gen_jso" functions for "int" and > "bool" because we can't use json_object_*() functions from json-c > directly like it's done with yajl. > > To make the generation of _libxl_types*json.[ch] with both YAJL and > json-c we add "--libjsonc" to gentypes.py so it can generate > functions/types for both. > > Also introducing "jsonc_json_gen_fn" in the IDL, to be able to point > to a different function when using json-c. > > Also, don't export any of the new *_gen_jso() function, at the cost of > having "_hidden" macro in semi-public headers. > > - xl changes: > > Also, rework the implementation of printf_info() in `xl` to avoid > using libxl_domain_config_gen_json() which isn't available without > YAJL. The implementation using "json_object" call > libxl_domain_config_to_json() which generate a plain string of JSON, > which we parse to add it to our own json; this avoid a dependency on > the json library used by libxl. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > @@ -358,6 +535,36 @@ int libxl__mac_parse_json(libxl__gc *gc, const libxl__json_object *o, > return libxl__parse_mac(libxl__json_object_get_string(o), *p); > } > > +#ifdef HAVE_LIBJSONC > +int libxl_hwcap_gen_jso(json_object **jso_r, libxl_hwcap *p) > +{ > + json_object *jso; > + int i; > + int rc = ERROR_FAIL; > + > + jso = json_object_new_array(); > + if (!jso) goto out; > + > + for(i=0; i<4; i++) { typedef uint32_t libxl_hwcap[8]; I see this is the same as the yajl implementation, but should this be 8? The remainder looks good: Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> Thanks, Jason > + json_object *jso_value = json_object_new_int((*p)[i]); > + if (!jso_value) > + goto out; > + int r = json_object_array_add(jso, jso_value); > + if (r) { > + json_object_put(jso_value); > + goto out; > + } > + } > + *jso_r = jso; > + jso = NULL; > + rc = 0; > +out: > + json_object_put(jso); > + return rc; > +} > +#endif > + > +#ifdef HAVE_LIBYAJL > yajl_gen_status libxl_hwcap_gen_json(yajl_gen hand, > libxl_hwcap *p) > { ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c 2025-08-27 17:51 ` Jason Andryuk @ 2025-08-27 17:59 ` Andrew Cooper 2025-08-29 15:32 ` Anthony PERARD 0 siblings, 1 reply; 34+ messages in thread From: Andrew Cooper @ 2025-08-27 17:59 UTC (permalink / raw) To: Jason Andryuk, Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 27/08/2025 6:51 pm, Jason Andryuk wrote: > On 2025-08-08 10:55, Anthony PERARD wrote: >> From: Anthony PERARD <anthony.perard@vates.tech> >> >> - libxl changes: >> >> While doing so, we rename all "*_gen_json" function to "*_gen_jso" as >> they have different prototype. All the function pointer are been cast >> to (libxl__gen_json_callback) by "gentypes.py" when generating >> "*_to_json()" functions. >> >> We also introduce a few more "*_gen_jso" functions for "int" and >> "bool" because we can't use json_object_*() functions from json-c >> directly like it's done with yajl. >> >> To make the generation of _libxl_types*json.[ch] with both YAJL and >> json-c we add "--libjsonc" to gentypes.py so it can generate >> functions/types for both. >> >> Also introducing "jsonc_json_gen_fn" in the IDL, to be able to point >> to a different function when using json-c. >> >> Also, don't export any of the new *_gen_jso() function, at the cost of >> having "_hidden" macro in semi-public headers. >> >> - xl changes: >> >> Also, rework the implementation of printf_info() in `xl` to avoid >> using libxl_domain_config_gen_json() which isn't available without >> YAJL. The implementation using "json_object" call >> libxl_domain_config_to_json() which generate a plain string of JSON, >> which we parse to add it to our own json; this avoid a dependency on >> the json library used by libxl. >> >> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > >> @@ -358,6 +535,36 @@ int libxl__mac_parse_json(libxl__gc *gc, const >> libxl__json_object *o, >> return libxl__parse_mac(libxl__json_object_get_string(o), *p); >> } >> +#ifdef HAVE_LIBJSONC >> +int libxl_hwcap_gen_jso(json_object **jso_r, libxl_hwcap *p) >> +{ >> + json_object *jso; >> + int i; >> + int rc = ERROR_FAIL; >> + >> + jso = json_object_new_array(); >> + if (!jso) goto out; >> + >> + for(i=0; i<4; i++) { > > typedef uint32_t libxl_hwcap[8]; > > I see this is the same as the yajl implementation, but should this be 8? > > The remainder looks good: > > Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> A tangent, but physinfo.hw_cap (which libxl_hwcap wraps) is as good as stack rubble. It's not exactly random data, but it is a view of an internal Xen structure which has been reformatted multiple times before we even realised it was exported, then continued being reformatting it because it's a gross laying violation that noone could possibly be using anyway. It needs purging from libxl and the sysctl interface, and if that makes JSON easier, then lets get it done. ~Andrew ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c 2025-08-27 17:59 ` Andrew Cooper @ 2025-08-29 15:32 ` Anthony PERARD 0 siblings, 0 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-29 15:32 UTC (permalink / raw) To: Andrew Cooper; +Cc: Jason Andryuk, xen-devel, Anthony PERARD, Juergen Gross On Wed, Aug 27, 2025 at 06:59:14PM +0100, Andrew Cooper wrote: > On 27/08/2025 6:51 pm, Jason Andryuk wrote: > > On 2025-08-08 10:55, Anthony PERARD wrote: > >> From: Anthony PERARD <anthony.perard@vates.tech> > >> > >> - libxl changes: > >> > >> While doing so, we rename all "*_gen_json" function to "*_gen_jso" as > >> they have different prototype. All the function pointer are been cast > >> to (libxl__gen_json_callback) by "gentypes.py" when generating > >> "*_to_json()" functions. > >> > >> We also introduce a few more "*_gen_jso" functions for "int" and > >> "bool" because we can't use json_object_*() functions from json-c > >> directly like it's done with yajl. > >> > >> To make the generation of _libxl_types*json.[ch] with both YAJL and > >> json-c we add "--libjsonc" to gentypes.py so it can generate > >> functions/types for both. > >> > >> Also introducing "jsonc_json_gen_fn" in the IDL, to be able to point > >> to a different function when using json-c. > >> > >> Also, don't export any of the new *_gen_jso() function, at the cost of > >> having "_hidden" macro in semi-public headers. > >> > >> - xl changes: > >> > >> Also, rework the implementation of printf_info() in `xl` to avoid > >> using libxl_domain_config_gen_json() which isn't available without > >> YAJL. The implementation using "json_object" call > >> libxl_domain_config_to_json() which generate a plain string of JSON, > >> which we parse to add it to our own json; this avoid a dependency on > >> the json library used by libxl. > >> > >> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > > > >> @@ -358,6 +535,36 @@ int libxl__mac_parse_json(libxl__gc *gc, const > >> libxl__json_object *o, > >> return libxl__parse_mac(libxl__json_object_get_string(o), *p); > >> } > >> +#ifdef HAVE_LIBJSONC > >> +int libxl_hwcap_gen_jso(json_object **jso_r, libxl_hwcap *p) > >> +{ > >> + json_object *jso; > >> + int i; > >> + int rc = ERROR_FAIL; > >> + > >> + jso = json_object_new_array(); > >> + if (!jso) goto out; > >> + > >> + for(i=0; i<4; i++) { > > > > typedef uint32_t libxl_hwcap[8]; > > > > I see this is the same as the yajl implementation, but should this be 8? Yeah, looks like it should be ARRAY_SIZE(p). But that would want fixing in a different patch. And since no one complained about missing bits in this json conversion, I guess it's not used. We would need to also fix libxl__hwcap_parse_json(), to parse up to 8 items, and be able to deal with missing 4 of them. > > > > The remainder looks good: > > > > Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> > > A tangent, but physinfo.hw_cap (which libxl_hwcap wraps) is as good as > stack rubble. It's not exactly random data, but it is a view of an > internal Xen structure which has been reformatted multiple times before > we even realised it was exported, then continued being reformatting it > because it's a gross laying violation that noone could possibly be using > anyway. It's display in `xl info`, surely it's useful for someone :-), a long long time ago since it seems to be inherited from `xm info`. > It needs purging from libxl and the sysctl interface, and if that makes > JSON easier, then lets get it done. It would be more work, not less. Removing things from libxl's api is annoying. But I guess we can look at removing that later. Cheers, -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (6 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c Anthony PERARD @ 2025-08-08 14:55 ` Anthony PERARD 2025-08-27 17:54 ` Jason Andryuk 2025-08-08 14:56 ` [XEN PATCH 09/11] tools/libxenstat: Use json-c when available Anthony PERARD ` (3 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:55 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> But keep the implementation done for YAJL. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/libs/light/libxl_json.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index 01944ef94d..cffda158d2 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -104,10 +104,12 @@ typedef struct libxl__yajl_ctx { * YAJL Helper */ +#ifdef HAVE_LIBYAJL yajl_gen_status libxl__yajl_gen_asciiz(yajl_gen hand, const char *str) { return yajl_gen_string(hand, (const unsigned char *)str, strlen(str)); } +#endif #ifdef HAVE_LIBJSONC int libxl__enum_gen_jso(json_object **jso_r, const char *str) @@ -1522,6 +1524,29 @@ char *libxl__object_to_json(libxl_ctx *ctx, const char *type, char *libxl__json_object_to_json(libxl__gc *gc, const libxl__json_object *args) { +#ifdef HAVE_LIBJSONC + const char *buf; + json_object *root; + char *ret = NULL; + int rc; + + if (!args) + return NULL; + + rc = libxl__json_object_to_json_object(gc, &root, args); + if (rc) + goto out; + + buf = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY); + if (!buf) + goto out; + + ret = libxl__strdup(gc, buf); + +out: + json_object_put(root); + return ret; +#elif defined(HAVE_LIBYAJL) const unsigned char *buf; libxl_yajl_length len; yajl_gen_status s; @@ -1549,6 +1574,7 @@ char *libxl__json_object_to_json(libxl__gc *gc, out: yajl_gen_free(hand); return ret; +#endif } #ifdef HAVE_LIBJSONC -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object 2025-08-08 14:55 ` [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object Anthony PERARD @ 2025-08-27 17:54 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 17:54 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:55, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > But keep the implementation done for YAJL. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 09/11] tools/libxenstat: Use json-c when available 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (7 preceding siblings ...) 2025-08-08 14:55 ` [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object Anthony PERARD @ 2025-08-08 14:56 ` Anthony PERARD 2025-08-27 18:00 ` Jason Andryuk 2025-08-08 14:56 ` [XEN PATCH 10/11] configure: Use json-c by default, fallback to yajl Anthony PERARD ` (2 subsequent siblings) 11 siblings, 1 reply; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:56 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD, Juergen Gross From: Anthony PERARD <anthony.perard@vates.tech> This is mainly a copy of the existing code in yajl and use json-c instead. Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/libs/stat/Makefile | 3 +- tools/libs/stat/xenstat_qmp.c | 126 ++++++++++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 8 deletions(-) diff --git a/tools/libs/stat/Makefile b/tools/libs/stat/Makefile index a968eaff48..3f13cf07be 100644 --- a/tools/libs/stat/Makefile +++ b/tools/libs/stat/Makefile @@ -24,7 +24,8 @@ OBJS-$(CONFIG_SunOS) += xenstat_solaris.o OBJS-$(CONFIG_NetBSD) += xenstat_netbsd.o OBJS-$(CONFIG_FreeBSD) += xenstat_freebsd.o -LDLIBS-y += -lyajl +LDLIBS-y += $(YAJL_LIBS) +LDLIBS-y += $(LIBJSONC_LIBS) LDLIBS-$(CONFIG_SunOS) += -lkstat LDLIBS += $(LDLIBS-y) diff --git a/tools/libs/stat/xenstat_qmp.c b/tools/libs/stat/xenstat_qmp.c index 9909b9727e..21e321fffa 100644 --- a/tools/libs/stat/xenstat_qmp.c +++ b/tools/libs/stat/xenstat_qmp.c @@ -24,6 +24,10 @@ #include "xenstat_priv.h" +#ifdef HAVE_LIBJSONC +#include <json-c/json.h> + +#elif defined(HAVE_LIBYAJL) #ifdef HAVE_YAJL_YAJL_VERSION_H # include <yajl/yajl_version.h> #endif @@ -32,11 +36,13 @@ #if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1) # define HAVE_YAJL_V2 1 #endif +#endif #ifdef HAVE_YAJL_V2 - #include <yajl/yajl_tree.h> +#endif +#if defined(HAVE_LIBJSONC) || defined(HAVE_YAJL_V2) static unsigned char *qmp_query(int, const char *); enum query_blockstats { @@ -76,9 +82,10 @@ enum query_block { "type": 'str' }]} */ -static char *qmp_get_block_image(xenstat_node *node, char *qmp_devname, int qfd) +static char *qmp_get_block_image(xenstat_node *node, const char *qmp_devname, int qfd) { - char *tmp, *file = NULL; + const char *tmp; + char *file = NULL; const char *query_block_cmd = "{ \"execute\": \"query-block\" }"; static const char *const qblock[] = { [ QMP_BLOCK_RETURN ] = "return", @@ -88,13 +95,56 @@ static char *qmp_get_block_image(xenstat_node *node, char *qmp_devname, int qfd) }; const char *ptr[] = {0, 0}; unsigned char *qmp_stats; - yajl_val info, ret_obj, dev_obj, n; int i; if ((qmp_stats = qmp_query(qfd, query_block_cmd)) == NULL) return NULL; +#ifdef HAVE_LIBJSONC + json_object *jso; + enum json_tokener_error error; + jso = json_tokener_parse_verbose((const char *)qmp_stats, &error); + free(qmp_stats); + if (jso == NULL) + return NULL; + + ptr[0] = qblock[QMP_BLOCK_RETURN]; /* "return" */ + json_object *ret_jso = json_object_object_get(jso, ptr[0]); + if (ret_jso == NULL) + goto done; + + for (i=0; i<json_object_array_length(ret_jso); i++) { + json_object *n = json_object_array_get_idx(ret_jso, i); + + ptr[0] = qblock[QMP_BLOCK_DEVICE]; /* "device" */ + json_object *dev_jso = json_object_object_get(n, ptr[0]); + if (dev_jso) { + tmp = json_object_get_string(dev_jso); + if (!tmp || strcmp(qmp_devname, tmp)) + continue; + } else { + continue; + } + + ptr[0] = qblock[QMP_INSERTED]; /* "inserted" */ + n = json_object_object_get(n, ptr[0]); + if (n) { + ptr[0] = qblock[QMP_FILE]; /* "file" */ + n = json_object_object_get(n, ptr[0]); + if (n && json_object_is_type(n, json_type_string)) { + tmp = json_object_get_string(n); + file = malloc(strlen(tmp)+1); + if (file != NULL) + strcpy(file, tmp); + goto done; + } + } + } +done: + json_object_put(jso); +#elif defined(HAVE_LIBYAJL) /* Use libyajl version 2.0.3 or newer for the tree parser feature with bug fixes */ + yajl_val info, ret_obj, dev_obj, n; info = yajl_tree_parse((char *)qmp_stats, NULL, 0); free(qmp_stats); if (info == NULL) @@ -132,12 +182,13 @@ static char *qmp_get_block_image(xenstat_node *node, char *qmp_devname, int qfd) } done: yajl_tree_free(info); +#endif return file; } /* Given a QMP device name, lookup the associated xenstore qdisk device id */ -static void lookup_xenstore_devid(xenstat_node * node, unsigned int domid, char *qmp_devname, +static void lookup_xenstore_devid(xenstat_node * node, unsigned int domid, const char *qmp_devname, int qfd, unsigned int *dev, unsigned int *sector_size) { char **dev_ids, *tmp, *ptr, *image, path[80]; @@ -191,7 +242,7 @@ static void lookup_xenstore_devid(xenstat_node * node, unsigned int domid, char /* Parse the stats buffer which contains I/O data for all the disks belonging to domid */ static void qmp_parse_stats(xenstat_node *node, unsigned int domid, unsigned char *stats_buf, int qfd) { - char *qmp_devname; + const char *qmp_devname; static const char *const qstats[] = { [ QMP_STATS_RETURN ] = "return", [ QMP_STATS_DEVICE ] = "device", @@ -202,12 +253,72 @@ static void qmp_parse_stats(xenstat_node *node, unsigned int domid, unsigned cha [ QMP_WR_OPERATIONS ] = "wr_operations", }; const char *ptr[] = {0, 0}; - yajl_val info, ret_obj, stats_obj, n; xenstat_vbd vbd; xenstat_domain *domain; unsigned int sector_size = 512; int i, j; +#ifdef HAVE_LIBJSONC + json_object *jso, *ret_jso, *stats_obj, *n; + enum json_tokener_error error; + + jso = json_tokener_parse_verbose((const char *)stats_buf, &error); + if (jso == NULL) + return; + + ptr[0] = qstats[QMP_STATS_RETURN]; /* "return" */ + ret_jso = json_object_object_get(jso, ptr[0]); + if (ret_jso == NULL) + goto done; + + /* Array of devices */ + for (i=0; i<json_object_array_length(ret_jso); i++) { + memset(&vbd, 0, sizeof(xenstat_vbd)); + qmp_devname = NULL; + stats_obj = json_object_array_get_idx(ret_jso, i); + + ptr[0] = qstats[QMP_STATS_DEVICE]; /* "device" */ + n = json_object_object_get(stats_obj, ptr[0]); + if (n) + qmp_devname = json_object_get_string(n); + + ptr[0] = qstats[QMP_STATS]; /* "stats" */ + stats_obj = json_object_object_get(stats_obj, ptr[0]); + if (stats_obj && json_object_is_type(stats_obj, json_type_object)) { + for (j=3; j<7; j++) { + ptr[0] = qstats[j]; + n = json_object_object_get(stats_obj, ptr[0]); + if (n && json_object_is_type(n, json_type_int)) { + switch(j) { + case QMP_RD_BYTES: /* "rd_bytes" */ + vbd.rd_sects = json_object_get_int64(n) / sector_size; + break; + case QMP_WR_BYTES: /* "wr_bytes" */ + vbd.wr_sects = json_object_get_int64(n) / sector_size; + break; + case QMP_RD_OPERATIONS: /* "rd_operations" */ + vbd.rd_reqs = json_object_get_int64(n); + break; + case QMP_WR_OPERATIONS: /* "wr_operations" */ + vbd.wr_reqs = json_object_get_int64(n); + break; + } + } + } + /* With the QMP device name, lookup the xenstore qdisk device ID and set vdb.dev */ + if (qmp_devname) + lookup_xenstore_devid(node, domid, qmp_devname, qfd, &vbd.dev, §or_size); + if ((domain = xenstat_node_domain(node, domid)) == NULL) + continue; + if ((xenstat_save_vbd(domain, &vbd)) == NULL) + goto done; + } + } +done: + json_object_put(jso); +#elif defined(HAVE_LIBYAJL) + yajl_val info, ret_obj, stats_obj, n; + /* Use libyajl version 2.0.3 or newer for the tree parser feature */ if ((info = yajl_tree_parse((char *)stats_buf, NULL, 0)) == NULL) return; @@ -260,6 +371,7 @@ static void qmp_parse_stats(xenstat_node *node, unsigned int domid, unsigned cha } done: yajl_tree_free(info); +#endif } /* Write a command via the QMP. Returns number of bytes written */ -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 09/11] tools/libxenstat: Use json-c when available 2025-08-08 14:56 ` [XEN PATCH 09/11] tools/libxenstat: Use json-c when available Anthony PERARD @ 2025-08-27 18:00 ` Jason Andryuk 0 siblings, 0 replies; 34+ messages in thread From: Jason Andryuk @ 2025-08-27 18:00 UTC (permalink / raw) To: Anthony PERARD, xen-devel; +Cc: Anthony PERARD, Juergen Gross On 2025-08-08 10:56, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > This is mainly a copy of the existing code in yajl and use json-c > instead. > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com> ^ permalink raw reply [flat|nested] 34+ messages in thread
* [XEN PATCH 10/11] configure: Use json-c by default, fallback to yajl 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (8 preceding siblings ...) 2025-08-08 14:56 ` [XEN PATCH 09/11] tools/libxenstat: Use json-c when available Anthony PERARD @ 2025-08-08 14:56 ` Anthony PERARD 2025-08-08 14:56 ` [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c Anthony PERARD 2025-08-08 15:14 ` [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Andrew Cooper 11 siblings, 0 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:56 UTC (permalink / raw) To: xen-devel; +Cc: Anthony PERARD From: Anthony PERARD <anthony.perard@vates.tech> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- tools/configure | 97 +++++++++++++++++++++++++++++----------------- tools/configure.ac | 12 +++--- 2 files changed, 69 insertions(+), 40 deletions(-) diff --git a/tools/configure b/tools/configure index edd1701b2d..0eb7a0ab6a 100755 --- a/tools/configure +++ b/tools/configure @@ -9692,41 +9692,7 @@ fi # Put the nasty error message in config.log where it belongs echo "$libjsonc_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (json-c) were not met: - -$libjsonc_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -Alternatively, you may set the environment variables libjsonc_CFLAGS -and libjsonc_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details." "$LINENO" 5 -elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -Alternatively, you may set the environment variables libjsonc_CFLAGS -and libjsonc_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details. - -To get pkg-config, see <http://pkg-config.freedesktop.org/>. -See \`config.log' for more details" "$LINENO" 5; } -else - libjsonc_CFLAGS=$pkg_cv_libjsonc_CFLAGS - libjsonc_LIBS=$pkg_cv_libjsonc_LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define HAVE_LIBJSONC 1" >>confdefs.h - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for yajl_alloc in -lyajl" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for yajl_alloc in -lyajl" >&5 printf %s "checking for yajl_alloc in -lyajl... " >&6; } if test ${ac_cv_lib_yajl_yajl_alloc+y} then : @@ -9772,6 +9738,67 @@ else $as_nop as_fn_error $? "Could not find yajl" "$LINENO" 5 fi + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for yajl_alloc in -lyajl" >&5 +printf %s "checking for yajl_alloc in -lyajl... " >&6; } +if test ${ac_cv_lib_yajl_yajl_alloc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lyajl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char yajl_alloc (); +int +main (void) +{ +return yajl_alloc (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_yajl_yajl_alloc=yes +else $as_nop + ac_cv_lib_yajl_yajl_alloc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_yajl_yajl_alloc" >&5 +printf "%s\n" "$ac_cv_lib_yajl_yajl_alloc" >&6; } +if test "x$ac_cv_lib_yajl_yajl_alloc" = xyes +then : + YAJL_LIBS=-lyajl + + +printf "%s\n" "#define HAVE_LIBYAJL 1" >>confdefs.h + +else $as_nop + as_fn_error $? "Could not find yajl" "$LINENO" 5 +fi + + +else + libjsonc_CFLAGS=$pkg_cv_libjsonc_CFLAGS + libjsonc_LIBS=$pkg_cv_libjsonc_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_LIBJSONC 1" >>confdefs.h + +fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for deflateCopy in -lz" >&5 printf %s "checking for deflateCopy in -lz... " >&6; } if test ${ac_cv_lib_z_deflateCopy+y} diff --git a/tools/configure.ac b/tools/configure.ac index bb40b5b3f0..7267d02a04 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -425,11 +425,13 @@ AC_SUBST([ZLIB_LIBS]) AX_CHECK_EXTFS AX_CHECK_PTHREAD PKG_CHECK_MODULES([libjsonc], [json-c], - [AC_DEFINE([HAVE_LIBJSONC], [1], [Use library json-c])]) -AC_CHECK_LIB([yajl], [yajl_alloc], - [AC_SUBST([YAJL_LIBS],[-lyajl]) - AC_DEFINE([HAVE_LIBYAJL],[1],[Define to 1 if you have the `yajl' library (-lyajl).])], - [AC_MSG_ERROR([Could not find yajl])]) + [AC_DEFINE([HAVE_LIBJSONC], [1], [Use library json-c])], + [AC_CHECK_LIB([yajl], [yajl_alloc], + [AC_SUBST([YAJL_LIBS],[-lyajl]) + AC_DEFINE([HAVE_LIBYAJL],[1],[Define to 1 if you have the `yajl' library (-lyajl).])], + [AC_MSG_ERROR([Could not find yajl])]) +]) + AC_CHECK_LIB([z], [deflateCopy], [], [AC_MSG_ERROR([Could not find zlib])]) AC_CHECK_HEADER([argp.h], [ AC_CHECK_LIB([argp], [argp_usage], [argp_ldflags="-largp"]) -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (9 preceding siblings ...) 2025-08-08 14:56 ` [XEN PATCH 10/11] configure: Use json-c by default, fallback to yajl Anthony PERARD @ 2025-08-08 14:56 ` Anthony PERARD 2025-08-11 8:27 ` Oleksii Kurochko 2025-08-11 10:55 ` Andrew Cooper 2025-08-08 15:14 ` [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Andrew Cooper 11 siblings, 2 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-08 14:56 UTC (permalink / raw) To: xen-devel Cc: Anthony PERARD, Oleksii Kurochko, Community Manager, Andrew Cooper, Michal Orzel, Jan Beulich, Julien Grall, Roger Pau Monné, Stefano Stabellini From: Anthony PERARD <anthony.perard@vates.tech> Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> --- CHANGELOG.md | 2 ++ README | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f31ca08fe..83195e2dae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - For x86, GCC 5.1 and Binutils 2.25, or Clang/LLVM 11 - For ARM32 and ARM64, GCC 5.1 and Binutils 2.25 - Linux based device model stubdomains are now fully supported. + - New dependency on library json-c, the toolstack will prefer it to `YAJL` + when available. - On x86: - Restrict the cache flushing done as a result of guest physical memory map diff --git a/README b/README index 6ee58f7b35..9329f30e13 100644 --- a/README +++ b/README @@ -53,7 +53,7 @@ provided by your OS distributor: * Development install of Python 2.7 or later (e.g., python-dev) * Development install of curses (e.g., libncurses-dev) * Development install of uuid (e.g. uuid-dev) - * Development install of yajl (e.g. libyajl-dev) + * Development install of json-c (e.g. libjson-c-dev) or yajl (e.g. libyajl-dev) * Development install of libaio (e.g. libaio-dev) version 0.3.107 or greater. * Development install of GLib v2.0 (e.g. libglib2.0-dev) -- Anthony PERARD ^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c 2025-08-08 14:56 ` [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c Anthony PERARD @ 2025-08-11 8:27 ` Oleksii Kurochko 2025-08-11 10:55 ` Andrew Cooper 1 sibling, 0 replies; 34+ messages in thread From: Oleksii Kurochko @ 2025-08-11 8:27 UTC (permalink / raw) To: Anthony PERARD, xen-devel Cc: Anthony PERARD, Community Manager, Andrew Cooper, Michal Orzel, Jan Beulich, Julien Grall, Roger Pau Monné, Stefano Stabellini [-- Attachment #1: Type: text/plain, Size: 1775 bytes --] On 8/8/25 4:56 PM, Anthony PERARD wrote: > From: Anthony PERARD<anthony.perard@vates.tech> > > Signed-off-by: Anthony PERARD<anthony.perard@vates.tech> LGTM: Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail> With one question ... > --- > CHANGELOG.md | 2 ++ > README | 2 +- > 2 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/CHANGELOG.md b/CHANGELOG.md > index 5f31ca08fe..83195e2dae 100644 > --- a/CHANGELOG.md > +++ b/CHANGELOG.md > @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) > - For x86, GCC 5.1 and Binutils 2.25, or Clang/LLVM 11 > - For ARM32 and ARM64, GCC 5.1 and Binutils 2.25 > - Linux based device model stubdomains are now fully supported. > + - New dependency on library json-c, the toolstack will prefer it to `YAJL` > + when available. > > - On x86: > - Restrict the cache flushing done as a result of guest physical memory map > diff --git a/README b/README > index 6ee58f7b35..9329f30e13 100644 > --- a/README > +++ b/README > @@ -53,7 +53,7 @@ provided by your OS distributor: > * Development install of Python 2.7 or later (e.g., python-dev) > * Development install of curses (e.g., libncurses-dev) > * Development install of uuid (e.g. uuid-dev) > - * Development install of yajl (e.g. libyajl-dev) > + * Development install of json-c (e.g. libjson-c-dev) or yajl (e.g. libyajl-dev) ... as you mentioned in the cover letter libyajl-dev is unmaintained for several years. Do any plans exist to drop libyajl-dev at all? Can't it be dropped now? ~ Oleksii > * Development install of libaio (e.g. libaio-dev) version 0.3.107 or > greater. > * Development install of GLib v2.0 (e.g. libglib2.0-dev) [-- Attachment #2: Type: text/html, Size: 2690 bytes --] ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c 2025-08-08 14:56 ` [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c Anthony PERARD 2025-08-11 8:27 ` Oleksii Kurochko @ 2025-08-11 10:55 ` Andrew Cooper 2025-08-11 14:37 ` Anthony PERARD 1 sibling, 1 reply; 34+ messages in thread From: Andrew Cooper @ 2025-08-11 10:55 UTC (permalink / raw) To: Anthony PERARD, xen-devel Cc: Anthony PERARD, Oleksii Kurochko, Community Manager, Michal Orzel, Jan Beulich, Julien Grall, Roger Pau Monné, Stefano Stabellini On 08/08/2025 3:56 pm, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > --- > CHANGELOG.md | 2 ++ > README | 2 +- > 2 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/CHANGELOG.md b/CHANGELOG.md > index 5f31ca08fe..83195e2dae 100644 > --- a/CHANGELOG.md > +++ b/CHANGELOG.md > @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) > - For x86, GCC 5.1 and Binutils 2.25, or Clang/LLVM 11 > - For ARM32 and ARM64, GCC 5.1 and Binutils 2.25 > - Linux based device model stubdomains are now fully supported. > + - New dependency on library json-c, the toolstack will prefer it to `YAJL` > + when available. > > - On x86: > - Restrict the cache flushing done as a result of guest physical memory map > diff --git a/README b/README > index 6ee58f7b35..9329f30e13 100644 > --- a/README > +++ b/README > @@ -53,7 +53,7 @@ provided by your OS distributor: > * Development install of Python 2.7 or later (e.g., python-dev) > * Development install of curses (e.g., libncurses-dev) > * Development install of uuid (e.g. uuid-dev) > - * Development install of yajl (e.g. libyajl-dev) > + * Development install of json-c (e.g. libjson-c-dev) or yajl (e.g. libyajl-dev) > * Development install of libaio (e.g. libaio-dev) version 0.3.107 or > greater. > * Development install of GLib v2.0 (e.g. libglib2.0-dev) What are we going to do about testing this? We should add libjson-c to some build containers. We need to annotate # Xen < 4.21 in the existing containers so we can drop it in due course. Also, for a container we don't intend to backport to stable trees, we should have libjson-c only and no yajl. Probably best to do this in the Alpine update which is long overdue. ~Andrew ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c 2025-08-11 10:55 ` Andrew Cooper @ 2025-08-11 14:37 ` Anthony PERARD 0 siblings, 0 replies; 34+ messages in thread From: Anthony PERARD @ 2025-08-11 14:37 UTC (permalink / raw) To: Andrew Cooper Cc: xen-devel, Anthony PERARD, Oleksii Kurochko, Community Manager, Michal Orzel, Jan Beulich, Julien Grall, Roger Pau Monné, Stefano Stabellini On Mon, Aug 11, 2025 at 11:55:04AM +0100, Andrew Cooper wrote: > On 08/08/2025 3:56 pm, Anthony PERARD wrote: > > From: Anthony PERARD <anthony.perard@vates.tech> > > > > Signed-off-by: Anthony PERARD <anthony.perard@vates.tech> > > --- > > CHANGELOG.md | 2 ++ > > README | 2 +- > > 2 files changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/CHANGELOG.md b/CHANGELOG.md > > index 5f31ca08fe..83195e2dae 100644 > > --- a/CHANGELOG.md > > +++ b/CHANGELOG.md > > @@ -11,6 +11,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) > > - For x86, GCC 5.1 and Binutils 2.25, or Clang/LLVM 11 > > - For ARM32 and ARM64, GCC 5.1 and Binutils 2.25 > > - Linux based device model stubdomains are now fully supported. > > + - New dependency on library json-c, the toolstack will prefer it to `YAJL` > > + when available. > > > > - On x86: > > - Restrict the cache flushing done as a result of guest physical memory map > > diff --git a/README b/README > > index 6ee58f7b35..9329f30e13 100644 > > --- a/README > > +++ b/README > > @@ -53,7 +53,7 @@ provided by your OS distributor: > > * Development install of Python 2.7 or later (e.g., python-dev) > > * Development install of curses (e.g., libncurses-dev) > > * Development install of uuid (e.g. uuid-dev) > > - * Development install of yajl (e.g. libyajl-dev) > > + * Development install of json-c (e.g. libjson-c-dev) or yajl (e.g. libyajl-dev) > > * Development install of libaio (e.g. libaio-dev) version 0.3.107 or > > greater. > > * Development install of GLib v2.0 (e.g. libglib2.0-dev) > > What are we going to do about testing this? > > We should add libjson-c to some build containers. We need to annotate # > Xen < 4.21 in the existing containers so we can drop it in due course. archlinux container already have `json-c` so the CI already do some build jobs with it. (no *-dev needed for this one container). It even notice an issue with `debug=n` builds, I had to replace `strncpy` by `memcpy`. > Also, for a container we don't intend to backport to stable trees, we > should have libjson-c only and no yajl. Probably best to do this in the > Alpine update which is long overdue. Doing this on alpine container would allow to actually do some runtime tests with json-c instead of yajl, so yes. -- Anthony PERARD ^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD ` (10 preceding siblings ...) 2025-08-08 14:56 ` [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c Anthony PERARD @ 2025-08-08 15:14 ` Andrew Cooper 11 siblings, 0 replies; 34+ messages in thread From: Andrew Cooper @ 2025-08-08 15:14 UTC (permalink / raw) To: Anthony PERARD, xen-devel Cc: Anthony PERARD, Juergen Gross, Roger Pau Monné, Jan Beulich, Community Manager, Stefano Stabellini, Julien Grall, Michal Orzel, Oleksii Kurochko On 08/08/2025 3:55 pm, Anthony PERARD wrote: > From: Anthony PERARD <anthony.perard@vates.tech> > > Patch series available in this git branch: > https://xenbits.xenproject.org/git-http/people/aperard/xen-unstable.git br.libxl-libjsonc-v1 > > Hi, > > The library YAJL has been unmaintained for several years, without an obvious > fork to pick. > > On the other and the library json-c is been maintained and use by several other > project, it's probably already installed on your machine. So this patch series > intend to allow to build the Xen toolstack again json-c, and forgo yajl. > > Just in case, YAJL is can still be used. > > There's bit of libxl API that exposes YAJL, mainly so it can be used by `xl` to > call libxl_domain_config_gen_json(). It was exposed via the "libxl_json.h" > headers. This functions and others won't be available when libxl is build > against json-c. > > Cheers, > > Anthony PERARD (11): > xl: move printf_info prototype to an header > libxl: Remove duplicate libxl_domain_config_gen_json prototype > libxl: remove duplicated libxl__yajl_gen_asciiz() prototype First three, trivially Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> I'll look at the rest when I've got a bit more time. ^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2025-09-29 9:53 UTC | newest] Thread overview: 34+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-08 14:55 [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 01/11] xl: move printf_info prototype to an header Anthony PERARD 2025-08-27 14:55 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 02/11] libxl: Remove duplicate libxl_domain_config_gen_json prototype Anthony PERARD 2025-08-27 14:55 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 03/11] libxl: remove duplicated libxl__yajl_gen_asciiz() prototype Anthony PERARD 2025-08-27 14:56 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 04/11] tools/configure: Introduce deps on json-c lib for libxl Anthony PERARD 2025-08-11 10:48 ` Andrew Cooper 2025-08-13 15:42 ` Anthony PERARD 2025-08-27 15:01 ` Jason Andryuk 2025-08-29 13:17 ` Anthony PERARD 2025-08-31 14:42 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 05/11] libxl: Convert libxl__json_parse() to use json-c Anthony PERARD 2025-08-27 15:20 ` Jason Andryuk 2025-08-08 14:55 ` [XEN PATCH 06/11] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object Anthony PERARD 2025-08-27 15:37 ` Jason Andryuk 2025-08-29 13:56 ` Anthony PERARD 2025-08-31 14:51 ` Jason Andryuk 2025-09-29 9:52 ` Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 07/11] libxl: libxl__object_to_json() to json-c Anthony PERARD 2025-08-27 17:51 ` Jason Andryuk 2025-08-27 17:59 ` Andrew Cooper 2025-08-29 15:32 ` Anthony PERARD 2025-08-08 14:55 ` [XEN PATCH 08/11] libxl: convert libxl__json_object_to_json() to json_object Anthony PERARD 2025-08-27 17:54 ` Jason Andryuk 2025-08-08 14:56 ` [XEN PATCH 09/11] tools/libxenstat: Use json-c when available Anthony PERARD 2025-08-27 18:00 ` Jason Andryuk 2025-08-08 14:56 ` [XEN PATCH 10/11] configure: Use json-c by default, fallback to yajl Anthony PERARD 2025-08-08 14:56 ` [XEN PATCH 11/11] Update CHANGELOG and README with dependency on json-c Anthony PERARD 2025-08-11 8:27 ` Oleksii Kurochko 2025-08-11 10:55 ` Andrew Cooper 2025-08-11 14:37 ` Anthony PERARD 2025-08-08 15:14 ` [XEN PATCH 00/11] Allow to build libxl and other tools with json-c instead of yajl Andrew Cooper
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.