From a778805101d50e65b2ff9d9922851b7c9a9f0f49 Mon Sep 17 00:00:00 2001 From: yezengruan Date: Thu, 24 Mar 2022 14:54:29 +0800 Subject: [PATCH] update patch with openeuler !58 qemuMonitorJSONSetMigrationParams: Take double pointer for @params qemuMonitorJSONAddObject: Take double pointer for @props :qemuMonitorJSONMakeCommandInternal: Clear @arguments when stolen qemuMonitorAddObject: Fix semantics of @alias qemuMonitorAddObject: Refactor cleanup util: json: Replace virJSONValueObjectSteal by virJSONValueObjectRemoveKey qemu: command: Generate commandline of 'masterKey0' secret via JSON qemu: command: Generate commandline of 'sev0' sev-guest object via JSON qemu: command: Generate commandline of iothread objects JSON qemu: capabilities: Introduce QEMU_CAPS_OBJECT_QAPIFIED qemu: monitor: Make wrapping of 'props' of 'object-add' optional qemuMonitorCreateObjectPropsWrap: Open-code in qemuBuildMemoryBackendProps qemu: monitor: Don't add 'props' wrapper if qemu has QEMU_CAPS_OBJECT_QAPIFIED qemu: command: Use JSON for QAPIfied -object directly tests: qemuxml2argv: Validate generation of JSON props for object-add qemu: capabilities: Enable detection of QEMU_CAPS_OBJECT_QAPIFIED Signed-off-by: yezengruan (cherry picked from commit da25da87c49d1b576b48fd58614ff43833a04f37) --- libvirt.spec | 36 +- ...s-Enable-detection-of-QEMU_CAPS_OBJE.patch | 33 ++ ...s-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch | 56 +++ ...erate-commandline-of-iothread-object.patch | 53 +++ ...erate-commandline-of-masterKey0-secr.patch | 54 +++ ...erate-commandline-of-sev0-sev-guest-.patch | 93 +++++ ...se-JSON-for-QAPIfied-object-directly.patch | 371 ++++++++++++++++++ ...-t-add-props-wrapper-if-qemu-has-QEM.patch | 47 +++ ...e-wrapping-of-props-of-object-add-op.patch | 198 ++++++++++ ...itorAddObject-Fix-semantics-of-alias.patch | 38 ++ qemuMonitorAddObject-Refactor-cleanup.patch | 77 ++++ ...eObjectPropsWrap-Open-code-in-qemuBu.patch | 81 ++++ ...ddObject-Take-double-pointer-for-pro.patch | 66 ++++ ...akeCommandInternal-Clear-arguments-w.patch | 122 ++++++ ...etMigrationParams-Take-double-pointe.patch | 118 ++++++ ...gv-Validate-generation-of-JSON-props.patch | 49 +++ ...e-virJSONValueObjectSteal-by-virJSON.patch | 65 +++ 17 files changed, 1556 insertions(+), 1 deletion(-) create mode 100644 qemu-capabilities-Enable-detection-of-QEMU_CAPS_OBJE.patch create mode 100644 qemu-capabilities-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch create mode 100644 qemu-command-Generate-commandline-of-iothread-object.patch create mode 100644 qemu-command-Generate-commandline-of-masterKey0-secr.patch create mode 100644 qemu-command-Generate-commandline-of-sev0-sev-guest-.patch create mode 100644 qemu-command-Use-JSON-for-QAPIfied-object-directly.patch create mode 100644 qemu-monitor-Don-t-add-props-wrapper-if-qemu-has-QEM.patch create mode 100644 qemu-monitor-Make-wrapping-of-props-of-object-add-op.patch create mode 100644 qemuMonitorAddObject-Fix-semantics-of-alias.patch create mode 100644 qemuMonitorAddObject-Refactor-cleanup.patch create mode 100644 qemuMonitorCreateObjectPropsWrap-Open-code-in-qemuBu.patch create mode 100644 qemuMonitorJSONAddObject-Take-double-pointer-for-pro.patch create mode 100644 qemuMonitorJSONMakeCommandInternal-Clear-arguments-w.patch create mode 100644 qemuMonitorJSONSetMigrationParams-Take-double-pointe.patch create mode 100644 tests-qemuxml2argv-Validate-generation-of-JSON-props.patch create mode 100644 util-json-Replace-virJSONValueObjectSteal-by-virJSON.patch diff --git a/libvirt.spec b/libvirt.spec index 44dfe1b..760824f 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -101,7 +101,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.2.0 -Release: 34 +Release: 35 License: LGPLv2+ URL: https://libvirt.org/ @@ -229,6 +229,22 @@ Patch0116: qemu-Fix-libvirt-hang-due-to-early-TPM-device-stop.patch Patch0117: qemu_tpm-Move-logfile-path-generation-into-a-separat.patch Patch0118: qemu_tpm-Generate-log-file-path-among-with-storage-p.patch Patch0119: virtpm-Fix-path-handling-in-virTPMEmulatorInit.patch +Patch0120: qemuMonitorJSONSetMigrationParams-Take-double-pointe.patch +Patch0121: qemuMonitorJSONAddObject-Take-double-pointer-for-pro.patch +Patch0122: qemuMonitorJSONMakeCommandInternal-Clear-arguments-w.patch +Patch0123: qemuMonitorAddObject-Fix-semantics-of-alias.patch +Patch0124: qemuMonitorAddObject-Refactor-cleanup.patch +Patch0125: util-json-Replace-virJSONValueObjectSteal-by-virJSON.patch +Patch0126: qemu-command-Generate-commandline-of-masterKey0-secr.patch +Patch0127: qemu-command-Generate-commandline-of-sev0-sev-guest-.patch +Patch0128: qemu-command-Generate-commandline-of-iothread-object.patch +Patch0129: qemu-capabilities-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch +Patch0130: qemu-monitor-Make-wrapping-of-props-of-object-add-op.patch +Patch0131: qemuMonitorCreateObjectPropsWrap-Open-code-in-qemuBu.patch +Patch0132: qemu-monitor-Don-t-add-props-wrapper-if-qemu-has-QEM.patch +Patch0133: qemu-command-Use-JSON-for-QAPIfied-object-directly.patch +Patch0134: tests-qemuxml2argv-Validate-generation-of-JSON-props.patch +Patch0135: qemu-capabilities-Enable-detection-of-QEMU_CAPS_OBJE.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -1963,6 +1979,24 @@ exit 0 %changelog +* Thu Mar 24 2022 yezengruan +- qemuMonitorJSONSetMigrationParams: Take double pointer for @params +- qemuMonitorJSONAddObject: Take double pointer for @props +- :qemuMonitorJSONMakeCommandInternal: Clear @arguments when stolen +- qemuMonitorAddObject: Fix semantics of @alias +- qemuMonitorAddObject: Refactor cleanup +- util: json: Replace virJSONValueObjectSteal by virJSONValueObjectRemoveKey +- qemu: command: Generate commandline of 'masterKey0' secret via JSON +- qemu: command: Generate commandline of 'sev0' sev-guest object via JSON +- qemu: command: Generate commandline of iothread objects JSON +- qemu: capabilities: Introduce QEMU_CAPS_OBJECT_QAPIFIED +- qemu: monitor: Make wrapping of 'props' of 'object-add' optional +- qemuMonitorCreateObjectPropsWrap: Open-code in qemuBuildMemoryBackendProps +- qemu: monitor: Don't add 'props' wrapper if qemu has QEMU_CAPS_OBJECT_QAPIFIED +- qemu: command: Use JSON for QAPIfied -object directly +- tests: qemuxml2argv: Validate generation of JSON props for object-add +- qemu: capabilities: Enable detection of QEMU_CAPS_OBJECT_QAPIFIED + * Sat Mar 12 2022 yezengruan - Revert libvirt: support aarch64 vtpm with parameter tpm-tis-device - qemu: Fix swtpm device with aarch64 diff --git a/qemu-capabilities-Enable-detection-of-QEMU_CAPS_OBJE.patch b/qemu-capabilities-Enable-detection-of-QEMU_CAPS_OBJE.patch new file mode 100644 index 0000000..7cb7ff6 --- /dev/null +++ b/qemu-capabilities-Enable-detection-of-QEMU_CAPS_OBJE.patch @@ -0,0 +1,33 @@ +From 50faad7d541f17426770b69117cd156a33fc5f93 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Thu, 24 Mar 2022 13:01:15 +0800 +Subject: [PATCH 16/16] qemu: capabilities: Enable detection of + QEMU_CAPS_OBJECT_QAPIFIED + +Base the detection on the presence of the 'secret' qom-type entry, which +isn't conditionally compiled in qemu. + +All caps-based test now switch to using JSON for -object. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + src/qemu/qemu_capabilities.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index e232a37b79..3b4e26822b 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -1457,6 +1457,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { + { "migrate-set-parameters/arg-type/max-bandwidth", QEMU_CAPS_MIGRATION_PARAM_BANDWIDTH }, + { "migrate-set-parameters/arg-type/downtime-limit", QEMU_CAPS_MIGRATION_PARAM_DOWNTIME }, + { "migrate-set-parameters/arg-type/xbzrle-cache-size", QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE }, ++ { "object-add/arg-type/qom-type/^secret", QEMU_CAPS_OBJECT_QAPIFIED }, + }; + + typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps; +-- +2.27.0 + diff --git a/qemu-capabilities-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch b/qemu-capabilities-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch new file mode 100644 index 0000000..eac937c --- /dev/null +++ b/qemu-capabilities-Introduce-QEMU_CAPS_OBJECT_QAPIFIE.patch @@ -0,0 +1,56 @@ +From a604b93e9f9f6033d5fe251f84591fb6474e2386 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Thu, 24 Mar 2022 12:41:43 +0800 +Subject: [PATCH 10/16] qemu: capabilities: Introduce QEMU_CAPS_OBJECT_QAPIFIED + +Starting from qemu-6.0 the parameters of -object/object-add are formally +described by the QAPI schema. Additionally this changes the nesting of +the properties as the 'props' nested object will be flattened to the +parent. + +We'll need to detect whether qemu switched to this new approach to +generate the objects with proper nesting and also allow testing. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + src/qemu/qemu_capabilities.c | 8 +++++--- + src/qemu/qemu_capabilities.h | 2 ++ + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 0fb3e74c77..e232a37b79 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -569,9 +569,11 @@ VIR_ENUM_IMPL(virQEMUCaps, + "blockdev-reopen", + "storage.werror", + +- "migration-param.bandwidth", +- "migration-param.downtime", +- "migration-param.xbzrle-cache-size", ++ "migration-param.bandwidth", ++ "migration-param.downtime", ++ "migration-param.xbzrle-cache-size", ++ ++ "object.qapified", + ); + + +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 10a6ce50e7..ffb366f84a 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -554,6 +554,8 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_MIGRATION_PARAM_DOWNTIME, /* downtime-limit field in migrate-set-parameters */ + QEMU_CAPS_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, /* xbzrle-cache-size field in migrate-set-parameters */ + ++ QEMU_CAPS_OBJECT_QAPIFIED, /* parameters for object-add are formally described */ ++ + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; + +-- +2.27.0 + diff --git a/qemu-command-Generate-commandline-of-iothread-object.patch b/qemu-command-Generate-commandline-of-iothread-object.patch new file mode 100644 index 0000000..7e03206 --- /dev/null +++ b/qemu-command-Generate-commandline-of-iothread-object.patch @@ -0,0 +1,53 @@ +From 868eae25430b00560be5f078d12137b875ce6239 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 26 Nov 2020 19:07:03 +0100 +Subject: [PATCH 09/16] qemu: command: Generate commandline of iothread objects + JSON +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The commandline generator for 'iothread' objects has a private +implementation of the properties. Convert it to JSON so that it can be +later validated. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 4ec661e4b5..be51400928 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7386,15 +7386,19 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd, + if (def->niothreadids == 0) + return 0; + +- /* Create iothread objects using the defined iothreadids list +- * and the defined id and name from the list. These may be used +- * by a disk definition which will associate to an iothread by +- * supplying a value of an id from the list +- */ + for (i = 0; i < def->niothreadids; i++) { ++ g_autoptr(virJSONValue) props = NULL; ++ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; ++ g_autofree char *alias = g_strdup_printf("iothread%u", def->iothreadids[i]->iothread_id); ++ ++ if (qemuMonitorCreateObjectProps(&props, "iothread", alias, NULL) < 0) ++ return -1; ++ ++ if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-object"); +- virCommandAddArgFormat(cmd, "iothread,id=iothread%u", +- def->iothreadids[i]->iothread_id); ++ virCommandAddArgBuffer(cmd, &buf); + } + + return 0; +-- +2.27.0 + diff --git a/qemu-command-Generate-commandline-of-masterKey0-secr.patch b/qemu-command-Generate-commandline-of-masterKey0-secr.patch new file mode 100644 index 0000000..9f87584 --- /dev/null +++ b/qemu-command-Generate-commandline-of-masterKey0-secr.patch @@ -0,0 +1,54 @@ +From b1e1413077ee5bb9f0f5eed82cf6c629d7df4ebf Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 26 Nov 2020 19:07:03 +0100 +Subject: [PATCH 07/16] qemu: command: Generate commandline of 'masterKey0' + secret via JSON +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +While the 'masterKey0' secret object will never be hotplugged we want to +generate it through JSON so that we'll be able to validate all +parameters of '-object' against the QAPI schema once 'object-add' is +qapified in qemu. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_command.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index d5d46c0892..6a861f3c8f 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -208,6 +208,7 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd, + g_autofree char *alias = NULL; + g_autofree char *path = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; ++ g_autoptr(virJSONValue) props = NULL; + + /* If the -object secret does not exist, then just return. This just + * means the domain won't be able to use a secret master key and is +@@ -229,9 +230,16 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd, + if (!(path = qemuDomainGetMasterKeyFilePath(priv->libDir))) + return -1; + ++ if (qemuMonitorCreateObjectProps(&props, "secret", alias, ++ "s:format", "raw", ++ "s:file", path, ++ NULL) < 0) ++ return -1; ++ ++ if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ return -1; ++ + virCommandAddArg(cmd, "-object"); +- virBufferAsprintf(&buf, "secret,id=%s,format=raw,file=", alias); +- virQEMUBuildBufferEscapeComma(&buf, path); + virCommandAddArgBuffer(cmd, &buf); + + return 0; +-- +2.27.0 + diff --git a/qemu-command-Generate-commandline-of-sev0-sev-guest-.patch b/qemu-command-Generate-commandline-of-sev0-sev-guest-.patch new file mode 100644 index 0000000..6e35b1e --- /dev/null +++ b/qemu-command-Generate-commandline-of-sev0-sev-guest-.patch @@ -0,0 +1,93 @@ +From 2626cba5134d81501f0fcc138c0f6d3427f7656e Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Thu, 24 Mar 2022 12:37:24 +0800 +Subject: [PATCH 08/16] qemu: command: Generate commandline of 'sev0' sev-guest + object via JSON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +While the 'sev0' sev-guest object will never be hotplugged, but we want +to generate it through JSON so that we'll be able to validate all +parameters of '-object' against the QAPI schema once 'object-add' is +qapified in qemu. + +Signed-off-by: Peter Krempa +Reviewed-by: Ján Tomko +Signed-off-by: Yan Wang +--- + src/qemu/qemu_command.c | 32 +++++++++++-------- + .../launch-security-sev.x86_64-2.12.0.args | 2 +- + 2 files changed, 19 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 6a861f3c8f..4ec661e4b5 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -9392,9 +9392,11 @@ static int + qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, + virDomainSEVDefPtr sev) + { ++ g_autoptr(virJSONValue) props = NULL; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + qemuDomainObjPrivatePtr priv = vm->privateData; +- char *path = NULL; ++ g_autofree char *dhpath = NULL; ++ g_autofree char *sessionpath = NULL; + + if (!sev) + return 0; +@@ -9402,21 +9404,23 @@ qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, + VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d", + sev->policy, sev->cbitpos, sev->reduced_phys_bits); + +- virBufferAsprintf(&buf, "sev-guest,id=sev0,cbitpos=%d", sev->cbitpos); +- virBufferAsprintf(&buf, ",reduced-phys-bits=%d", sev->reduced_phys_bits); +- virBufferAsprintf(&buf, ",policy=0x%x", sev->policy); ++ if (sev->dh_cert) ++ dhpath = g_strdup_printf("%s/dh_cert.base64", priv->libDir); + +- if (sev->dh_cert) { +- path = g_strdup_printf("%s/dh_cert.base64", priv->libDir); +- virBufferAsprintf(&buf, ",dh-cert-file=%s", path); +- VIR_FREE(path); +- } ++ if (sev->session) ++ sessionpath = g_strdup_printf("%s/session.base64", priv->libDir); + +- if (sev->session) { +- path = g_strdup_printf("%s/session.base64", priv->libDir); +- virBufferAsprintf(&buf, ",session-file=%s", path); +- VIR_FREE(path); +- } ++ if (qemuMonitorCreateObjectProps(&props, "sev-guest", "sev0", ++ "u:cbitpos", sev->cbitpos, ++ "u:reduced-phys-bits", sev->reduced_phys_bits, ++ "u:policy", sev->policy, ++ "S:dh-cert-file", dhpath, ++ "S:session-file", sessionpath, ++ NULL) < 0) ++ return -1; ++ ++ if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ return -1; + + virCommandAddArg(cmd, "-object"); + virCommandAddArgBuffer(cmd, &buf); +diff --git a/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args b/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args +index 378c3b681c..9fad85737a 100644 +--- a/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args ++++ b/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args +@@ -29,7 +29,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ + -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ + -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +--object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,\ ++-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=1,\ + dh-cert-file=/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64,\ + session-file=/tmp/lib/domain--1-QEMUGuest1/session.base64 \ + -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +-- +2.27.0 + diff --git a/qemu-command-Use-JSON-for-QAPIfied-object-directly.patch b/qemu-command-Use-JSON-for-QAPIfied-object-directly.patch new file mode 100644 index 0000000..f39a38d --- /dev/null +++ b/qemu-command-Use-JSON-for-QAPIfied-object-directly.patch @@ -0,0 +1,371 @@ +From b43ddd42069c503980ad0d8b3439e70cf10e3323 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Thu, 24 Mar 2022 12:56:50 +0800 +Subject: [PATCH 14/16] qemu: command: Use JSON for QAPIfied -object directly + +Skip the lossy conversion to legacy commandline arguments by using the +JSON props directly when -object is QAPIfied. This avoids issues with +conversion of bitmaps and also allows validation of the generated JSON +against the QMP schema in the tests. + +Since the new approach is triggered by a qemu capability the code +from 'virQEMUBuildObjectCommandlineFromJSON' in util/virqemu.c was moved +to 'qemuBuildObjectCommandlineFromJSON' in qemu/qemu_command.c which has +the virQEMUCaps type. + +Some functions needed to be modified to propagate qemuCaps. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + src/libvirt_private.syms | 1 - + src/qemu/qemu_command.c | 94 +++++++++++++++++++++++++++------------- + src/util/virqemu.c | 24 ---------- + src/util/virqemu.h | 3 -- + 4 files changed, 65 insertions(+), 57 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 861a4892be..997039868e 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2905,7 +2905,6 @@ virQEMUBuildCommandLineJSONArrayBitmap; + virQEMUBuildCommandLineJSONArrayNumbered; + virQEMUBuildDriveCommandlineFromJSON; + virQEMUBuildNetdevCommandlineFromJSON; +-virQEMUBuildObjectCommandlineFromJSON; + virQEMUBuildQemuImgKeySecretOpts; + + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index fd3b0baaf8..27b2eef8e5 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -190,6 +190,32 @@ VIR_ENUM_IMPL(qemuNumaPolicy, + "interleave", + ); + ++ ++static int ++qemuBuildObjectCommandlineFromJSON(virBuffer *buf, ++ virJSONValue *props, ++ virQEMUCaps *qemuCaps) ++{ ++ const char *type = virJSONValueObjectGetString(props, "qom-type"); ++ const char *alias = virJSONValueObjectGetString(props, "id"); ++ ++ if (!type || !alias) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("missing 'type'(%s) or 'alias'(%s) field of QOM 'object'"), ++ NULLSTR(type), NULLSTR(alias)); ++ return -1; ++ } ++ ++ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_QAPIFIED)) { ++ return virJSONValueToBuffer(props, buf, false); ++ } else { ++ virBufferAsprintf(buf, "%s,", type); ++ ++ return virQEMUBuildCommandLineJSON(props, buf, "qom-type", false, ++ virQEMUBuildCommandLineJSONArrayBitmap); ++ } ++} ++ + + /** + * qemuBuildMasterKeyCommandLine: +@@ -236,7 +262,7 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd, + NULL) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -722,6 +748,7 @@ qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo, + * qemuBuildObjectSecretCommandLine: + * @cmd: the command to modify + * @secinfo: pointer to the secret info object ++ * @qemuCaps: qemu capabilities + * + * If the secinfo is available and associated with an AES secret, + * then format the command line for the secret object. This object +@@ -732,7 +759,8 @@ qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo, + */ + static int + qemuBuildObjectSecretCommandLine(virCommandPtr cmd, +- qemuDomainSecretInfoPtr secinfo) ++ qemuDomainSecretInfoPtr secinfo, ++ virQEMUCaps *qemuCaps) + { + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props = NULL; +@@ -740,7 +768,7 @@ qemuBuildObjectSecretCommandLine(virCommandPtr cmd, + if (qemuBuildSecretInfoProps(secinfo, &props) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -761,13 +789,14 @@ qemuBuildObjectSecretCommandLine(virCommandPtr cmd, + */ + static int + qemuBuildDiskSecinfoCommandLine(virCommandPtr cmd, +- qemuDomainSecretInfoPtr secinfo) ++ qemuDomainSecretInfoPtr secinfo, ++ virQEMUCaps *qemuCaps) + { + /* Not necessary for non AES secrets */ + if (!secinfo || secinfo->type != VIR_DOMAIN_SECRET_INFO_TYPE_AES) + return 0; + +- return qemuBuildObjectSecretCommandLine(cmd, secinfo); ++ return qemuBuildObjectSecretCommandLine(cmd, secinfo, qemuCaps); + } + + +@@ -929,7 +958,7 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd, + certEncSecretAlias, qemuCaps, &props) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -2388,14 +2417,15 @@ qemuBuildFloppyCommandLineControllerOptions(virCommandPtr cmd, + + static int + qemuBuildObjectCommandline(virCommandPtr cmd, +- virJSONValuePtr objProps) ++ virJSONValuePtr objProps, ++ virQEMUCaps *qemuCaps) + { + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + + if (!objProps) + return 0; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, objProps) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, objProps, qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -2407,15 +2437,16 @@ qemuBuildObjectCommandline(virCommandPtr cmd, + + static int + qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd, +- qemuBlockStorageSourceAttachDataPtr data) ++ qemuBlockStorageSourceAttachDataPtr data, ++ virQEMUCaps *qemuCaps) + { + char *tmp; + +- if (qemuBuildObjectCommandline(cmd, data->prmgrProps) < 0 || +- qemuBuildObjectCommandline(cmd, data->authsecretProps) < 0 || +- qemuBuildObjectCommandline(cmd, data->encryptsecretProps) < 0 || +- qemuBuildObjectCommandline(cmd, data->httpcookiesecretProps) < 0 || +- qemuBuildObjectCommandline(cmd, data->tlsProps) < 0) ++ if (qemuBuildObjectCommandline(cmd, data->prmgrProps, qemuCaps) < 0 || ++ qemuBuildObjectCommandline(cmd, data->authsecretProps, qemuCaps) < 0 || ++ qemuBuildObjectCommandline(cmd, data->encryptsecretProps, qemuCaps) < 0 || ++ qemuBuildObjectCommandline(cmd, data->httpcookiesecretProps, qemuCaps) < 0 || ++ qemuBuildObjectCommandline(cmd, data->tlsProps, qemuCaps) < 0) + return -1; + + if (data->driveCmd) +@@ -2478,7 +2509,8 @@ qemuBuildDiskSourceCommandLine(virCommandPtr cmd, + + for (i = data->nsrcdata; i > 0; i--) { + if (qemuBuildBlockStorageSourceAttachDataCommandline(cmd, +- data->srcdata[i - 1]) < 0) ++ data->srcdata[i - 1], ++ qemuCaps) < 0) + return -1; + } + +@@ -3630,7 +3662,7 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def, + priv, def, &mem, false)) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(buf, props, priv->qemuCaps) < 0) + return -1; + + return rc; +@@ -3659,7 +3691,7 @@ qemuBuildMemoryDimmBackendStr(virBufferPtr buf, + priv, def, mem, true) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(buf, props, priv->qemuCaps) < 0) + return -1; + + return 0; +@@ -5289,7 +5321,8 @@ qemuBuildChrChardevStr(virLogManagerPtr logManager, + * functions can just check the config fields */ + if (chrSourcePriv && chrSourcePriv->secinfo) { + if (qemuBuildObjectSecretCommandLine(cmd, +- chrSourcePriv->secinfo) < 0) ++ chrSourcePriv->secinfo, ++ qemuCaps) < 0) + return NULL; + + tlsCertEncSecAlias = chrSourcePriv->secinfo->s.aes.alias; +@@ -5488,7 +5521,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd, + + if (qemuBuildDiskSecinfoCommandLine(cmd, srcPriv ? + srcPriv->secinfo : +- NULL) < 0) ++ NULL, qemuCaps) < 0) + return -1; + } + +@@ -5861,7 +5894,7 @@ qemuBuildRNGCommandLine(virLogManagerPtr logManager, + if (qemuBuildRNGBackendProps(rng, qemuCaps, &props) < 0) + return -1; + +- rc = virQEMUBuildObjectCommandlineFromJSON(&buf, props); ++ rc = qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps); + + if (rc < 0) + return -1; +@@ -7381,7 +7414,8 @@ qemuBuildMemCommandLine(virCommandPtr cmd, + + static int + qemuBuildIOThreadCommandLine(virCommandPtr cmd, +- const virDomainDef *def) ++ const virDomainDef *def, ++ virQEMUCaps *qemuCaps) + { + size_t i; + +@@ -7396,7 +7430,7 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd, + if (qemuMonitorCreateObjectProps(&props, "iothread", alias, NULL) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -7662,7 +7696,8 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, + + if (gfxPriv->secinfo) { + if (qemuBuildObjectSecretCommandLine(cmd, +- gfxPriv->secinfo) < 0) ++ gfxPriv->secinfo, ++ qemuCaps) < 0) + return -1; + secretAlias = gfxPriv->secinfo->s.aes.alias; + } +@@ -8688,7 +8723,7 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager, + if (!(memProps = qemuBuildShmemBackendMemProps(shmem))) + return -1; + +- rc = virQEMUBuildObjectCommandlineFromJSON(&buf, memProps); ++ rc = qemuBuildObjectCommandlineFromJSON(&buf, memProps, qemuCaps); + + if (rc < 0) + return -1; +@@ -9425,7 +9460,7 @@ qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd, + NULL) < 0) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -9611,7 +9646,7 @@ qemuBuildManagedPRCommandLine(virCommandPtr cmd, + if (!(props = qemuBuildPRManagedManagerInfoProps(priv))) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -9635,7 +9670,8 @@ qemuBuildPflashBlockdevOne(virCommandPtr cmd, + + for (i = data->nsrcdata; i > 0; i--) { + if (qemuBuildBlockStorageSourceAttachDataCommandline(cmd, +- data->srcdata[i - 1]) < 0) ++ data->srcdata[i - 1], ++ qemuCaps) < 0) + return -1; + } + +@@ -9700,7 +9736,7 @@ qemuBuildDBusVMStateCommandLine(virCommandPtr cmd, + if (!(props = qemuBuildDBusVMStateInfoProps(driver, vm))) + return -1; + +- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) ++ if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0) + return -1; + + virCommandAddArg(cmd, "-object"); +@@ -9975,7 +10011,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, + if (qemuBuildSmpCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + +- if (qemuBuildIOThreadCommandLine(cmd, def) < 0) ++ if (qemuBuildIOThreadCommandLine(cmd, def, qemuCaps) < 0) + return NULL; + + if (virDomainNumaGetNodeCount(def->numa) && +diff --git a/src/util/virqemu.c b/src/util/virqemu.c +index c2a14c9194..c331443b00 100644 +--- a/src/util/virqemu.c ++++ b/src/util/virqemu.c +@@ -319,30 +319,6 @@ virQEMUBuildNetdevCommandlineFromJSON(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'"), +- NULLSTR(type), NULLSTR(alias)); +- return -1; +- } +- +- virBufferAsprintf(buf, "%s,", type); +- +- if (virQEMUBuildCommandLineJSON(objprops, buf, "qom-type", false, +- virQEMUBuildCommandLineJSONArrayBitmap) < 0) +- return -1; +- +- return 0; +-} +- +- + char * + virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef) + { +diff --git a/src/util/virqemu.h b/src/util/virqemu.h +index b1296cb657..963ca03576 100644 +--- a/src/util/virqemu.h ++++ b/src/util/virqemu.h +@@ -53,9 +53,6 @@ char * + virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr props, + bool rawjson); + +-int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf, +- virJSONValuePtr objprops); +- + char *virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr src); + + void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str); +-- +2.27.0 + diff --git a/qemu-monitor-Don-t-add-props-wrapper-if-qemu-has-QEM.patch b/qemu-monitor-Don-t-add-props-wrapper-if-qemu-has-QEM.patch new file mode 100644 index 0000000..cd8320a --- /dev/null +++ b/qemu-monitor-Don-t-add-props-wrapper-if-qemu-has-QEM.patch @@ -0,0 +1,47 @@ +From 25f25258f0574822834c459eb414eba217b23f23 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 18:30:46 +0100 +Subject: [PATCH 13/16] qemu: monitor: Don't add 'props' wrapper if qemu has + QEMU_CAPS_OBJECT_QAPIFIED + +Set 'objectAddNoWrap' when the capability is present. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_monitor.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index dd1bf925b2..ec79fa6368 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -32,6 +32,7 @@ + #include "qemu_monitor_json.h" + #include "qemu_domain.h" + #include "qemu_process.h" ++#include "qemu_capabilities.h" + #include "virerror.h" + #include "viralloc.h" + #include "virlog.h" +@@ -666,6 +667,7 @@ qemuMonitorOpenInternal(virDomainObjPtr vm, + qemuMonitorCallbacksPtr cb, + void *opaque) + { ++ qemuDomainObjPrivatePtr priv = vm->privateData; + qemuMonitorPtr mon; + g_autoptr(GError) gerr = NULL; + +@@ -698,6 +700,9 @@ qemuMonitorOpenInternal(virDomainObjPtr vm, + mon->cb = cb; + mon->callbackOpaque = opaque; + ++ if (priv) ++ mon->objectAddNoWrap = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_QAPIFIED); ++ + if (virSetCloseExec(mon->fd) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("Unable to set monitor close-on-exec flag")); +-- +2.27.0 + diff --git a/qemu-monitor-Make-wrapping-of-props-of-object-add-op.patch b/qemu-monitor-Make-wrapping-of-props-of-object-add-op.patch new file mode 100644 index 0000000..fa7174d --- /dev/null +++ b/qemu-monitor-Make-wrapping-of-props-of-object-add-op.patch @@ -0,0 +1,198 @@ +From 80b46d6712ab8393659cff7a02c7e447f4e084ad Mon Sep 17 00:00:00 2001 +From: Peter Krempa +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 +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + 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 + diff --git a/qemuMonitorAddObject-Fix-semantics-of-alias.patch b/qemuMonitorAddObject-Fix-semantics-of-alias.patch new file mode 100644 index 0000000..3edfd53 --- /dev/null +++ b/qemuMonitorAddObject-Fix-semantics-of-alias.patch @@ -0,0 +1,38 @@ +From cf227a71451c95d2e5db3d0d79f108caf086234f Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 16:21:18 +0100 +Subject: [PATCH 04/16] qemuMonitorAddObject: Fix semantics of @alias + +The callers of qemuMonitorAddObject rely on the fact that @alias is +filled only when the object is added successfully. This is documented +but the code didn't behave like that. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_monitor.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 0447b609fd..f573292e37 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2966,11 +2966,14 @@ qemuMonitorAddObject(qemuMonitorPtr mon, + if (alias) + tmp = g_strdup(id); + +- ret = qemuMonitorJSONAddObject(mon, props); ++ if (qemuMonitorJSONAddObject(mon, props) < 0) ++ goto cleanup; + + if (alias) + *alias = g_steal_pointer(&tmp); + ++ ret = 0; ++ + cleanup: + VIR_FREE(tmp); + virJSONValueFree(*props); +-- +2.27.0 + diff --git a/qemuMonitorAddObject-Refactor-cleanup.patch b/qemuMonitorAddObject-Refactor-cleanup.patch new file mode 100644 index 0000000..98ac3d4 --- /dev/null +++ b/qemuMonitorAddObject-Refactor-cleanup.patch @@ -0,0 +1,77 @@ +From a9516cceecbf98e34619e2978192f50665d82528 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 16:23:55 +0100 +Subject: [PATCH 05/16] qemuMonitorAddObject: Refactor cleanup + +Remove freeing/clearing of @props as the function doesn't guarantee that +it happens on success, rename the variable hodling copy of the alias and +use g_autofree to automatically free it and remove the cleanup label as +well as 'ret' variable. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_monitor.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index f573292e37..188d7700a7 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2940,13 +2940,12 @@ qemuMonitorAddObject(qemuMonitorPtr mon, + { + const char *type = NULL; + const char *id = NULL; +- char *tmp = NULL; +- int ret = -1; ++ g_autofree char *aliasCopy = NULL; + + if (!*props) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("object props can't be NULL")); +- goto cleanup; ++ return -1; + } + + type = virJSONValueObjectGetString(*props, "qom-type"); +@@ -2954,31 +2953,25 @@ qemuMonitorAddObject(qemuMonitorPtr mon, + + VIR_DEBUG("type=%s id=%s", NULLSTR(type), NULLSTR(id)); + +- QEMU_CHECK_MONITOR_GOTO(mon, cleanup); ++ QEMU_CHECK_MONITOR(mon); + + if (!id || !type) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing alias or qom-type for qemu object '%s'"), + NULLSTR(type)); +- goto cleanup; ++ return -1; + } + + if (alias) +- tmp = g_strdup(id); ++ aliasCopy = g_strdup(id); + + if (qemuMonitorJSONAddObject(mon, props) < 0) +- goto cleanup; ++ return -1; + + if (alias) +- *alias = g_steal_pointer(&tmp); +- +- ret = 0; ++ *alias = g_steal_pointer(&aliasCopy); + +- cleanup: +- VIR_FREE(tmp); +- virJSONValueFree(*props); +- *props = NULL; +- return ret; ++ return 0; + } + + +-- +2.27.0 + diff --git a/qemuMonitorCreateObjectPropsWrap-Open-code-in-qemuBu.patch b/qemuMonitorCreateObjectPropsWrap-Open-code-in-qemuBu.patch new file mode 100644 index 0000000..c9c284c --- /dev/null +++ b/qemuMonitorCreateObjectPropsWrap-Open-code-in-qemuBu.patch @@ -0,0 +1,81 @@ +From dc2f20399a4ceb0781a5ffca31c251c98579f34d Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 17:08:46 +0100 +Subject: [PATCH 12/16] qemuMonitorCreateObjectPropsWrap: Open-code in + qemuBuildMemoryBackendProps + +There's just one caller left. Since qemuBuildMemoryBackendProps is too +complex to be modified for now, just move the adding of 'id' and 'qom' +type directly into the function. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_command.c | 6 ++++-- + src/qemu/qemu_monitor.c | 15 --------------- + src/qemu/qemu_monitor.h | 4 ---- + 3 files changed, 4 insertions(+), 21 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index be51400928..fd3b0baaf8 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3596,10 +3596,12 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, + rc = 0; + } + +- if (!(*backendProps = qemuMonitorCreateObjectPropsWrap(backendType, alias, +- &props))) ++ if (virJSONValueObjectPrependString(props, "id", alias) < 0 || ++ virJSONValueObjectPrependString(props, "qom-type", backendType) < 0) + return -1; + ++ *backendProps = g_steal_pointer(&props); ++ + return rc; + } + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index b7aa824f20..dd1bf925b2 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2870,21 +2870,6 @@ qemuMonitorAddDeviceArgs(qemuMonitorPtr mon, + } + + +-virJSONValuePtr +-qemuMonitorCreateObjectPropsWrap(const char *type, +- const char *alias, +- virJSONValuePtr *props) +-{ +- +- if (virJSONValueObjectPrependString(*props, "id", alias) < 0 || +- virJSONValueObjectPrependString(*props, "qom-type", type)) +- return NULL; +- +- return g_steal_pointer(props); +-} +- +- +- + /** + * qemuMonitorCreateObjectProps: + * @propsret: returns full object properties +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 561417f6c1..73c8af9e78 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -919,10 +919,6 @@ int qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon, + int qemuMonitorDelDevice(qemuMonitorPtr mon, + const char *devalias); + +-virJSONValuePtr qemuMonitorCreateObjectPropsWrap(const char *type, +- const char *alias, +- virJSONValuePtr *props); +- + int qemuMonitorCreateObjectProps(virJSONValuePtr *propsret, + const char *type, + const char *alias, +-- +2.27.0 + diff --git a/qemuMonitorJSONAddObject-Take-double-pointer-for-pro.patch b/qemuMonitorJSONAddObject-Take-double-pointer-for-pro.patch new file mode 100644 index 0000000..14df45a --- /dev/null +++ b/qemuMonitorJSONAddObject-Take-double-pointer-for-pro.patch @@ -0,0 +1,66 @@ +From 717b22f34cf5ce58be5a5223a29546e8c46e0365 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 15:32:14 +0100 +Subject: [PATCH 02/16] qemuMonitorJSONAddObject: Take double pointer for + @props + +Prepare for a refactor of qemuMonitorJSONMakeCommandInternal. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_monitor.c | 3 +-- + src/qemu/qemu_monitor_json.c | 5 +++-- + src/qemu/qemu_monitor_json.h | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 58a8741bb8..0447b609fd 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2966,8 +2966,7 @@ qemuMonitorAddObject(qemuMonitorPtr mon, + if (alias) + tmp = g_strdup(id); + +- ret = qemuMonitorJSONAddObject(mon, *props); +- *props = NULL; ++ ret = qemuMonitorJSONAddObject(mon, props); + + if (alias) + *alias = g_steal_pointer(&tmp); +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 03af998cb0..ce7f35e2ca 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -4427,12 +4427,13 @@ qemuMonitorJSONAddDevice(qemuMonitorPtr mon, + + int + qemuMonitorJSONAddObject(qemuMonitorPtr mon, +- virJSONValuePtr props) ++ virJSONValuePtr *props) + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; ++ virJSONValuePtr pr = g_steal_pointer(props); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("object-add", props))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("object-add", pr))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index af52372a93..2c0e3ec07a 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -234,7 +234,7 @@ int qemuMonitorJSONDelDevice(qemuMonitorPtr mon, + const char *devalias); + + int qemuMonitorJSONAddObject(qemuMonitorPtr mon, +- virJSONValuePtr props); ++ virJSONValuePtr *props); + + int qemuMonitorJSONDelObject(qemuMonitorPtr mon, + const char *objalias, +-- +2.27.0 + diff --git a/qemuMonitorJSONMakeCommandInternal-Clear-arguments-w.patch b/qemuMonitorJSONMakeCommandInternal-Clear-arguments-w.patch new file mode 100644 index 0000000..3455852 --- /dev/null +++ b/qemuMonitorJSONMakeCommandInternal-Clear-arguments-w.patch @@ -0,0 +1,122 @@ +From 18bcc450bbd6db8b124a8e6e218bde9846e5c3d5 Mon Sep 17 00:00:00 2001 +From: Yan Wang +Date: Thu, 24 Mar 2022 12:10:30 +0800 +Subject: [PATCH 03/16] :qemuMonitorJSONMakeCommandInternal: Clear @arguments + when stolen + +All callers of qemuMonitorJSONMakeCommandInternal will benefit from +making @arguments a double pointer and passing it to +virJSONValueObjectCreate directly which will clear it if it steals the +value. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + src/qemu/qemu_monitor_json.c | 27 ++++++++++----------------- + 1 file changed, 10 insertions(+), 17 deletions(-) + +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index ce7f35e2ca..cc6644c9c3 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -546,20 +546,18 @@ qemuMonitorJSONTransactionAdd(virJSONValuePtr actions, + * + * Create a JSON object used on the QMP monitor to call a command. + * +- * Note that @arguments is always consumed and should not be referenced after +- * the call to this function. ++ * Note that @arguments is consumed and cleared. + */ + static virJSONValuePtr + qemuMonitorJSONMakeCommandInternal(const char *cmdname, +- virJSONValuePtr arguments) ++ virJSONValuePtr *arguments) + { + virJSONValuePtr ret = NULL; + + ignore_value(virJSONValueObjectCreate(&ret, + "s:execute", cmdname, +- "A:arguments", &arguments, NULL)); ++ "A:arguments", arguments, NULL)); + +- virJSONValueFree(arguments); + return ret; + } + +@@ -569,7 +567,7 @@ qemuMonitorJSONMakeCommand(const char *cmdname, + ...) + { + virJSONValuePtr obj = NULL; +- virJSONValuePtr jargs = NULL; ++ g_autoptr(virJSONValue) jargs = NULL; + va_list args; + + va_start(args, cmdname); +@@ -577,7 +575,7 @@ qemuMonitorJSONMakeCommand(const char *cmdname, + if (virJSONValueObjectCreateVArgs(&jargs, args) < 0) + goto cleanup; + +- obj = qemuMonitorJSONMakeCommandInternal(cmdname, jargs); ++ obj = qemuMonitorJSONMakeCommandInternal(cmdname, &jargs); + + cleanup: + va_end(args); +@@ -3469,9 +3467,8 @@ qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; +- virJSONValuePtr par = g_steal_pointer(params); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("migrate-set-parameters", par))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("migrate-set-parameters", params))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +@@ -3998,9 +3995,8 @@ qemuMonitorJSONAddNetdev(qemuMonitorPtr mon, + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; +- virJSONValuePtr pr = g_steal_pointer(props); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("netdev_add", pr))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("netdev_add", props))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +@@ -4431,9 +4427,8 @@ qemuMonitorJSONAddObject(qemuMonitorPtr mon, + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; +- virJSONValuePtr pr = g_steal_pointer(props); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("object-add", pr))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("object-add", props))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +@@ -8812,9 +8807,8 @@ qemuMonitorJSONBlockdevAdd(qemuMonitorPtr mon, + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; +- virJSONValuePtr pr = g_steal_pointer(props); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-add", pr))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-add", props))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +@@ -8833,9 +8827,8 @@ qemuMonitorJSONBlockdevReopen(qemuMonitorPtr mon, + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; +- virJSONValuePtr pr = g_steal_pointer(props); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", pr))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("blockdev-reopen", props))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +-- +2.27.0 + diff --git a/qemuMonitorJSONSetMigrationParams-Take-double-pointe.patch b/qemuMonitorJSONSetMigrationParams-Take-double-pointe.patch new file mode 100644 index 0000000..c9c3696 --- /dev/null +++ b/qemuMonitorJSONSetMigrationParams-Take-double-pointe.patch @@ -0,0 +1,118 @@ +From 3c3f616a826b5c0cd1a01faafa2f1f6c71494e05 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 15:17:34 +0100 +Subject: [PATCH 01/16] qemuMonitorJSONSetMigrationParams: Take double pointer + for @params + +This allows simplification of the caller as well as will enable a later +refactor of qemuMonitorJSONMakeCommandInternal. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/qemu/qemu_migration_params.c | 9 +++------ + src/qemu/qemu_monitor.c | 11 +++-------- + src/qemu/qemu_monitor.h | 2 +- + src/qemu/qemu_monitor_json.c | 5 +++-- + src/qemu/qemu_monitor_json.h | 2 +- + 5 files changed, 11 insertions(+), 18 deletions(-) + +diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c +index 6953badcfe..df9d5d205a 100644 +--- a/src/qemu/qemu_migration_params.c ++++ b/src/qemu/qemu_migration_params.c +@@ -880,12 +880,9 @@ qemuMigrationParamsApply(virQEMUDriverPtr driver, + if (!(params = qemuMigrationParamsToJSON(migParams))) + goto cleanup; + +- if (virJSONValueObjectKeysNumber(params) > 0) { +- rc = qemuMonitorSetMigrationParams(priv->mon, params); +- params = NULL; +- if (rc < 0) +- goto cleanup; +- } ++ if (virJSONValueObjectKeysNumber(params) > 0 && ++ qemuMonitorSetMigrationParams(priv->mon, ¶ms) < 0) ++ goto cleanup; + + ret = 0; + +diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c +index 9f4432ab3a..58a8741bb8 100644 +--- a/src/qemu/qemu_monitor.c ++++ b/src/qemu/qemu_monitor.c +@@ -2463,22 +2463,17 @@ qemuMonitorGetMigrationParams(qemuMonitorPtr mon, + * @mon: Pointer to the monitor object. + * @params: Migration parameters. + * +- * The @params object is consumed and should not be referenced by the caller +- * after this function returns. ++ * The @params object is consumed and cleared on success and some errors. + * + * Returns 0 on success, -1 on error. + */ + int + qemuMonitorSetMigrationParams(qemuMonitorPtr mon, +- virJSONValuePtr params) ++ virJSONValuePtr *params) + { +- QEMU_CHECK_MONITOR_GOTO(mon, error); ++ QEMU_CHECK_MONITOR(mon); + + return qemuMonitorJSONSetMigrationParams(mon, params); +- +- error: +- virJSONValueFree(params); +- return -1; + } + + +diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h +index 83a33b5b0f..561417f6c1 100644 +--- a/src/qemu/qemu_monitor.h ++++ b/src/qemu/qemu_monitor.h +@@ -754,7 +754,7 @@ int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, + int qemuMonitorGetMigrationParams(qemuMonitorPtr mon, + virJSONValuePtr *params); + int qemuMonitorSetMigrationParams(qemuMonitorPtr mon, +- virJSONValuePtr params); ++ virJSONValuePtr *params); + + typedef enum { + QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, +diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c +index 199b73eafe..03af998cb0 100644 +--- a/src/qemu/qemu_monitor_json.c ++++ b/src/qemu/qemu_monitor_json.c +@@ -3465,12 +3465,13 @@ qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, + + int + qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, +- virJSONValuePtr params) ++ virJSONValuePtr *params) + { + g_autoptr(virJSONValue) cmd = NULL; + g_autoptr(virJSONValue) reply = NULL; ++ virJSONValuePtr par = g_steal_pointer(params); + +- if (!(cmd = qemuMonitorJSONMakeCommandInternal("migrate-set-parameters", params))) ++ if (!(cmd = qemuMonitorJSONMakeCommandInternal("migrate-set-parameters", par))) + return -1; + + if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) +diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h +index dd25e5d6e6..af52372a93 100644 +--- a/src/qemu/qemu_monitor_json.h ++++ b/src/qemu/qemu_monitor_json.h +@@ -142,7 +142,7 @@ int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, + int qemuMonitorJSONGetMigrationParams(qemuMonitorPtr mon, + virJSONValuePtr *params); + int qemuMonitorJSONSetMigrationParams(qemuMonitorPtr mon, +- virJSONValuePtr params); ++ virJSONValuePtr *params); + + int qemuMonitorJSONGetMigrationStats(qemuMonitorPtr mon, + qemuMonitorMigrationStatsPtr stats, +-- +2.27.0 + diff --git a/tests-qemuxml2argv-Validate-generation-of-JSON-props.patch b/tests-qemuxml2argv-Validate-generation-of-JSON-props.patch new file mode 100644 index 0000000..f58186e --- /dev/null +++ b/tests-qemuxml2argv-Validate-generation-of-JSON-props.patch @@ -0,0 +1,49 @@ +From 798600dd1fd6d0d96661f9c2b5cbd6e8ae96a229 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Thu, 26 Nov 2020 18:35:55 +0100 +Subject: [PATCH 15/16] tests: qemuxml2argv: Validate generation of JSON props + for object-add + +Similarly to the validation for blockdev-add and netdev_add, use the +qemuxml2argv test repository to drive validation of props for +object-add. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +Signed-off-by: Yan Wang +--- + tests/qemuxml2argvtest.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 47fce1c3bf..e07d6cf398 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -546,6 +546,24 @@ testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv, + return -1; + } + ++ i++; ++ } else if (STREQ(args[i], "-object")) { ++ ++ if (*args[i + 1] != '{') { ++ i++; ++ continue; ++ } ++ ++ if (!(jsonargs = virJSONValueFromString(args[i + 1]))) ++ return -1; ++ ++ if (testQEMUSchemaValidateCommand("object-add", jsonargs, ++ schema, &debug) < 0) { ++ VIR_TEST_VERBOSE("failed to validate -object '%s' against QAPI schema: %s", ++ args[i + 1], virBufferCurrentContent(&debug)); ++ return -1; ++ } ++ + i++; + } + } +-- +2.27.0 + diff --git a/util-json-Replace-virJSONValueObjectSteal-by-virJSON.patch b/util-json-Replace-virJSONValueObjectSteal-by-virJSON.patch new file mode 100644 index 0000000..b776156 --- /dev/null +++ b/util-json-Replace-virJSONValueObjectSteal-by-virJSON.patch @@ -0,0 +1,65 @@ +From bca866e875d4f1a4f02f792201cf5e46cdafe4f5 Mon Sep 17 00:00:00 2001 +From: Peter Krempa +Date: Mon, 30 Nov 2020 14:59:38 +0100 +Subject: [PATCH 06/16] util: json: Replace virJSONValueObjectSteal by + virJSONValueObjectRemoveKey + +virJSONValueObjectRemoveKey can be used as direct replacement. Fix the +one caller and remove the duplicate function. + +Signed-off-by: Peter Krempa +Reviewed-by: Michal Privoznik +--- + src/util/virjson.c | 29 ++++------------------------- + 1 file changed, 4 insertions(+), 25 deletions(-) + +diff --git a/src/util/virjson.c b/src/util/virjson.c +index 6921eccb60..6626e78255 100644 +--- a/src/util/virjson.c ++++ b/src/util/virjson.c +@@ -888,30 +888,6 @@ virJSONValueObjectGet(virJSONValuePtr object, + } + + +-static virJSONValuePtr +-virJSONValueObjectSteal(virJSONValuePtr object, +- const char *key) +-{ +- size_t i; +- virJSONValuePtr obj = NULL; +- +- if (object->type != VIR_JSON_TYPE_OBJECT) +- return NULL; +- +- for (i = 0; i < object->data.object.npairs; i++) { +- if (STREQ(object->data.object.pairs[i].key, key)) { +- obj = g_steal_pointer(&object->data.object.pairs[i].value); +- VIR_FREE(object->data.object.pairs[i].key); +- VIR_DELETE_ELEMENT(object->data.object.pairs, i, +- object->data.object.npairs); +- break; +- } +- } +- +- return obj; +-} +- +- + /* Return the value associated with KEY within OBJECT, but return NULL + * if the key is missing or if value is not the correct TYPE. */ + virJSONValuePtr +@@ -934,7 +910,10 @@ virJSONValueObjectStealByType(virJSONValuePtr object, + const char *key, + virJSONType type) + { +- virJSONValuePtr value = virJSONValueObjectSteal(object, key); ++ virJSONValuePtr value; ++ ++ if (virJSONValueObjectRemoveKey(object, key, &value) <= 0) ++ return NULL; + + if (value && value->type == type) + return value; +-- +2.27.0 + -- Gitee