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 <yezengruan@huawei.com> (cherry picked from commit da25da87c49d1b576b48fd58614ff43833a04f37)
372 lines
14 KiB
Diff
372 lines
14 KiB
Diff
From b43ddd42069c503980ad0d8b3439e70cf10e3323 Mon Sep 17 00:00:00 2001
|
|
From: Yan Wang <wangyan122@huawei.com>
|
|
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 <pkrempa@redhat.com>
|
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
|
Signed-off-by: Yan Wang <wangyan122@huawei.com>
|
|
---
|
|
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
|
|
|