virt/libvirt/debian/patches/0015-qemu-command-Use-JSON-for-QAPIfied-object-directly.patch
Thales Elero Cervi 7a7256da11 libvirt: Fix device hot-plug on 7.0.0
The QEMU base version on 7.2+dfsg-7+deb12u5 was still causing
incompatibilities other than the ones fixed in [1].
When hot-plugging devices to instances, the error was still occurring
and extra cherry-picks [2-4] were required to be brought from master
in order to fix bug/2083929.

Patch 0014-qemu-remove-support-for-generating-yes-no-boolean-op.patch
was not strictly necessary for this fix, but it helped to smooth the
package build with the other two patches in place.

When we decide to uprev libvirt, this change will no longer be needed.

[1] https://opendev.org/starlingx/virt/commit/a4fad169adb97d5d7d6fd1ae6510db8c24fd6f3
[2] libvirt/libvirt/-/commit/29318399667114b3dd8a054f7ef898b3ba74828d
[3] libvirt/libvirt/-/commit/4f33b817b2926198ec626f10c3fca1c8aaececf6
[4] libvirt/libvirt/-/commit/f763b6e43900605308df8dbca16e4702033947e9

Test Plan:
PASS - build-pkgs -c -p libvirt
PASS - build-stx-images.sh --only stx-libvirt
PASS - Re-apply STX-O with new stx-libvirt image
PASS - Launch VM with 1 bootable volume
PASS - Attach 1 extra volume to the VM
PASS - Live-migrate the VM

Bug: 2083929

Change-Id: I19bcce19fb006e9023505e0c9d6aa67c4c0cb827
Signed-off-by: Thales Elero Cervi <thaleselero.cervi@windriver.com>
Co-authored-by: Daniel Caires <DanielMarques.Caires@windriver.com>
2024-10-18 08:34:36 -03:00

370 lines
14 KiB
Diff

From 4f33b817b2926198ec626f10c3fca1c8aaececf6 Mon Sep 17 00:00:00 2001
From: Peter Krempa <pkrempa@redhat.com>
Date: Fri, 12 Mar 2021 15:44:19 +0100
Subject: [PATCH] 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>
[ Patch defuzzed for libvirt 7.0.0]
Signed-off-by: Thales Elero Cervi <thaleselero.cervi@windriver.com>
---
src/libvirt_private.syms | 1 -
src/qemu/qemu_command.c | 106 +++++++++++++++++++++++++++------------
src/util/virqemu.c | 24 ---------
src/util/virqemu.h | 3 --
4 files changed, 73 insertions(+), 61 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c325040..e96bf96 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2955,7 +2955,6 @@ virQEMUBuildCommandLineJSONArrayBitmap;
virQEMUBuildCommandLineJSONArrayNumbered;
virQEMUBuildDriveCommandlineFromJSON;
virQEMUBuildNetdevCommandlineFromJSON;
-virQEMUBuildObjectCommandlineFromJSON;
# util/virrandom.h
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9f972a8..dafa85b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -177,6 +177,32 @@ VIR_ENUM_IMPL(qemuNumaPolicy,
);
+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",
+ virQEMUBuildCommandLineJSONArrayBitmap);
+ }
+}
+
+
/**
* qemuBuildMasterKeyCommandLine:
* @cmd: the command to modify
@@ -690,6 +716,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
@@ -700,7 +727,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;
@@ -708,7 +736,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");
@@ -876,7 +904,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");
@@ -1981,14 +2009,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");
@@ -2000,16 +2029,17 @@ 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->tlsKeySecretProps) < 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->tlsKeySecretProps, qemuCaps) < 0 ||
+ qemuBuildObjectCommandline(cmd, data->tlsProps, qemuCaps) < 0)
return -1;
if (data->driveCmd)
@@ -2072,7 +2102,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;
}
@@ -3271,7 +3302,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;
@@ -3300,7 +3331,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;
@@ -4886,7 +4917,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;
@@ -5124,7 +5156,7 @@ qemuBuildHostdevSCSICommandLine(virCommandPtr cmd,
if (!(data = qemuBuildHostdevSCSIAttachPrepare(hostdev, &backendAlias, qemuCaps)))
return -1;
- if (qemuBuildBlockStorageSourceAttachDataCommandline(cmd, data) < 0)
+ if (qemuBuildBlockStorageSourceAttachDataCommandline(cmd, data, qemuCaps) < 0)
return -1;
virCommandAddArg(cmd, "-device");
@@ -5530,7 +5562,7 @@ qemuBuildRNGCommandLine(virLogManagerPtr logManager,
if (qemuBuildRNGBackendProps(rng, &props) < 0)
return -1;
- rc = virQEMUBuildObjectCommandlineFromJSON(&buf, props);
+ rc = qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps);
if (rc < 0)
return -1;
@@ -7099,7 +7131,7 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommandPtr cmd,
priv, def, &mem, false) < 0)
return -1;
- if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0)
+ if (qemuBuildObjectCommandlineFromJSON(&buf, props, priv->qemuCaps) < 0)
return -1;
virCommandAddArg(cmd, "-object");
@@ -7172,25 +7204,31 @@ qemuBuildMemCommandLine(virCommandPtr cmd,
static int
qemuBuildIOThreadCommandLine(virCommandPtr cmd,
- const virDomainDef *def)
+ const virDomainDef *def,
+ virQEMUCaps *qemuCaps)
{
size_t i;
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 (qemuBuildObjectCommandlineFromJSON(&buf, props, qemuCaps) < 0)
+ return -1;
+
virCommandAddArg(cmd, "-object");
- virCommandAddArgFormat(cmd, "iothread,id=iothread%u",
- def->iothreadids[i]->iothread_id);
+ virCommandAddArgBuffer(cmd, &buf);
}
return 0;
+
}
@@ -7613,7 +7651,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;
}
@@ -8658,7 +8697,7 @@ qemuBuildShmemCommandLine(virLogManagerPtr logManager,
if (!(memProps = qemuBuildShmemBackendMemProps(shmem)))
return -1;
- rc = virQEMUBuildObjectCommandlineFromJSON(&buf, memProps);
+ rc = qemuBuildObjectCommandlineFromJSON(&buf, memProps, qemuCaps);
if (rc < 0)
return -1;
@@ -9523,7 +9562,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");
@@ -9547,7 +9586,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;
}
@@ -9612,7 +9652,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");
@@ -9890,7 +9930,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 aa322be..a1f57de 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -303,30 +303,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 849b7df..361abdd 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -48,9 +48,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.34.1