From nobody Sat Oct 4 23:29:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1759147717; cv=none; d=zohomail.com; s=zohoarc; b=XH18IDTsk1VnzcQNvwxh/eJqEutg6BuF1V3JjiLyjLo0zeSWEz8BYjIQUwUgJCjtys6CzP54/FGySn4biKKT7lZ0wwFzSJ7OgUii7RtXESpwltr6acm+8xrfeUItNiqhA78jiU4uxwbxJlDtKBPAKM69IoMO8PkLDa+UZKpqex4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759147717; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=j0zZ2dT1fhfsBSW2ysbdrRB/kmY03la1y9qVx0g8+RM=; b=mP975UsV13TwiAsW6s78xgHqTBDyvhuMy3lmQ+jtJWqQ/u4sx3znUbD1krwCymMhQu0jKOxkxU12bfLBNgIzBl93oWsyV1GllVg9fNS2t/M8o4Sla+vEK9b3PKYreunv9zW0NT/FSFU6vadFUhaKp8CnZ9hepWK0jXmKmS6Foe8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1759147717010107.56584005339585; Mon, 29 Sep 2025 05:08:37 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1132741.1471008 (Exim 4.92) (envelope-from ) id 1v3Cfj-00084w-Fb; Mon, 29 Sep 2025 12:08:03 +0000 Received: by outflank-mailman (output) from mailman id 1132741.1471008; Mon, 29 Sep 2025 12:08:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1v3Cfj-00084m-CB; Mon, 29 Sep 2025 12:08:03 +0000 Received: by outflank-mailman (input) for mailman id 1132741; Mon, 29 Sep 2025 12:08:02 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1v3Cfh-0007T0-W8 for xen-devel@lists.xenproject.org; Mon, 29 Sep 2025 12:08:01 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1v3Cfh-00GXBN-2I; Mon, 29 Sep 2025 12:08:01 +0000 Received: from [2a01:cb15:80df:da00:e2a9:ff82:7bde:38cd] (helo=l14.home) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1v3Cfh-004JHo-2O; Mon, 29 Sep 2025 12:08:01 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xenproject.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=j0zZ2dT1fhfsBSW2ysbdrRB/kmY03la1y9qVx0g8+RM=; b=SjVfFDflBZ610y32EMC0u0eAI6 mK2QfpMRNOXpBwQA3AdvIeCfnJXca8P/ioSjzurE3hO/XjNNSPXR+P415irJRrJ1UsYUb/Z7ej5/l zANGZzVHg7GzNSlM697DMa5o8S8IqWiEEMUEP3vs+xeRPkI1M/0tBIGb7cnzez1Ip3JA=; From: Anthony PERARD To: xen-devel@lists.xenproject.org Cc: Anthony PERARD , Jason Andryuk , Juergen Gross Subject: [XEN PATCH v2 3/8] libxl: convert libxl__json_object_to_yajl_gen to libxl__json_object_to_libjsonc_object Date: Mon, 29 Sep 2025 14:07:51 +0200 Message-ID: <20250929120756.46075-4-anthony@xenproject.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20250929120756.46075-1-anthony@xenproject.org> References: <20250929120756.46075-1-anthony@xenproject.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xenproject.org) X-ZM-MESSAGEID: 1759147718478116600 Content-Type: text/plain; charset="utf-8" From: Anthony PERARD 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 Reviewed-by: Jason Andryuk --- Notes: v2: - In libxl__json_object_to_json_object(), when generating a `json_object` from JSON_NUMBER, use json_object_new_double_s() instead of json_object_new_string(). This way, the json-c implementation will behave like the yajl one when number are bigger than int64, which is very unlikely. tools/include/libxl_json.h | 6 ++ tools/libs/light/libxl_internal.h | 7 +++ tools/libs/light/libxl_json.c | 100 ++++++++++++++++++++++++++++++ tools/libs/light/libxl_qmp.c | 53 ++++++++++++++++ 4 files changed, 166 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 =20 +#ifdef HAVE_LIBJSONC +#include +#endif + +#ifdef HAVE_LIBYAJL #include #include =20 #ifdef HAVE_YAJL_YAJL_VERSION_H # include #endif +#endif =20 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_int= ernal.h index 062123eed4..5204cb8889 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_ge= t(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 *ob= j); +#endif +#ifdef HAVE_LIBYAJL _hidden yajl_status libxl__json_object_to_yajl_gen(libxl__gc *gc_opt, yajl_gen hand, const libxl__json_objec= t *param); +#endif _hidden void libxl__json_object_free(libxl__gc *gc_opt, libxl__json_object *obj); =20 diff --git a/tools/libs/light/libxl_json.c b/tools/libs/light/libxl_json.c index 44ee6e213f..75b383ee14 100644 --- a/tools/libs/light/libxl_json.c +++ b/tools/libs/light/libxl_json.c @@ -631,6 +631,105 @@ const libxl__json_object *libxl__json_map_get(const c= har *key, return NULL; } =20 +#ifdef HAVE_LIBJSONC +int libxl__json_object_to_json_object(libxl__gc *gc, + json_object **jso_out, + const libxl__json_object *obj) +{ + int idx =3D 0; + int rc, r; + + switch (obj->type) { + case JSON_NULL: + *jso_out =3D json_object_new_null(); + return 0; + case JSON_BOOL: + *jso_out =3D json_object_new_boolean(obj->u.b); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_INTEGER: + *jso_out =3D json_object_new_int64(obj->u.i); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_DOUBLE: + *jso_out =3D json_object_new_double(obj->u.d); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_NUMBER: + /* + * 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 =3D json_object_new_double_s(0, obj->u.string); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_STRING: + *jso_out =3D json_object_new_string(obj->u.string); + if (!*jso_out) + return ERROR_NOMEM; + return 0; + case JSON_MAP: { + libxl__json_map_node *node =3D NULL; + json_object *map_root =3D json_object_new_object(); + json_object *node_value; + + for (idx =3D 0; idx < obj->u.map->count; idx++) { + if (flexarray_get(obj->u.map, idx, (void**)&node) !=3D 0) + break; + + rc =3D libxl__json_object_to_json_object(gc, &node_value, node= ->obj); + if (rc) { + json_object_put(map_root); + return rc; + } + + r =3D json_object_object_add(map_root, node->map_key, node_val= ue); + if (r < 0) { + json_object_put(node_value); + json_object_put(map_root); + return ERROR_FAIL; + } + } + *jso_out =3D map_root; + return 0; + } + case JSON_ARRAY: { + libxl__json_object *node =3D NULL; + json_object *array_root =3D json_object_new_array_ext(obj->u.array= ->count); + json_object *node_value; + + for (idx =3D 0; idx < obj->u.array->count; idx++) { + if (flexarray_get(obj->u.array, idx, (void**)&node) !=3D 0) + break; + + rc =3D libxl__json_object_to_json_object(gc, &node_value, node= ); + if (rc) { + json_object_put(array_root); + return rc; + } + r =3D 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 =3D 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 +797,7 @@ yajl_status libxl__json_object_to_yajl_gen(libxl__gc *g= c, abort(); #undef CONVERT_YAJL_GEN_TO_STATUS } +#endif =20 =20 /* 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 @@ =20 #include =20 +#ifdef HAVE_LIBJSONC +#include +#elif defined(HAVE_LIBYAJL) #include +#endif =20 #include "xen_list.h" #include "libxl_internal.h" @@ -481,13 +485,56 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const cha= r *cmd, const libxl__json_object *args, int id) { +#ifdef HAVE_LIBJSONC + json_object *jso =3D NULL; + json_object *jso_value =3D NULL; + /* memory for 'buf' is owned by 'jso' */ + const char *buf; + int rc, r; +#elif defined(HAVE_LIBYAJL) yajl_gen hand =3D 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 =3D NULL; =20 +#ifdef HAVE_LIBJSONC + jso =3D json_object_new_object(); + if (!jso) + goto out; + + jso_value =3D json_object_new_string(cmd); + if (!jso_value) + goto out; + r =3D json_object_object_add(jso, "execute", jso_value); + if (r < 0) + goto out; + jso_value =3D json_object_new_int(id); + if (!jso_value) + goto out; + r =3D 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 =3D NULL; + if (args) { + rc =3D libxl__json_object_to_json_object(gc, &jso_value, args); + if (rc) + goto out; + r =3D json_object_object_add(jso, "arguments", jso_value); + if (r < 0) + goto out; + jso_value =3D NULL; + } + + buf =3D json_object_to_json_string_ext(jso, JSON_C_TO_STRING_PLAIN); + ret =3D libxl__sprintf(gc, "%s\r\n", buf); + +#elif defined(HAVE_LIBYAJL) hand =3D libxl_yajl_gen_alloc(NULL); =20 if (!hand) { @@ -516,9 +563,15 @@ static char *qmp_prepare_cmd(libxl__gc *gc, const char= *cmd, goto out; =20 ret =3D libxl__sprintf(gc, "%*.*s\r\n", (int)len, (int)len, buf); +#endif =20 out: +#ifdef HAVE_LIBJSONC + json_object_put(jso_value); + json_object_put(jso); +#elif defined(HAVE_LIBYAJL) yajl_gen_free(hand); +#endif return ret; } =20 --=20 Anthony PERARD