From: Ján Tomko Date: Wed, 2 May 2018 15:17:01 +0000 (+0200) Subject: Switch from yajl to Jansson X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=9cf38263d05ca7f27dbbd9b1a0b48d338d9280e2;p=libvirt.git Switch from yajl to Jansson Yajl has not seen much activity upstream recently. Switch to using Jansson >= 2.5. All the platforms we target on https://libvirt.org/platforms.html have a version >= 2.7 listed on the sites below: https://repology.org/metapackage/jansson/versions https://build.opensuse.org/package/show/devel:libraries:c_c++/libjansson Additionally, Ubuntu 14.04 on Travis-CI has 2.5. Set the requirement to 2.5 since we don't use anything from newer versions. Implement virJSONValue{From,To}String using Jansson, delete the yajl code (and the related virJSONParser structure) and report an error if someone explicitly specifies --with-yajl. Also adjust the test data to account for Jansson's different whitespace usage for empty arrays and tune up the specfile to keep 'make rpm' working when bisecting. Signed-off-by: Ján Tomko --- diff --git a/libvirt.spec.in b/libvirt.spec.in index 6f360c5579..f83e5f8601 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -330,7 +330,7 @@ BuildRequires: systemd-devel >= 185 BuildRequires: libudev-devel >= 145 %endif BuildRequires: libpciaccess-devel >= 0.10.9 -BuildRequires: yajl-devel +BuildRequires: jansson-devel %if %{with_sanlock} BuildRequires: sanlock-devel >= 2.4 %endif @@ -1321,7 +1321,7 @@ rm -f po/stamp-po --without-apparmor \ --without-hal \ --with-udev \ - --with-yajl \ + --with-jansson \ %{?arg_sanlock} \ --with-libpcap \ --with-macvtap \ diff --git a/m4/virt-nss.m4 b/m4/virt-nss.m4 index 951a74e835..082b7b14f6 100644 --- a/m4/virt-nss.m4 +++ b/m4/virt-nss.m4 @@ -27,9 +27,9 @@ AC_DEFUN([LIBVIRT_CHECK_NSS],[ bsd_nss=no fail=0 if test "x$with_nss_plugin" != "xno" ; then - if test "x$with_yajl" != "xyes" ; then + if test "x$with_jansson" != "xyes" ; then if test "x$with_nss_plugin" = "xyes" ; then - AC_MSG_ERROR([Can't build nss plugin without yajl]) + AC_MSG_ERROR([Can't build nss plugin without JSON support]) else with_nss_plugin=no fi diff --git a/m4/virt-yajl.m4 b/m4/virt-yajl.m4 index c4ea0102a3..8d4c43a6b2 100644 --- a/m4/virt-yajl.m4 +++ b/m4/virt-yajl.m4 @@ -23,31 +23,10 @@ AC_DEFUN([LIBVIRT_ARG_YAJL],[ AC_DEFUN([LIBVIRT_CHECK_YAJL],[ dnl YAJL JSON library http://lloyd.github.com/yajl/ - if test "$with_qemu:$with_yajl" = yes:check; then - dnl Some versions of qemu require the use of yajl; try to detect them - dnl here, although we do not require qemu to exist in order to compile. - dnl This check mirrors src/qemu/qemu_capabilities.c - AC_PATH_PROGS([QEMU], [qemu-kvm qemu kvm qemu-system-x86_64], - [], [$PATH:/usr/bin:/usr/libexec]) - if test -x "$QEMU"; then - if $QEMU -help 2>/dev/null | grep -q libvirt; then - with_yajl=yes - else - [qemu_version_sed='s/.*ersion \([0-9.,]*\).*/\1/'] - qemu_version=`$QEMU -version | sed "$qemu_version_sed"` - case $qemu_version in - [[1-9]].* | 0.15.* ) with_yajl=yes ;; - 0.* | '' ) ;; - *) AC_MSG_ERROR([Unexpected qemu version string]) ;; - esac - fi - fi + if test "$with_yajl" = yes; then + AC_MSG_ERROR([Compilation with YAJL is no longer supported]) fi - - LIBVIRT_CHECK_LIB_ALT([YAJL], [yajl], - [yajl_parse_complete], [yajl/yajl_common.h], - [YAJL2], [yajl], - [yajl_tree_parse], [yajl/yajl_common.h]) + with_yajl=no ]) AC_DEFUN([LIBVIRT_RESULT_YAJL],[ diff --git a/src/Makefile.am b/src/Makefile.am index db8c8ebd1a..83263e69e5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -544,7 +544,7 @@ libvirt_admin_la_CFLAGS = \ libvirt_admin_la_CFLAGS += \ $(XDR_CFLAGS) \ $(CAPNG_CFLAGS) \ - $(YAJL_CFLAGS) \ + $(JANSSON_CFLAGS) \ $(SSH2_CFLAGS) \ $(SASL_CFLAGS) \ $(GNUTLS_CFLAGS) \ @@ -552,7 +552,7 @@ libvirt_admin_la_CFLAGS += \ libvirt_admin_la_LIBADD += \ $(CAPNG_LIBS) \ - $(YAJL_LIBS) \ + $(JANSSON_LIBS) \ $(DEVMAPPER_LIBS) \ $(LIBXML_LIBS) \ $(SSH2_LIBS) \ @@ -994,14 +994,14 @@ libvirt_nss_la_SOURCES = \ libvirt_nss_la_CFLAGS = \ -DLIBVIRT_NSS \ $(AM_CFLAGS) \ - $(YAJL_CFLAGS) \ + $(JANSSON_CFLAGS) \ $(NULL) libvirt_nss_la_LDFLAGS = \ $(AM_LDFLAGS) \ $(NULL) libvirt_nss_la_LIBADD = \ - $(YAJL_LIBS) \ + $(JANSSON_LIBS) \ $(NULL) endif WITH_NSS diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 847dab2edc..6fb66516c2 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2092,7 +2092,7 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags) */ if ((!useAgent) || (ret < 0 && (acpiRequested || !flags))) { -#if !WITH_YAJL +#if !WITH_JANSSON virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("ACPI reboot is not supported without the JSON monitor")); goto endjob; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index a22265606c..71b2b93c2d 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -251,7 +251,7 @@ libvirt_util_la_SOURCES = \ $(NULL) libvirt_util_la_CFLAGS = \ $(CAPNG_CFLAGS) \ - $(YAJL_CFLAGS) \ + $(JANSSON_CFLAGS) \ $(LIBNL_CFLAGS) \ $(AM_CFLAGS) \ $(AUDIT_CFLAGS) \ @@ -264,7 +264,7 @@ libvirt_util_la_CFLAGS = \ $(NULL) libvirt_util_la_LIBADD = \ $(CAPNG_LIBS) \ - $(YAJL_LIBS) \ + $(JANSSON_LIBS) \ $(LIBNL_LIBS) \ $(THREAD_LIBS) \ $(AUDIT_LIBS) \ diff --git a/src/util/virjson.c b/src/util/virjson.c index 29530dcb15..608ba85d67 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -1985,6 +1985,217 @@ virJSONValueToString(virJSONValuePtr object, } +#elif WITH_JANSSON +# include + +static virJSONValuePtr +virJSONValueFromJansson(json_t *json) +{ + virJSONValuePtr ret = NULL; + const char *key; + json_t *cur; + size_t i; + + switch (json_typeof(json)) { + case JSON_OBJECT: + ret = virJSONValueNewObject(); + if (!ret) + goto error; + + json_object_foreach(json, key, cur) { + virJSONValuePtr val = virJSONValueFromJansson(cur); + if (!val) + goto error; + + if (virJSONValueObjectAppend(ret, key, val) < 0) { + virJSONValueFree(val); + goto error; + } + } + + break; + + case JSON_ARRAY: + ret = virJSONValueNewArray(); + if (!ret) + goto error; + + json_array_foreach(json, i, cur) { + virJSONValuePtr val = virJSONValueFromJansson(cur); + if (!val) + goto error; + + if (virJSONValueArrayAppend(ret, val) < 0) { + virJSONValueFree(val); + goto error; + } + } + break; + + case JSON_STRING: + ret = virJSONValueNewString(json_string_value(json)); + break; + + case JSON_INTEGER: + ret = virJSONValueNewNumberLong(json_integer_value(json)); + break; + + case JSON_REAL: + ret = virJSONValueNewNumberDouble(json_real_value(json)); + break; + + case JSON_TRUE: + ret = virJSONValueNewBoolean(true); + break; + + case JSON_FALSE: + ret = virJSONValueNewBoolean(false); + break; + + case JSON_NULL: + ret = virJSONValueNewNull(); + break; + } + + return ret; + + error: + virJSONValueFree(ret); + return NULL; +} + +virJSONValuePtr +virJSONValueFromString(const char *jsonstring) +{ + virJSONValuePtr ret = NULL; + json_t *json; + json_error_t error; + size_t flags = JSON_REJECT_DUPLICATES | + JSON_DECODE_ANY; + + if (!(json = json_loads(jsonstring, flags, &error))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse JSON %d:%d: %s"), + error.line, error.column, error.text); + return NULL; + } + + ret = virJSONValueFromJansson(json); + json_decref(json); + return ret; +} + + +static json_t * +virJSONValueToJansson(virJSONValuePtr object) +{ + json_t *ret = NULL; + size_t i; + + switch ((virJSONType)object->type) { + case VIR_JSON_TYPE_OBJECT: + ret = json_object(); + if (!ret) + goto no_memory; + for (i = 0; i < object->data.object.npairs; i++) { + virJSONObjectPairPtr cur = object->data.object.pairs + i; + json_t *val = virJSONValueToJansson(cur->value); + + if (!val) + goto error; + if (json_object_set_new(ret, cur->key, val) < 0) { + json_decref(val); + goto no_memory; + } + } + break; + + case VIR_JSON_TYPE_ARRAY: + ret = json_array(); + if (!ret) + goto no_memory; + for (i = 0; i < object->data.array.nvalues; i++) { + virJSONValuePtr cur = object->data.array.values[i]; + json_t *val = virJSONValueToJansson(cur); + + if (!val) + goto error; + if (json_array_append_new(ret, val) < 0) { + json_decref(val); + goto no_memory; + } + } + break; + + case VIR_JSON_TYPE_STRING: + ret = json_string(object->data.string); + break; + + case VIR_JSON_TYPE_NUMBER: { + long long ll_val; + double d_val; + if (virStrToLong_ll(object->data.number, NULL, 10, &ll_val) < 0) { + if (virStrToDouble(object->data.number, NULL, &d_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("JSON value is not a number")); + return NULL; + } + ret = json_real(d_val); + } else { + ret = json_integer(ll_val); + } + } + break; + + case VIR_JSON_TYPE_BOOLEAN: + ret = json_boolean(object->data.boolean); + break; + + case VIR_JSON_TYPE_NULL: + ret = json_null(); + break; + + default: + virReportEnumRangeError(virJSONType, object->type); + goto error; + } + if (!ret) + goto no_memory; + return ret; + + no_memory: + virReportOOMError(); + error: + json_decref(ret); + return NULL; +} + + +char * +virJSONValueToString(virJSONValuePtr object, + bool pretty) +{ + size_t flags = JSON_ENCODE_ANY; + json_t *json; + char *str = NULL; + + if (pretty) + flags |= JSON_INDENT(2); + else + flags |= JSON_COMPACT; + + json = virJSONValueToJansson(object); + if (!json) + return NULL; + + str = json_dumps(json, flags); + if (!str) + virReportOOMError(); + json_decref(json); + return str; +} + + #else virJSONValuePtr virJSONValueFromString(const char *jsonstring ATTRIBUTE_UNUSED) diff --git a/tests/Makefile.am b/tests/Makefile.am index 21a6c823d9..302b50e1cd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -46,7 +46,7 @@ AM_CFLAGS = \ $(SASL_CFLAGS) \ $(SELINUX_CFLAGS) \ $(APPARMOR_CFLAGS) \ - $(YAJL_CFLAGS) \ + $(JANSSON_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(XDR_CFLAGS) \ $(WARN_CFLAGS) @@ -331,9 +331,9 @@ if WITH_CIL test_programs += objectlocking endif WITH_CIL -if WITH_YAJL +if WITH_JANSSON test_programs += virjsontest -endif WITH_YAJL +endif WITH_JANSSON test_programs += \ networkxml2xmltest \ @@ -1219,15 +1219,15 @@ virdeterministichashmock_la_LIBADD = $(MOCKLIBS_LIBS) test_libraries += virdeterministichashmock.la -if WITH_YAJL +if WITH_JANSSON virmacmaptest_SOURCES = \ virmacmaptest.c testutils.h testutils.c virmacmaptest_LDADD = $(LDADDS) test_programs += virmacmaptest -else ! WITH_YAJL +else ! WITH_JANSSON EXTRA_DIST += virmacmaptest.c -endif ! WITH_YAJL +endif ! WITH_JANSSON virnetdevtest_SOURCES = \ virnetdevtest.c testutils.h testutils.c diff --git a/tests/cputest.c b/tests/cputest.c index baf2b3c648..9cc361d125 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -40,7 +40,7 @@ #include "cpu/cpu_map.h" #include "virstring.h" -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON # include "testutilsqemu.h" # include "qemumonitortestutils.h" # define __QEMU_CAPSPRIV_H_ALLOW__ @@ -67,7 +67,7 @@ struct data { int result; }; -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON static virQEMUDriver driver; #endif @@ -479,7 +479,7 @@ typedef enum { JSON_MODELS_REQUIRED, } cpuTestCPUIDJson; -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON static virQEMUCapsPtr cpuTestMakeQEMUCaps(const struct data *data) { @@ -554,7 +554,7 @@ cpuTestGetCPUModels(const struct data *data, return 0; } -#else /* if WITH_QEMU && WITH_YAJL */ +#else /* if WITH_QEMU && WITH_JANSSON */ static int cpuTestGetCPUModels(const struct data *data, @@ -834,7 +834,7 @@ cpuTestUpdateLive(const void *arg) } -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON static int cpuTestJSONCPUID(const void *arg) { @@ -911,7 +911,7 @@ mymain(void) virDomainCapsCPUModelsPtr ppc_models = NULL; int ret = 0; -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; @@ -1004,7 +1004,7 @@ mymain(void) host "/" cpu " (" #models ")", \ host, cpu, models, 0, result) -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON # define DO_TEST_JSON(arch, host, json) \ do { \ if (json == JSON_MODELS) { \ @@ -1205,7 +1205,7 @@ mymain(void) DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-X5460", JSON_NONE); cleanup: -#if WITH_QEMU && WITH_YAJL +#if WITH_QEMU && WITH_JANSSON qemuTestDriverFree(&driver); #endif diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c index 54a92cc959..34a63e22b5 100644 --- a/tests/libxlxml2domconfigtest.c +++ b/tests/libxlxml2domconfigtest.c @@ -33,7 +33,7 @@ #include "testutils.h" -#if defined(WITH_LIBXL) && defined(WITH_YAJL) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) +#if defined(WITH_LIBXL) && defined(WITH_JANSSON) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) # include "internal.h" # include "viralloc.h" @@ -227,4 +227,4 @@ int main(void) return EXIT_AM_SKIP; } -#endif /* WITH_LIBXL && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ +#endif /* WITH_LIBXL && WITH_JANSSON && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index 2f79986207..232b34f9cd 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -907,7 +907,7 @@ mymain(void) { int ret = 0; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 0c335abc5b..9a387cf063 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -309,6 +309,7 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque) goto cleanup; virBufferAdd(&buf, jsonstr, -1); + virBufferAddLit(&buf, "\n"); VIR_FREE(jsonstr); } diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c index 4aec175968..641ec4f597 100644 --- a/tests/qemucapabilitiestest.c +++ b/tests/qemucapabilitiestest.c @@ -141,7 +141,7 @@ mymain(void) int ret = 0; testQemuData data; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemucaps2xmltest.c b/tests/qemucaps2xmltest.c index 5b9152b04d..e3b7b97925 100644 --- a/tests/qemucaps2xmltest.c +++ b/tests/qemucaps2xmltest.c @@ -165,7 +165,7 @@ mymain(void) testQemuData data; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c index f0921e3b93..8e57a1b79d 100644 --- a/tests/qemucommandutiltest.c +++ b/tests/qemucommandutiltest.c @@ -76,7 +76,7 @@ mymain(void) int ret = 0; testQemuCommandBuildObjectFromJSONData data1; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 663e33ed00..c7bc69ab32 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -589,7 +589,7 @@ mymain(void) struct qemuHotplugTestData data = {0}; struct testQemuHotplugCpuParams cpudata; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemumigparamsdata/empty.json b/tests/qemumigparamsdata/empty.json index 0db3279e44..0967ef424b 100644 --- a/tests/qemumigparamsdata/empty.json +++ b/tests/qemumigparamsdata/empty.json @@ -1,3 +1 @@ -{ - -} +{} diff --git a/tests/qemumigparamsdata/unsupported.json b/tests/qemumigparamsdata/unsupported.json index 0db3279e44..0967ef424b 100644 --- a/tests/qemumigparamsdata/unsupported.json +++ b/tests/qemumigparamsdata/unsupported.json @@ -1,3 +1 @@ -{ - -} +{} diff --git a/tests/qemumigparamstest.c b/tests/qemumigparamstest.c index 0532053722..b8af68211b 100644 --- a/tests/qemumigparamstest.c +++ b/tests/qemumigparamstest.c @@ -203,7 +203,7 @@ mymain(void) virQEMUDriver driver; int ret = 0; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index e9b2632655..c11615f7ac 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -2863,7 +2863,7 @@ mymain(void) virJSONValuePtr metaschema = NULL; char *metaschemastr = NULL; -#if !WITH_YAJL +#if !WITH_JANSSON fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); return EXIT_AM_SKIP; #endif diff --git a/tests/virmacmaptestdata/empty.json b/tests/virmacmaptestdata/empty.json index 41b42e677b..fe51488c70 100644 --- a/tests/virmacmaptestdata/empty.json +++ b/tests/virmacmaptestdata/empty.json @@ -1,3 +1 @@ -[ - -] +[] diff --git a/tests/virmocklibxl.c b/tests/virmocklibxl.c index 546c6d6a43..0a047c239f 100644 --- a/tests/virmocklibxl.c +++ b/tests/virmocklibxl.c @@ -22,7 +22,7 @@ #include -#if defined(WITH_LIBXL) && defined(WITH_YAJL) +#if defined(WITH_LIBXL) && defined(WITH_JANSSON) # include "virmock.h" # include # include @@ -136,4 +136,4 @@ VIR_MOCK_IMPL_RET_ARGS(stat, int, return real_stat(path, sb); } -#endif /* WITH_LIBXL && WITH_YAJL */ +#endif /* WITH_LIBXL && WITH_JANSSON */ diff --git a/tests/virnetdaemontest.c b/tests/virnetdaemontest.c index 6f4957fc4c..cbc961dbaf 100644 --- a/tests/virnetdaemontest.c +++ b/tests/virnetdaemontest.c @@ -26,7 +26,7 @@ #define VIR_FROM_THIS VIR_FROM_RPC -#if defined(HAVE_SOCKETPAIR) && defined(WITH_YAJL) +#if defined(HAVE_SOCKETPAIR) && defined(WITH_JANSSON) struct testClientPriv { int magic; }; diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 68d0307d5c..b20b5a8744 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -1317,7 +1317,7 @@ mymain(void) " \n" "\n"); -#ifdef WITH_YAJL +#ifdef WITH_JANSSON TEST_BACKING_PARSE("json:", NULL); TEST_BACKING_PARSE("json:asdgsdfg", NULL); TEST_BACKING_PARSE("json:{}", NULL); @@ -1581,7 +1581,7 @@ mymain(void) "\n" " \n" "\n"); -#endif /* WITH_YAJL */ +#endif /* WITH_JANSSON */ cleanup: /* Final cleanup */