|
|
d0ea73 |
From 21f0a22072f0543c416c440665bcf75ae09e6233 Mon Sep 17 00:00:00 2001
|
|
|
d0ea73 |
From: Pino Toscano <ptoscano@redhat.com>
|
|
|
d0ea73 |
Date: Mon, 12 Feb 2018 11:24:06 +0100
|
|
|
d0ea73 |
Subject: [PATCH] Switch from YAJL to Jansson
|
|
|
d0ea73 |
|
|
|
d0ea73 |
While YAJL mostly works fine, it did not see any active development in
|
|
|
d0ea73 |
the last 3 years. OTOH, Jansson is another JSON C implementation, with
|
|
|
d0ea73 |
a very liberal license, and a much nicer API.
|
|
|
d0ea73 |
|
|
|
d0ea73 |
Hence, switch all of libguestfs from YAJL to Jansson:
|
|
|
d0ea73 |
- configure checks, and buildsystem in general
|
|
|
d0ea73 |
- packages pulled in the appliance
|
|
|
d0ea73 |
- actual implementations
|
|
|
d0ea73 |
- contrib scripts
|
|
|
d0ea73 |
- documentation
|
|
|
d0ea73 |
|
|
|
d0ea73 |
This also makes use of the better APIs available (e.g. json_object_get,
|
|
|
d0ea73 |
json_array_foreach, and json_object_foreach). This does not change the
|
|
|
d0ea73 |
API of our OCaml Yajl module.
|
|
|
d0ea73 |
|
|
|
d0ea73 |
(cherry picked from commit bd1c5c9f4dcf38458099db8a0bf4659a07ef055d)
|
|
|
d0ea73 |
---
|
|
|
d0ea73 |
appliance/packagelist.in | 13 ++--
|
|
|
d0ea73 |
builder/Makefile.am | 4 +-
|
|
|
d0ea73 |
builder/yajl-c.c | 66 ++++++++--------
|
|
|
d0ea73 |
contrib/p2v/aux-scripts/do-build.sh | 8 +-
|
|
|
d0ea73 |
contrib/p2v/build-p2v-iso.sh | 3 +-
|
|
|
d0ea73 |
daemon/Makefile.am | 4 +-
|
|
|
d0ea73 |
daemon/ldm.c | 113 ++++++++++++----------------
|
|
|
d0ea73 |
docs/guestfs-building.pod | 2 +-
|
|
|
d0ea73 |
lib/Makefile.am | 4 +-
|
|
|
d0ea73 |
lib/info.c | 113 +++++++++++-----------------
|
|
|
d0ea73 |
lib/qemu.c | 64 ++++++----------
|
|
|
d0ea73 |
m4/guestfs-libraries.m4 | 4 +-
|
|
|
d0ea73 |
12 files changed, 168 insertions(+), 230 deletions(-)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
|
|
|
d0ea73 |
index 8ded2588a..f92a6ce95 100644
|
|
|
d0ea73 |
--- a/appliance/packagelist.in
|
|
|
d0ea73 |
+++ b/appliance/packagelist.in
|
|
|
d0ea73 |
@@ -35,6 +35,7 @@ ifelse(REDHAT,1,
|
|
|
d0ea73 |
hivex
|
|
|
d0ea73 |
iproute
|
|
|
d0ea73 |
iputils
|
|
|
d0ea73 |
+ jansson
|
|
|
d0ea73 |
kernel
|
|
|
d0ea73 |
libcap
|
|
|
d0ea73 |
libldm
|
|
|
d0ea73 |
@@ -51,7 +52,6 @@ ifelse(REDHAT,1,
|
|
|
d0ea73 |
systemd dnl for /sbin/reboot and udevd
|
|
|
d0ea73 |
vim-minimal
|
|
|
d0ea73 |
xz
|
|
|
d0ea73 |
- yajl
|
|
|
d0ea73 |
yara
|
|
|
d0ea73 |
zfs-fuse
|
|
|
d0ea73 |
)
|
|
|
d0ea73 |
@@ -82,12 +82,12 @@ dnl iproute has been renamed to iproute2
|
|
|
d0ea73 |
libc-bin
|
|
|
d0ea73 |
libcap2
|
|
|
d0ea73 |
libhivex0
|
|
|
d0ea73 |
+ libjansson4
|
|
|
d0ea73 |
libpcre3
|
|
|
d0ea73 |
libsystemd0
|
|
|
d0ea73 |
libsystemd-id128-0
|
|
|
d0ea73 |
libsystemd-journal0
|
|
|
d0ea73 |
libtirpc1
|
|
|
d0ea73 |
- libyajl2
|
|
|
d0ea73 |
libyara3
|
|
|
d0ea73 |
linux-image
|
|
|
d0ea73 |
dnl syslinux 'suggests' mtools, but in reality it's a hard dependency:
|
|
|
d0ea73 |
@@ -116,6 +116,7 @@ ifelse(ARCHLINUX,1,
|
|
|
d0ea73 |
hivex
|
|
|
d0ea73 |
iproute2
|
|
|
d0ea73 |
iputils
|
|
|
d0ea73 |
+ jansson
|
|
|
d0ea73 |
libcap
|
|
|
d0ea73 |
libtirpc
|
|
|
d0ea73 |
linux
|
|
|
d0ea73 |
@@ -131,7 +132,6 @@ ifelse(ARCHLINUX,1,
|
|
|
d0ea73 |
systemd
|
|
|
d0ea73 |
vim
|
|
|
d0ea73 |
xz
|
|
|
d0ea73 |
- yajl
|
|
|
d0ea73 |
yara
|
|
|
d0ea73 |
)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
@@ -153,9 +153,9 @@ ifelse(SUSE,1,
|
|
|
d0ea73 |
iputils
|
|
|
d0ea73 |
libcap2
|
|
|
d0ea73 |
libhivex0
|
|
|
d0ea73 |
+ libjansson4
|
|
|
d0ea73 |
libselinux1
|
|
|
d0ea73 |
libtirpc3
|
|
|
d0ea73 |
- libyajl2
|
|
|
d0ea73 |
libyara3
|
|
|
d0ea73 |
mkisofs
|
|
|
d0ea73 |
ntfsprogs
|
|
|
d0ea73 |
@@ -177,6 +177,7 @@ ifelse(FRUGALWARE,1,
|
|
|
d0ea73 |
hfsplus
|
|
|
d0ea73 |
iproute2
|
|
|
d0ea73 |
iputils
|
|
|
d0ea73 |
+ jansson
|
|
|
d0ea73 |
kernel
|
|
|
d0ea73 |
libcap
|
|
|
d0ea73 |
libtirpc
|
|
|
d0ea73 |
@@ -188,7 +189,6 @@ ifelse(FRUGALWARE,1,
|
|
|
d0ea73 |
systemd
|
|
|
d0ea73 |
vim
|
|
|
d0ea73 |
xz
|
|
|
d0ea73 |
- yajl
|
|
|
d0ea73 |
xfsprogs-acl
|
|
|
d0ea73 |
xfsprogs-attr
|
|
|
d0ea73 |
gptfdisk
|
|
|
d0ea73 |
@@ -209,9 +209,9 @@ ifelse(MAGEIA,1,
|
|
|
d0ea73 |
iproute2
|
|
|
d0ea73 |
iputils
|
|
|
d0ea73 |
libcap
|
|
|
d0ea73 |
+ libjansson4
|
|
|
d0ea73 |
libldm
|
|
|
d0ea73 |
libtirpc
|
|
|
d0ea73 |
- libyajl
|
|
|
d0ea73 |
dnl syslinux uses mtools without depending on it
|
|
|
d0ea73 |
mtools
|
|
|
d0ea73 |
nilfs-utils
|
|
|
d0ea73 |
@@ -224,7 +224,6 @@ ifelse(MAGEIA,1,
|
|
|
d0ea73 |
systemd /* for /sbin/reboot and udevd */
|
|
|
d0ea73 |
vim-minimal
|
|
|
d0ea73 |
xz
|
|
|
d0ea73 |
- yajl
|
|
|
d0ea73 |
)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
acl
|
|
|
d0ea73 |
diff --git a/builder/Makefile.am b/builder/Makefile.am
|
|
|
d0ea73 |
index e5872bdd9..c7b50778a 100644
|
|
|
d0ea73 |
--- a/builder/Makefile.am
|
|
|
d0ea73 |
+++ b/builder/Makefile.am
|
|
|
d0ea73 |
@@ -157,7 +157,7 @@ virt_builder_CFLAGS = \
|
|
|
d0ea73 |
$(LIBLZMA_CFLAGS) \
|
|
|
d0ea73 |
$(LIBTINFO_CFLAGS) \
|
|
|
d0ea73 |
$(LIBXML2_CFLAGS) \
|
|
|
d0ea73 |
- $(YAJL_CFLAGS)
|
|
|
d0ea73 |
+ $(JANSSON_CFLAGS)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
BOBJECTS = $(SOURCES_ML:.ml=.cmo)
|
|
|
d0ea73 |
XOBJECTS = $(BOBJECTS:.cmo=.cmx)
|
|
|
d0ea73 |
@@ -211,7 +211,7 @@ OCAMLCLIBS = \
|
|
|
d0ea73 |
$(LIBCRYPT_LIBS) \
|
|
|
d0ea73 |
$(LIBLZMA_LIBS) \
|
|
|
d0ea73 |
$(LIBXML2_LIBS) \
|
|
|
d0ea73 |
- $(YAJL_LIBS) \
|
|
|
d0ea73 |
+ $(JANSSON_LIBS) \
|
|
|
d0ea73 |
$(LIBINTL) \
|
|
|
d0ea73 |
-lgnu
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/builder/yajl-c.c b/builder/yajl-c.c
|
|
|
d0ea73 |
index 3c2402e42..e53755f55 100644
|
|
|
d0ea73 |
--- a/builder/yajl-c.c
|
|
|
d0ea73 |
+++ b/builder/yajl-c.c
|
|
|
d0ea73 |
@@ -23,24 +23,17 @@
|
|
|
d0ea73 |
#include <caml/memory.h>
|
|
|
d0ea73 |
#include <caml/mlvalues.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-#include <yajl/yajl_tree.h>
|
|
|
d0ea73 |
+#include <jansson.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#include <stdio.h>
|
|
|
d0ea73 |
#include <string.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
|
d0ea73 |
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
|
d0ea73 |
- */
|
|
|
d0ea73 |
-#if defined(__GNUC__) && __GNUC__ >= 6 /* gcc >= 6 */
|
|
|
d0ea73 |
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
|
d0ea73 |
-#endif
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
#define Val_none (Val_int (0))
|
|
|
d0ea73 |
|
|
|
d0ea73 |
value virt_builder_yajl_tree_parse (value stringv);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
static value
|
|
|
d0ea73 |
-convert_yajl_value (yajl_val val, int level)
|
|
|
d0ea73 |
+convert_json_t (json_t *val, int level)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
CAMLparam0 ();
|
|
|
d0ea73 |
CAMLlocal4 (rv, lv, v, sv);
|
|
|
d0ea73 |
@@ -48,46 +41,51 @@ convert_yajl_value (yajl_val val, int level)
|
|
|
d0ea73 |
if (level > 20)
|
|
|
d0ea73 |
caml_invalid_argument ("too many levels of object/array nesting");
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (YAJL_IS_OBJECT (val)) {
|
|
|
d0ea73 |
- const size_t len = YAJL_GET_OBJECT(val)->len;
|
|
|
d0ea73 |
+ if (json_is_object (val)) {
|
|
|
d0ea73 |
+ const size_t len = json_object_size (val);
|
|
|
d0ea73 |
size_t i;
|
|
|
d0ea73 |
+ const char *key;
|
|
|
d0ea73 |
+ json_t *jvalue;
|
|
|
d0ea73 |
rv = caml_alloc (1, 3);
|
|
|
d0ea73 |
lv = caml_alloc_tuple (len);
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
+ i = 0;
|
|
|
d0ea73 |
+ json_object_foreach (val, key, jvalue) {
|
|
|
d0ea73 |
v = caml_alloc_tuple (2);
|
|
|
d0ea73 |
- sv = caml_copy_string (YAJL_GET_OBJECT(val)->keys[i]);
|
|
|
d0ea73 |
+ sv = caml_copy_string (key);
|
|
|
d0ea73 |
Store_field (v, 0, sv);
|
|
|
d0ea73 |
- sv = convert_yajl_value (YAJL_GET_OBJECT(val)->values[i], level + 1);
|
|
|
d0ea73 |
+ sv = convert_json_t (jvalue, level + 1);
|
|
|
d0ea73 |
Store_field (v, 1, sv);
|
|
|
d0ea73 |
Store_field (lv, i, v);
|
|
|
d0ea73 |
+ ++i;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
Store_field (rv, 0, lv);
|
|
|
d0ea73 |
- } else if (YAJL_IS_ARRAY (val)) {
|
|
|
d0ea73 |
- const size_t len = YAJL_GET_ARRAY(val)->len;
|
|
|
d0ea73 |
+ } else if (json_is_array (val)) {
|
|
|
d0ea73 |
+ const size_t len = json_array_size (val);
|
|
|
d0ea73 |
size_t i;
|
|
|
d0ea73 |
+ json_t *jvalue;
|
|
|
d0ea73 |
rv = caml_alloc (1, 4);
|
|
|
d0ea73 |
lv = caml_alloc_tuple (len);
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- v = convert_yajl_value (YAJL_GET_ARRAY(val)->values[i], level + 1);
|
|
|
d0ea73 |
+ json_array_foreach (val, i, jvalue) {
|
|
|
d0ea73 |
+ v = convert_json_t (jvalue, level + 1);
|
|
|
d0ea73 |
Store_field (lv, i, v);
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
Store_field (rv, 0, lv);
|
|
|
d0ea73 |
- } else if (YAJL_IS_STRING (val)) {
|
|
|
d0ea73 |
+ } else if (json_is_string (val)) {
|
|
|
d0ea73 |
rv = caml_alloc (1, 0);
|
|
|
d0ea73 |
- v = caml_copy_string (YAJL_GET_STRING(val));
|
|
|
d0ea73 |
+ v = caml_copy_string (json_string_value (val));
|
|
|
d0ea73 |
Store_field (rv, 0, v);
|
|
|
d0ea73 |
- } else if (YAJL_IS_DOUBLE (val)) {
|
|
|
d0ea73 |
+ } else if (json_is_real (val)) {
|
|
|
d0ea73 |
rv = caml_alloc (1, 2);
|
|
|
d0ea73 |
- v = caml_copy_double (YAJL_GET_DOUBLE(val));
|
|
|
d0ea73 |
+ v = caml_copy_double (json_real_value (val));
|
|
|
d0ea73 |
Store_field (rv, 0, v);
|
|
|
d0ea73 |
- } else if (YAJL_IS_INTEGER (val)) {
|
|
|
d0ea73 |
+ } else if (json_is_integer (val)) {
|
|
|
d0ea73 |
rv = caml_alloc (1, 1);
|
|
|
d0ea73 |
- v = caml_copy_int64 (YAJL_GET_INTEGER(val));
|
|
|
d0ea73 |
+ v = caml_copy_int64 (json_integer_value (val));
|
|
|
d0ea73 |
Store_field (rv, 0, v);
|
|
|
d0ea73 |
- } else if (YAJL_IS_TRUE (val)) {
|
|
|
d0ea73 |
+ } else if (json_is_true (val)) {
|
|
|
d0ea73 |
rv = caml_alloc (1, 5);
|
|
|
d0ea73 |
Store_field (rv, 0, Val_true);
|
|
|
d0ea73 |
- } else if (YAJL_IS_FALSE (val)) {
|
|
|
d0ea73 |
+ } else if (json_is_false (val)) {
|
|
|
d0ea73 |
rv = caml_alloc (1, 5);
|
|
|
d0ea73 |
Store_field (rv, 0, Val_false);
|
|
|
d0ea73 |
} else
|
|
|
d0ea73 |
@@ -101,21 +99,21 @@ virt_builder_yajl_tree_parse (value stringv)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
CAMLparam1 (stringv);
|
|
|
d0ea73 |
CAMLlocal1 (rv);
|
|
|
d0ea73 |
- yajl_val tree;
|
|
|
d0ea73 |
- char error_buf[256];
|
|
|
d0ea73 |
+ json_t *tree;
|
|
|
d0ea73 |
+ json_error_t err;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- tree = yajl_tree_parse (String_val (stringv), error_buf, sizeof error_buf);
|
|
|
d0ea73 |
+ tree = json_loads (String_val (stringv), JSON_DECODE_ANY, &err;;
|
|
|
d0ea73 |
if (tree == NULL) {
|
|
|
d0ea73 |
- char buf[256 + sizeof error_buf];
|
|
|
d0ea73 |
- if (strlen (error_buf) > 0)
|
|
|
d0ea73 |
- snprintf (buf, sizeof buf, "JSON parse error: %s", error_buf);
|
|
|
d0ea73 |
+ char buf[256 + JSON_ERROR_TEXT_LENGTH];
|
|
|
d0ea73 |
+ if (strlen (err.text) > 0)
|
|
|
d0ea73 |
+ snprintf (buf, sizeof buf, "JSON parse error: %s", err.text);
|
|
|
d0ea73 |
else
|
|
|
d0ea73 |
snprintf (buf, sizeof buf, "unknown JSON parse error");
|
|
|
d0ea73 |
caml_invalid_argument (buf);
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- rv = convert_yajl_value (tree, 1);
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
+ rv = convert_json_t (tree, 1);
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
CAMLreturn (rv);
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
diff --git a/contrib/p2v/aux-scripts/do-build.sh b/contrib/p2v/aux-scripts/do-build.sh
|
|
|
d0ea73 |
index 5edb53d0e..dd6424bb4 100644
|
|
|
d0ea73 |
--- a/contrib/p2v/aux-scripts/do-build.sh
|
|
|
d0ea73 |
+++ b/contrib/p2v/aux-scripts/do-build.sh
|
|
|
d0ea73 |
@@ -53,8 +53,8 @@ case $osversion in
|
|
|
d0ea73 |
# This just forces configure to ignore these missing dependencies.
|
|
|
d0ea73 |
export LIBTINFO_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
export LIBTINFO_LIBS=-lncurses
|
|
|
d0ea73 |
- export YAJL_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
- export YAJL_LIBS=-lyajl
|
|
|
d0ea73 |
+ export JANSSON_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
+ export JANSSON_LIBS=-ljansson
|
|
|
d0ea73 |
# Remove some unsupported flags that the configure script hard codes.
|
|
|
d0ea73 |
sed -i -e 's/-fno-strict-overflow//' configure
|
|
|
d0ea73 |
sed -i -e 's/-Wno-strict-overflow//' configure
|
|
|
d0ea73 |
@@ -66,8 +66,8 @@ case $osversion in
|
|
|
d0ea73 |
# This just forces configure to ignore these missing dependencies.
|
|
|
d0ea73 |
export LIBTINFO_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
export LIBTINFO_LIBS=-lncurses
|
|
|
d0ea73 |
- export YAJL_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
- export YAJL_LIBS=-lyajl
|
|
|
d0ea73 |
+ export JANSSON_CFLAGS=-D_GNU_SOURCE
|
|
|
d0ea73 |
+ export JANSSON_LIBS=-ljansson
|
|
|
d0ea73 |
;;
|
|
|
d0ea73 |
esac
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/contrib/p2v/build-p2v-iso.sh b/contrib/p2v/build-p2v-iso.sh
|
|
|
d0ea73 |
index c80a1b134..ae25cebc8 100755
|
|
|
d0ea73 |
--- a/contrib/p2v/build-p2v-iso.sh
|
|
|
d0ea73 |
+++ b/contrib/p2v/build-p2v-iso.sh
|
|
|
d0ea73 |
@@ -86,7 +86,6 @@ done
|
|
|
d0ea73 |
# Various hacks for different versions of RHEL.
|
|
|
d0ea73 |
if=virtio
|
|
|
d0ea73 |
netdev=virtio-net-pci
|
|
|
d0ea73 |
-pkgs="$pkgs,yajl-devel"
|
|
|
d0ea73 |
declare -a epel
|
|
|
d0ea73 |
case $osversion in
|
|
|
d0ea73 |
rhel-5.*|centos-5.*)
|
|
|
d0ea73 |
@@ -105,10 +104,12 @@ case $osversion in
|
|
|
d0ea73 |
rhel-6.*|centos-6.*)
|
|
|
d0ea73 |
epel[0]="--run-command"
|
|
|
d0ea73 |
epel[1]="yum install -y --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm"
|
|
|
d0ea73 |
+ pkgs="$pkgs,jansson-devel"
|
|
|
d0ea73 |
;;
|
|
|
d0ea73 |
rhel-7.*|centos-7.*)
|
|
|
d0ea73 |
epel[0]="--run-command"
|
|
|
d0ea73 |
epel[1]="yum install -y --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
|
|
|
d0ea73 |
+ pkgs="$pkgs,jansson-devel"
|
|
|
d0ea73 |
;;
|
|
|
d0ea73 |
esac
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
|
|
d0ea73 |
index 6240f517d..d9ed5625e 100644
|
|
|
d0ea73 |
--- a/daemon/Makefile.am
|
|
|
d0ea73 |
+++ b/daemon/Makefile.am
|
|
|
d0ea73 |
@@ -218,7 +218,7 @@ guestfsd_LDADD = \
|
|
|
d0ea73 |
camldaemon.o \
|
|
|
d0ea73 |
$(ACL_LIBS) \
|
|
|
d0ea73 |
$(CAP_LIBS) \
|
|
|
d0ea73 |
- $(YAJL_LIBS) \
|
|
|
d0ea73 |
+ $(JANSSON_LIBS) \
|
|
|
d0ea73 |
$(SELINUX_LIBS) \
|
|
|
d0ea73 |
$(AUGEAS_LIBS) \
|
|
|
d0ea73 |
$(HIVEX_LIBS) \
|
|
|
d0ea73 |
@@ -256,7 +256,7 @@ guestfsd_CFLAGS = \
|
|
|
d0ea73 |
$(AUGEAS_CFLAGS) \
|
|
|
d0ea73 |
$(HIVEX_CFLAGS) \
|
|
|
d0ea73 |
$(SD_JOURNAL_CFLAGS) \
|
|
|
d0ea73 |
- $(YAJL_CFLAGS) \
|
|
|
d0ea73 |
+ $(JANSSON_CFLAGS) \
|
|
|
d0ea73 |
$(PCRE_CFLAGS)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
# Parts of the daemon are written in OCaml. These are linked into a
|
|
|
d0ea73 |
diff --git a/daemon/ldm.c b/daemon/ldm.c
|
|
|
d0ea73 |
index 2f4d2aef3..be4fb9701 100644
|
|
|
d0ea73 |
--- a/daemon/ldm.c
|
|
|
d0ea73 |
+++ b/daemon/ldm.c
|
|
|
d0ea73 |
@@ -25,19 +25,12 @@
|
|
|
d0ea73 |
#include <sys/stat.h>
|
|
|
d0ea73 |
#include <string.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-#include <yajl/yajl_tree.h>
|
|
|
d0ea73 |
+#include <jansson.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#include "daemon.h"
|
|
|
d0ea73 |
#include "actions.h"
|
|
|
d0ea73 |
#include "optgroups.h"
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
|
d0ea73 |
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
|
d0ea73 |
- */
|
|
|
d0ea73 |
-#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 60000 /* gcc >= 6 */
|
|
|
d0ea73 |
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
|
d0ea73 |
-#endif
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
int
|
|
|
d0ea73 |
optgroup_ldm_available (void)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
@@ -72,44 +65,42 @@ do_ldmtool_remove_all (void)
|
|
|
d0ea73 |
return 0;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-static yajl_val
|
|
|
d0ea73 |
+static json_t *
|
|
|
d0ea73 |
parse_json (const char *json, const char *func)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- yajl_val tree;
|
|
|
d0ea73 |
- char parse_error[1024];
|
|
|
d0ea73 |
+ json_t *tree;
|
|
|
d0ea73 |
+ json_error_t err;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
if (verbose)
|
|
|
d0ea73 |
fprintf (stderr, "%s: parsing json: %s\n", func, json);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- tree = yajl_tree_parse (json, parse_error, sizeof parse_error);
|
|
|
d0ea73 |
+ tree = json_loads (json, 0, &err;;
|
|
|
d0ea73 |
if (tree == NULL) {
|
|
|
d0ea73 |
reply_with_error ("parse error: %s",
|
|
|
d0ea73 |
- strlen (parse_error) ? parse_error : "unknown error");
|
|
|
d0ea73 |
+ strlen (err.text) ? err.text : "unknown error");
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- /* Caller should free this by doing 'yajl_tree_free (tree);'. */
|
|
|
d0ea73 |
+ /* Caller should free this by doing 'json_decref (tree);'. */
|
|
|
d0ea73 |
return tree;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#define TYPE_ERROR ((char **) -1)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
static char **
|
|
|
d0ea73 |
-json_value_to_string_list (yajl_val node)
|
|
|
d0ea73 |
+json_value_to_string_list (json_t *node)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (strs);
|
|
|
d0ea73 |
- yajl_val n;
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
+ json_t *n;
|
|
|
d0ea73 |
+ size_t i;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_ARRAY (node))
|
|
|
d0ea73 |
+ if (!json_is_array (node))
|
|
|
d0ea73 |
return TYPE_ERROR;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_ARRAY (node)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- n = YAJL_GET_ARRAY (node)->values[i];
|
|
|
d0ea73 |
- if (! YAJL_IS_STRING (n))
|
|
|
d0ea73 |
+ json_array_foreach (node, i, n) {
|
|
|
d0ea73 |
+ if (!json_is_string (n))
|
|
|
d0ea73 |
return TYPE_ERROR;
|
|
|
d0ea73 |
- if (add_string (&strs, YAJL_GET_STRING (n)) == -1)
|
|
|
d0ea73 |
+ if (add_string (&strs, json_string_value (n)) == -1)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
if (end_stringsbuf (&strs) == -1)
|
|
|
d0ea73 |
@@ -123,14 +114,14 @@ parse_json_get_string_list (const char *json,
|
|
|
d0ea73 |
const char *func, const char *cmd)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
char **ret;
|
|
|
d0ea73 |
- yajl_val tree = NULL;
|
|
|
d0ea73 |
+ json_t *tree = NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
tree = parse_json (json, func);
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
ret = json_value_to_string_list (tree);
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
if (ret == TYPE_ERROR) {
|
|
|
d0ea73 |
reply_with_error ("output of '%s' was not a JSON array of strings", cmd);
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
@@ -144,43 +135,40 @@ static char *
|
|
|
d0ea73 |
parse_json_get_object_string (const char *json, const char *key, int flags,
|
|
|
d0ea73 |
const char *func, const char *cmd)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- char *str, *ret;
|
|
|
d0ea73 |
- yajl_val tree = NULL, node;
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
+ const char *str;
|
|
|
d0ea73 |
+ char *ret;
|
|
|
d0ea73 |
+ json_t *tree = NULL, *node;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
tree = parse_json (json, func);
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_OBJECT (tree))
|
|
|
d0ea73 |
+ if (!json_is_object (tree))
|
|
|
d0ea73 |
goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_OBJECT (tree)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- if (STREQ (YAJL_GET_OBJECT (tree)->keys[i], key)) {
|
|
|
d0ea73 |
- node = YAJL_GET_OBJECT (tree)->values[i];
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
- if ((flags & GET_STRING_NULL_TO_EMPTY) && YAJL_IS_NULL (node))
|
|
|
d0ea73 |
- ret = strdup ("");
|
|
|
d0ea73 |
- else {
|
|
|
d0ea73 |
- str = YAJL_GET_STRING (node);
|
|
|
d0ea73 |
- if (str == NULL)
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- ret = strdup (str);
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- if (ret == NULL)
|
|
|
d0ea73 |
- reply_with_perror ("strdup");
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
+ node = json_object_get (tree, key);
|
|
|
d0ea73 |
+ if (node == NULL)
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- return ret;
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
+ if ((flags & GET_STRING_NULL_TO_EMPTY) && json_is_null (node))
|
|
|
d0ea73 |
+ ret = strdup ("");
|
|
|
d0ea73 |
+ else {
|
|
|
d0ea73 |
+ str = json_string_value (node);
|
|
|
d0ea73 |
+ if (str == NULL)
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
+ ret = strndup (str, json_string_length (node));
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
+ if (ret == NULL)
|
|
|
d0ea73 |
+ reply_with_perror ("strdup");
|
|
|
d0ea73 |
+
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
+
|
|
|
d0ea73 |
+ return ret;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
bad_type:
|
|
|
d0ea73 |
reply_with_error ("output of '%s' was not a JSON object "
|
|
|
d0ea73 |
"containing a key '%s' of type string", cmd, key);
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
@@ -189,33 +177,30 @@ parse_json_get_object_string_list (const char *json, const char *key,
|
|
|
d0ea73 |
const char *func, const char *cmd)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
char **ret;
|
|
|
d0ea73 |
- yajl_val tree, node;
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
+ json_t *tree, *node;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
tree = parse_json (json, func);
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_OBJECT (tree))
|
|
|
d0ea73 |
+ if (!json_is_object (tree))
|
|
|
d0ea73 |
goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_OBJECT (tree)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- if (STREQ (YAJL_GET_OBJECT (tree)->keys[i], key)) {
|
|
|
d0ea73 |
- node = YAJL_GET_OBJECT (tree)->values[i];
|
|
|
d0ea73 |
- ret = json_value_to_string_list (node);
|
|
|
d0ea73 |
- if (ret == TYPE_ERROR)
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
- return ret;
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
+ node = json_object_get (tree, key);
|
|
|
d0ea73 |
+ if (node == NULL)
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
+
|
|
|
d0ea73 |
+ ret = json_value_to_string_list (node);
|
|
|
d0ea73 |
+ if (ret == TYPE_ERROR)
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
+ return ret;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
bad_type:
|
|
|
d0ea73 |
reply_with_error ("output of '%s' was not a JSON object "
|
|
|
d0ea73 |
"containing a key '%s' of type array of strings",
|
|
|
d0ea73 |
cmd, key);
|
|
|
d0ea73 |
- yajl_tree_free (tree);
|
|
|
d0ea73 |
+ json_decref (tree);
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
|
|
|
d0ea73 |
index d350b1d73..2029429fd 100644
|
|
|
d0ea73 |
--- a/docs/guestfs-building.pod
|
|
|
d0ea73 |
+++ b/docs/guestfs-building.pod
|
|
|
d0ea73 |
@@ -172,7 +172,7 @@ I<Required>.
|
|
|
d0ea73 |
|
|
|
d0ea73 |
I<Required>.
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-=item yajl E<ge> 2.0.4
|
|
|
d0ea73 |
+=item Jansson
|
|
|
d0ea73 |
|
|
|
d0ea73 |
I<Required>.
|
|
|
d0ea73 |
|
|
|
d0ea73 |
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
|
|
d0ea73 |
index 91c4e0a2e..d075174d9 100644
|
|
|
d0ea73 |
--- a/lib/Makefile.am
|
|
|
d0ea73 |
+++ b/lib/Makefile.am
|
|
|
d0ea73 |
@@ -141,7 +141,7 @@ libguestfs_la_CFLAGS = \
|
|
|
d0ea73 |
$(PCRE_CFLAGS) \
|
|
|
d0ea73 |
$(LIBVIRT_CFLAGS) \
|
|
|
d0ea73 |
$(LIBXML2_CFLAGS) \
|
|
|
d0ea73 |
- $(YAJL_CFLAGS)
|
|
|
d0ea73 |
+ $(JANSSON_CFLAGS)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
libguestfs_la_LIBADD = \
|
|
|
d0ea73 |
../common/errnostring/liberrnostring.la \
|
|
|
d0ea73 |
@@ -152,7 +152,7 @@ libguestfs_la_LIBADD = \
|
|
|
d0ea73 |
$(PCRE_LIBS) \
|
|
|
d0ea73 |
$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \
|
|
|
d0ea73 |
$(SELINUX_LIBS) \
|
|
|
d0ea73 |
- $(YAJL_LIBS) \
|
|
|
d0ea73 |
+ $(JANSSON_LIBS) \
|
|
|
d0ea73 |
../gnulib/lib/libgnu.la \
|
|
|
d0ea73 |
$(GETADDRINFO_LIB) \
|
|
|
d0ea73 |
$(HOSTENT_LIB) \
|
|
|
d0ea73 |
diff --git a/lib/info.c b/lib/info.c
|
|
|
d0ea73 |
index 93fadcd39..2eadc1c11 100644
|
|
|
d0ea73 |
--- a/lib/info.c
|
|
|
d0ea73 |
+++ b/lib/info.c
|
|
|
d0ea73 |
@@ -37,53 +37,46 @@
|
|
|
d0ea73 |
#include <sys/resource.h>
|
|
|
d0ea73 |
#endif
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-#include <yajl/yajl_tree.h>
|
|
|
d0ea73 |
+#include <jansson.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#include "guestfs.h"
|
|
|
d0ea73 |
#include "guestfs-internal.h"
|
|
|
d0ea73 |
#include "guestfs-internal-actions.h"
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#ifdef HAVE_ATTRIBUTE_CLEANUP
|
|
|
d0ea73 |
-#define CLEANUP_YAJL_TREE_FREE __attribute__((cleanup(cleanup_yajl_tree_free)))
|
|
|
d0ea73 |
+#define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref)))
|
|
|
d0ea73 |
|
|
|
d0ea73 |
static void
|
|
|
d0ea73 |
-cleanup_yajl_tree_free (void *ptr)
|
|
|
d0ea73 |
+cleanup_json_t_decref (void *ptr)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- yajl_tree_free (* (yajl_val *) ptr);
|
|
|
d0ea73 |
+ json_decref (* (json_t **) ptr);
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#else
|
|
|
d0ea73 |
-#define CLEANUP_YAJL_TREE_FREE
|
|
|
d0ea73 |
+#define CLEANUP_JSON_T_DECREF
|
|
|
d0ea73 |
#endif
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-static yajl_val get_json_output (guestfs_h *g, const char *filename);
|
|
|
d0ea73 |
+static json_t *get_json_output (guestfs_h *g, const char *filename);
|
|
|
d0ea73 |
static void set_child_rlimits (struct command *);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
char *
|
|
|
d0ea73 |
guestfs_impl_disk_format (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ json_t *node;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_OBJECT (tree))
|
|
|
d0ea73 |
+ if (!json_is_object (tree))
|
|
|
d0ea73 |
goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_OBJECT(tree)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "format")) {
|
|
|
d0ea73 |
- const char *str;
|
|
|
d0ea73 |
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
|
d0ea73 |
- if (YAJL_IS_NULL (node))
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- str = YAJL_GET_STRING (node);
|
|
|
d0ea73 |
- if (str == NULL)
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- return safe_strdup (g, str); /* caller frees */
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
+ node = json_object_get (tree, "format");
|
|
|
d0ea73 |
+ if (!json_is_string (node))
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
+
|
|
|
d0ea73 |
+ return safe_strndup (g, json_string_value (node),
|
|
|
d0ea73 |
+ json_string_length (node)); /* caller frees */
|
|
|
d0ea73 |
|
|
|
d0ea73 |
bad_type:
|
|
|
d0ea73 |
error (g, _("qemu-img info: JSON output did not contain ‘format’ key"));
|
|
|
d0ea73 |
@@ -93,30 +86,20 @@ guestfs_impl_disk_format (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
int64_t
|
|
|
d0ea73 |
guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ json_t *node;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return -1;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_OBJECT (tree))
|
|
|
d0ea73 |
+ if (!json_is_object (tree))
|
|
|
d0ea73 |
goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_OBJECT(tree)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "virtual-size")) {
|
|
|
d0ea73 |
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
|
d0ea73 |
- if (YAJL_IS_NULL (node))
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- if (! YAJL_IS_NUMBER (node))
|
|
|
d0ea73 |
- goto bad_type;
|
|
|
d0ea73 |
- if (! YAJL_IS_INTEGER (node)) {
|
|
|
d0ea73 |
- error (g, _("qemu-img info: ‘virtual-size’ is not representable as a 64 bit integer"));
|
|
|
d0ea73 |
- return -1;
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- return YAJL_GET_INTEGER (node);
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
+ node = json_object_get (tree, "virtual-size");
|
|
|
d0ea73 |
+ if (!json_is_integer (node))
|
|
|
d0ea73 |
+ goto bad_type;
|
|
|
d0ea73 |
+
|
|
|
d0ea73 |
+ return json_integer_value (node);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
bad_type:
|
|
|
d0ea73 |
error (g, _("qemu-img info: JSON output did not contain ‘virtual-size’ key"));
|
|
|
d0ea73 |
@@ -126,29 +109,25 @@ guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
int
|
|
|
d0ea73 |
guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- size_t i, len;
|
|
|
d0ea73 |
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
|
d0ea73 |
+ json_t *node;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
if (tree == NULL)
|
|
|
d0ea73 |
return -1;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- if (! YAJL_IS_OBJECT (tree))
|
|
|
d0ea73 |
+ if (!json_is_object (tree))
|
|
|
d0ea73 |
goto bad_type;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- len = YAJL_GET_OBJECT(tree)->len;
|
|
|
d0ea73 |
- for (i = 0; i < len; ++i) {
|
|
|
d0ea73 |
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "backing-filename")) {
|
|
|
d0ea73 |
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
|
d0ea73 |
- /* Work on the assumption that if this field is null, it means
|
|
|
d0ea73 |
- * no backing file, rather than being an error.
|
|
|
d0ea73 |
- */
|
|
|
d0ea73 |
- if (YAJL_IS_NULL (node))
|
|
|
d0ea73 |
- return 0;
|
|
|
d0ea73 |
- return 1;
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
- }
|
|
|
d0ea73 |
+ node = json_object_get (tree, "backing-filename");
|
|
|
d0ea73 |
+ if (node == NULL)
|
|
|
d0ea73 |
+ return 0; /* no backing-filename key means no backing file */
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- return 0; /* no backing-filename key means no backing file */
|
|
|
d0ea73 |
+ /* Work on the assumption that if this field is null, it means
|
|
|
d0ea73 |
+ * no backing file, rather than being an error.
|
|
|
d0ea73 |
+ */
|
|
|
d0ea73 |
+ if (json_is_null (node))
|
|
|
d0ea73 |
+ return 0;
|
|
|
d0ea73 |
+ return 1;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
bad_type:
|
|
|
d0ea73 |
error (g, _("qemu-img info: JSON output was not an object"));
|
|
|
d0ea73 |
@@ -161,12 +140,12 @@ guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
static void parse_json (guestfs_h *g, void *treevp, const char *input, size_t len);
|
|
|
d0ea73 |
#define PARSE_JSON_NO_OUTPUT ((void *) -1)
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-static yajl_val
|
|
|
d0ea73 |
+static json_t *
|
|
|
d0ea73 |
get_json_output (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g);
|
|
|
d0ea73 |
int r;
|
|
|
d0ea73 |
- yajl_val tree = NULL;
|
|
|
d0ea73 |
+ json_t *tree = NULL;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
guestfs_int_cmd_add_arg (cmd, "qemu-img");
|
|
|
d0ea73 |
guestfs_int_cmd_add_arg (cmd, "info");
|
|
|
d0ea73 |
@@ -196,16 +175,15 @@ get_json_output (guestfs_h *g, const char *filename)
|
|
|
d0ea73 |
return NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- return tree; /* caller must call yajl_tree_free (tree) */
|
|
|
d0ea73 |
+ return tree; /* caller must call json_decref (tree) */
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
/* Parse the JSON document printed by qemu-img info --output json. */
|
|
|
d0ea73 |
static void
|
|
|
d0ea73 |
parse_json (guestfs_h *g, void *treevp, const char *input, size_t len)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- yajl_val *tree_ret = treevp;
|
|
|
d0ea73 |
- CLEANUP_FREE char *input_copy = NULL;
|
|
|
d0ea73 |
- char parse_error[256];
|
|
|
d0ea73 |
+ json_t **tree_ret = treevp;
|
|
|
d0ea73 |
+ json_error_t err;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
assert (*tree_ret == NULL);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
@@ -218,15 +196,12 @@ parse_json (guestfs_h *g, void *treevp, const char *input, size_t len)
|
|
|
d0ea73 |
return;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- /* 'input' is not \0-terminated; we have to make it so. */
|
|
|
d0ea73 |
- input_copy = safe_strndup (g, input, len);
|
|
|
d0ea73 |
+ debug (g, "%s: qemu-img info JSON output:\n%.*s\n", __func__, (int) len, input);
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- debug (g, "%s: qemu-img info JSON output:\n%s\n", __func__, input_copy);
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
- *tree_ret = yajl_tree_parse (input_copy, parse_error, sizeof parse_error);
|
|
|
d0ea73 |
+ *tree_ret = json_loadb (input, len, 0, &err;;
|
|
|
d0ea73 |
if (*tree_ret == NULL) {
|
|
|
d0ea73 |
- if (strlen (parse_error) > 0)
|
|
|
d0ea73 |
- error (g, _("qemu-img info: JSON parse error: %s"), parse_error);
|
|
|
d0ea73 |
+ if (strlen (err.text) > 0)
|
|
|
d0ea73 |
+ error (g, _("qemu-img info: JSON parse error: %s"), err.text);
|
|
|
d0ea73 |
else
|
|
|
d0ea73 |
error (g, _("qemu-img info: unknown JSON parse error"));
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
diff --git a/lib/qemu.c b/lib/qemu.c
|
|
|
d0ea73 |
index 6159b5a52..a50eca988 100644
|
|
|
d0ea73 |
--- a/lib/qemu.c
|
|
|
d0ea73 |
+++ b/lib/qemu.c
|
|
|
d0ea73 |
@@ -37,7 +37,7 @@
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#include <libxml/uri.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-#include <yajl/yajl_tree.h>
|
|
|
d0ea73 |
+#include <jansson.h>
|
|
|
d0ea73 |
|
|
|
d0ea73 |
#include "full-write.h"
|
|
|
d0ea73 |
#include "ignore-value.h"
|
|
|
d0ea73 |
@@ -57,7 +57,7 @@ struct qemu_data {
|
|
|
d0ea73 |
|
|
|
d0ea73 |
/* The following fields are derived from the fields above. */
|
|
|
d0ea73 |
struct version qemu_version; /* Parsed qemu version number. */
|
|
|
d0ea73 |
- yajl_val qmp_schema_tree; /* qmp_schema parsed into a JSON tree */
|
|
|
d0ea73 |
+ json_t *qmp_schema_tree; /* qmp_schema parsed into a JSON tree */
|
|
|
d0ea73 |
};
|
|
|
d0ea73 |
|
|
|
d0ea73 |
static char *cache_filename (guestfs_h *g, const char *cachedir, const struct stat *, const char *suffix);
|
|
|
d0ea73 |
@@ -73,7 +73,7 @@ static int write_cache_qmp_schema (guestfs_h *g, const struct qemu_data *data, c
|
|
|
d0ea73 |
static int read_cache_qemu_stat (guestfs_h *g, struct qemu_data *data, const char *filename);
|
|
|
d0ea73 |
static int write_cache_qemu_stat (guestfs_h *g, const struct qemu_data *data, const char *filename);
|
|
|
d0ea73 |
static void parse_qemu_version (guestfs_h *g, const char *, struct version *qemu_version);
|
|
|
d0ea73 |
-static void parse_json (guestfs_h *g, const char *, yajl_val *);
|
|
|
d0ea73 |
+static void parse_json (guestfs_h *g, const char *, json_t **);
|
|
|
d0ea73 |
static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len);
|
|
|
d0ea73 |
static int generic_read_cache (guestfs_h *g, const char *filename, char **strp);
|
|
|
d0ea73 |
static int generic_write_cache (guestfs_h *g, const char *filename, const char *str);
|
|
|
d0ea73 |
@@ -405,17 +405,17 @@ parse_qemu_version (guestfs_h *g, const char *qemu_help,
|
|
|
d0ea73 |
* is not possible.
|
|
|
d0ea73 |
*/
|
|
|
d0ea73 |
static void
|
|
|
d0ea73 |
-parse_json (guestfs_h *g, const char *json, yajl_val *treep)
|
|
|
d0ea73 |
+parse_json (guestfs_h *g, const char *json, json_t **treep)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- char parse_error[256] = "";
|
|
|
d0ea73 |
+ json_error_t err;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
if (!json)
|
|
|
d0ea73 |
return;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
- *treep = yajl_tree_parse (json, parse_error, sizeof parse_error);
|
|
|
d0ea73 |
+ *treep = json_loads (json, 0, &err;;
|
|
|
d0ea73 |
if (*treep == NULL) {
|
|
|
d0ea73 |
- if (strlen (parse_error) > 0)
|
|
|
d0ea73 |
- debug (g, "QMP parse error: %s (ignored)", parse_error);
|
|
|
d0ea73 |
+ if (strlen (err.text) > 0)
|
|
|
d0ea73 |
+ debug (g, "QMP parse error: %s (ignored)", err.text);
|
|
|
d0ea73 |
else
|
|
|
d0ea73 |
debug (g, "QMP unknown parse error (ignored)");
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
@@ -580,17 +580,6 @@ guestfs_int_qemu_supports_device (guestfs_h *g,
|
|
|
d0ea73 |
return strstr (data->qemu_devices, device_name) != NULL;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
|
d0ea73 |
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
|
d0ea73 |
- */
|
|
|
d0ea73 |
-#pragma GCC diagnostic push
|
|
|
d0ea73 |
-#if defined(__GNUC__) && __GNUC__ >= 6 /* gcc >= 6 */
|
|
|
d0ea73 |
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
|
d0ea73 |
-#endif
|
|
|
d0ea73 |
-#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
|
|
|
d0ea73 |
-#pragma GCC diagnostic ignored "-Wnonnull"
|
|
|
d0ea73 |
-#endif
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
/**
|
|
|
d0ea73 |
* Test if the qemu binary uses mandatory file locking, added in
|
|
|
d0ea73 |
* QEMU >= 2.10 (but sometimes disabled).
|
|
|
d0ea73 |
@@ -599,11 +588,7 @@ int
|
|
|
d0ea73 |
guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
|
d0ea73 |
const struct qemu_data *data)
|
|
|
d0ea73 |
{
|
|
|
d0ea73 |
- const char *return_path[] = { "return", NULL };
|
|
|
d0ea73 |
- const char *meta_type_path[] = { "meta-type", NULL };
|
|
|
d0ea73 |
- const char *members_path[] = { "members", NULL };
|
|
|
d0ea73 |
- const char *name_path[] = { "name", NULL };
|
|
|
d0ea73 |
- yajl_val schema, v, meta_type, members, m, name;
|
|
|
d0ea73 |
+ json_t *schema, *v, *meta_type, *members, *m, *name;
|
|
|
d0ea73 |
size_t i, j;
|
|
|
d0ea73 |
|
|
|
d0ea73 |
/* If there's no QMP schema, fall back to checking the version. */
|
|
|
d0ea73 |
@@ -616,27 +601,24 @@ guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
|
d0ea73 |
* Extract the schema from the wrapper. Note the returned ‘schema’
|
|
|
d0ea73 |
* will be an array.
|
|
|
d0ea73 |
*/
|
|
|
d0ea73 |
- schema = yajl_tree_get (data->qmp_schema_tree, return_path, yajl_t_array);
|
|
|
d0ea73 |
- if (schema == NULL)
|
|
|
d0ea73 |
+ schema = json_object_get (data->qmp_schema_tree, "return");
|
|
|
d0ea73 |
+ if (!json_is_array (schema))
|
|
|
d0ea73 |
goto fallback;
|
|
|
d0ea73 |
- assert (YAJL_IS_ARRAY(schema));
|
|
|
d0ea73 |
|
|
|
d0ea73 |
/* Now look for any member of the array which has:
|
|
|
d0ea73 |
* { "meta-type": "object",
|
|
|
d0ea73 |
* "members": [ ... { "name": "locking", ... } ... ] ... }
|
|
|
d0ea73 |
*/
|
|
|
d0ea73 |
- for (i = 0; i < YAJL_GET_ARRAY(schema)->len; ++i) {
|
|
|
d0ea73 |
- v = YAJL_GET_ARRAY(schema)->values[i];
|
|
|
d0ea73 |
- meta_type = yajl_tree_get (v, meta_type_path, yajl_t_string);
|
|
|
d0ea73 |
- if (meta_type && YAJL_IS_STRING (meta_type) &&
|
|
|
d0ea73 |
- STREQ (YAJL_GET_STRING (meta_type), "object")) {
|
|
|
d0ea73 |
- members = yajl_tree_get (v, members_path, yajl_t_array);
|
|
|
d0ea73 |
- if (members) {
|
|
|
d0ea73 |
- for (j = 0; j < YAJL_GET_ARRAY(members)->len; ++j) {
|
|
|
d0ea73 |
- m = YAJL_GET_ARRAY(members)->values[j];
|
|
|
d0ea73 |
- name = yajl_tree_get (m, name_path, yajl_t_string);
|
|
|
d0ea73 |
- if (name && YAJL_IS_STRING (name) &&
|
|
|
d0ea73 |
- STREQ (YAJL_GET_STRING (name), "locking"))
|
|
|
d0ea73 |
+ json_array_foreach (schema, i, v) {
|
|
|
d0ea73 |
+ meta_type = json_object_get (v, "meta-type");
|
|
|
d0ea73 |
+ if (json_is_string (meta_type) &&
|
|
|
d0ea73 |
+ STREQ (json_string_value (meta_type), "object")) {
|
|
|
d0ea73 |
+ members = json_object_get (v, "members");
|
|
|
d0ea73 |
+ if (json_is_array (members)) {
|
|
|
d0ea73 |
+ json_array_foreach (members, j, m) {
|
|
|
d0ea73 |
+ name = json_object_get (v, "name");
|
|
|
d0ea73 |
+ if (json_is_string (name) &&
|
|
|
d0ea73 |
+ STREQ (json_string_value (name), "locking"))
|
|
|
d0ea73 |
return 1;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
@@ -646,8 +628,6 @@ guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
|
d0ea73 |
return 0;
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-#pragma GCC diagnostic pop
|
|
|
d0ea73 |
-
|
|
|
d0ea73 |
/**
|
|
|
d0ea73 |
* Escape a qemu parameter.
|
|
|
d0ea73 |
*
|
|
|
d0ea73 |
@@ -996,7 +976,7 @@ guestfs_int_free_qemu_data (struct qemu_data *data)
|
|
|
d0ea73 |
free (data->qemu_help);
|
|
|
d0ea73 |
free (data->qemu_devices);
|
|
|
d0ea73 |
free (data->qmp_schema);
|
|
|
d0ea73 |
- yajl_tree_free (data->qmp_schema_tree);
|
|
|
d0ea73 |
+ json_decref (data->qmp_schema_tree);
|
|
|
d0ea73 |
free (data);
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
}
|
|
|
d0ea73 |
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
|
|
|
d0ea73 |
index 78a9e792f..2fdbd9669 100644
|
|
|
d0ea73 |
--- a/m4/guestfs-libraries.m4
|
|
|
d0ea73 |
+++ b/m4/guestfs-libraries.m4
|
|
|
d0ea73 |
@@ -299,8 +299,8 @@ LIBS="$LIBS $LIBXML2_LIBS"
|
|
|
d0ea73 |
AC_CHECK_FUNCS([xmlBufferDetach])
|
|
|
d0ea73 |
LIBS="$old_LIBS"
|
|
|
d0ea73 |
|
|
|
d0ea73 |
-dnl Check for yajl JSON library (required).
|
|
|
d0ea73 |
-PKG_CHECK_MODULES([YAJL], [yajl >= 2.0.4])
|
|
|
d0ea73 |
+dnl Check for Jansson JSON library (required).
|
|
|
d0ea73 |
+PKG_CHECK_MODULES([JANSSON], [jansson])
|
|
|
d0ea73 |
|
|
|
d0ea73 |
dnl Check for C++ (optional, we just use this to test the header works).
|
|
|
d0ea73 |
AC_PROG_CXX
|
|
|
d0ea73 |
--
|
|
|
ca1ab6 |
2.21.0
|
|
|
d0ea73 |
|