From 80b46d6712ab8393659cff7a02c7e447f4e084ad Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 30 Nov 2020 16:03:57 +0100
Subject: [PATCH 11/16] qemu: monitor: Make wrapping of 'props' of 'object-add'
 optional

Construct the JSON object which is used for object-add without the
'props' wrapper and add the wrapper only in the monitor code.

This simplifies the JSON->commandline generator in the first place and
also prepares for upcoming qemu where 'props' will be removed.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Yan Wang <wangyan122@huawei.com>
---
 src/qemu/qemu_monitor.c | 68 +++++++++++++++++++++++++++++------------
 src/util/virqemu.c      | 34 ++++++---------------
 2 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 188d7700a7..b7aa824f20 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -112,6 +112,9 @@ struct _qemuMonitor {
     qemuMonitorReportDomainLogError logFunc;
     void *logOpaque;
     virFreeCallback logDestroy;
+
+    /* true if qemu no longer wants 'props' sub-object of object-add */
+    bool objectAddNoWrap;
 };
 
 /**
@@ -2872,14 +2875,12 @@ qemuMonitorCreateObjectPropsWrap(const char *type,
                                  const char *alias,
                                  virJSONValuePtr *props)
 {
-    virJSONValuePtr ret;
 
-    ignore_value(virJSONValueObjectCreate(&ret,
-                                          "s:qom-type", type,
-                                          "s:id", alias,
-                                          "A:props", props,
-                                          NULL));
-    return ret;
+    if (virJSONValueObjectPrependString(*props, "id", alias) < 0 ||
+        virJSONValueObjectPrependString(*props, "qom-type", type))
+        return NULL;
+
+    return g_steal_pointer(props);
 }
 
 
@@ -2899,26 +2900,28 @@ qemuMonitorCreateObjectProps(virJSONValuePtr *propsret,
                              const char *alias,
                              ...)
 {
-    virJSONValuePtr props = NULL;
-    int ret = -1;
+    g_autoptr(virJSONValue) props = NULL;
+    int rc;
     va_list args;
 
-    *propsret = NULL;
+    if (virJSONValueObjectCreate(&props,
+                                 "s:qom-type", type,
+                                 "s:id", alias,
+                                 NULL) < 0)
+        return -1;
+
 
     va_start(args, alias);
 
-    if (virJSONValueObjectCreateVArgs(&props, args) < 0)
-        goto cleanup;
+    rc = virJSONValueObjectAddVArgs(props, args);
 
-    if (!(*propsret = qemuMonitorCreateObjectPropsWrap(type, alias, &props)))
-        goto cleanup;
+    va_end(args);
 
-    ret = 0;
+    if (rc < 0)
+        return -1;
 
- cleanup:
-    virJSONValueFree(props);
-    va_end(args);
-    return ret;
+    *propsret = g_steal_pointer(&props);
+    return 0;
 }
 
 
@@ -2938,6 +2941,7 @@ qemuMonitorAddObject(qemuMonitorPtr mon,
                      virJSONValuePtr *props,
                      char **alias)
 {
+    g_autoptr(virJSONValue) pr = NULL;
     const char *type = NULL;
     const char *id = NULL;
     g_autofree char *aliasCopy = NULL;
@@ -2965,7 +2969,31 @@ qemuMonitorAddObject(qemuMonitorPtr mon,
     if (alias)
         aliasCopy = g_strdup(id);
 
-    if (qemuMonitorJSONAddObject(mon, props) < 0)
+    if (mon->objectAddNoWrap) {
+        pr = g_steal_pointer(props);
+    } else {
+        /* we need to create a wrapper which has the 'qom-type' and 'id' and
+         * store everything else under a 'props' sub-object */
+        g_autoptr(virJSONValue) typeobj = NULL;
+        g_autoptr(virJSONValue) idobj = NULL;
+
+        ignore_value(virJSONValueObjectRemoveKey(*props, "qom-type", &typeobj));
+        ignore_value(virJSONValueObjectRemoveKey(*props, "id", &idobj));
+
+        if (!virJSONValueObjectGetKey(*props, 0)) {
+            virJSONValueFree(*props);
+            *props = NULL;
+        }
+
+        if (virJSONValueObjectCreate(&pr,
+                                     "s:qom-type", type,
+                                     "s:id", id,
+                                     "A:props", props,
+                                     NULL) < 0)
+            return -1;
+    }
+
+    if (qemuMonitorJSONAddObject(mon, &pr) < 0)
         return -1;
 
     if (alias)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 321ddeb7e3..c2a14c9194 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -319,12 +319,13 @@ virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props,
 }
 
 
-static int
-virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
-                                              const char *type,
-                                              const char *alias,
-                                              virJSONValuePtr props)
+int
+virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
+                                      virJSONValuePtr objprops)
 {
+    const char *type = virJSONValueObjectGetString(objprops, "qom-type");
+    const char *alias = virJSONValueObjectGetString(objprops, "id");
+
     if (!type || !alias) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("missing 'type'(%s) or 'alias'(%s) field of QOM 'object'"),
@@ -332,31 +333,16 @@ virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
         return -1;
     }
 
-    virBufferAsprintf(buf, "%s,id=%s", type, alias);
+    virBufferAsprintf(buf, "%s,", type);
 
-    if (props) {
-        virBufferAddLit(buf, ",");
-        if (virQEMUBuildCommandLineJSON(props, buf, NULL, false,
-                                virQEMUBuildCommandLineJSONArrayBitmap) < 0)
-            return -1;
-    }
+    if (virQEMUBuildCommandLineJSON(objprops, buf, "qom-type", false,
+                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0)
+        return -1;
 
     return 0;
 }
 
 
-int
-virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf,
-                                      virJSONValuePtr objprops)
-{
-    const char *type = virJSONValueObjectGetString(objprops, "qom-type");
-    const char *alias = virJSONValueObjectGetString(objprops, "id");
-    virJSONValuePtr props = virJSONValueObjectGetObject(objprops, "props");
-
-    return virQEMUBuildObjectCommandlineFromJSONInternal(buf, type, alias, props);
-}
-
-
 char *
 virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef)
 {
-- 
2.27.0

