Note that the legacy 'ivshmem' device was already removed upstream, but
it's converted so that the code is identical.
For the two modern devices QEMU considers the properties being of
following types:
'ivshmem-doorbell'
chardev=<str> - ID of a chardev to use as a backend
ioeventfd=<bool> - on/off (default: true)
master=<OnOffAuto> - on/off/auto (default: "off")
vectors=<uint32> - (default: 1)
'ivshmem-plain'
master=<OnOffAuto> - on/off/auto (default: "off")
memdev=<link<memory-backend>>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_command.c | 107 ++++++++++++++++++++++------------------
src/qemu/qemu_command.h | 7 ++-
src/qemu/qemu_hotplug.c | 6 +--
3 files changed, 64 insertions(+), 56 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 794119a58c..cbd0b2890f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9201,60 +9201,64 @@ qemuBuildSmartcardCommandLine(virLogManager *logManager,
}
-static char *
-qemuBuildShmemDevLegacyStr(virDomainDef *def,
- virDomainShmemDef *shmem,
- virQEMUCaps *qemuCaps G_GNUC_UNUSED)
+static virJSONValue *
+qemuBuildShmemDevLegacyProps(virDomainDef *def,
+ virDomainShmemDef *shmem)
{
- g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+ g_autoptr(virJSONValue) props = NULL;
+ g_autofree char *size = NULL;
+ const char *shm = NULL;
+ g_autofree char *chardev = NULL;
- virBufferAddLit(&buf, "ivshmem");
- virBufferAsprintf(&buf, ",id=%s", shmem->info.alias);
+ /* while this would result in a type error with newer qemus, the 'ivshmem'
+ * device was removed in qemu-4.0, so for the sake of not changing the
+ * commandline we do this hack */
+ size = g_strdup_printf("%llum", shmem->size >> 20);
- if (shmem->size)
- virBufferAsprintf(&buf, ",size=%llum", shmem->size >>
20);
+ if (shmem->server.enabled)
+ chardev = g_strdup_printf("char%s", shmem->info.alias);
+ else
+ shm = shmem->name;
- if (!shmem->server.enabled) {
- virBufferAsprintf(&buf, ",shm=%s", shmem->name);
- } else {
- virBufferAsprintf(&buf, ",chardev=char%s", shmem->info.alias);
- if (shmem->msi.enabled) {
- virBufferAddLit(&buf, ",msi=on");
- if (shmem->msi.vectors)
- virBufferAsprintf(&buf, ",vectors=%u",
shmem->msi.vectors);
- if (shmem->msi.ioeventfd)
- virBufferAsprintf(&buf, ",ioeventfd=%s",
-
virTristateSwitchTypeToString(shmem->msi.ioeventfd));
- }
- }
+ if (virJSONValueObjectCreate(&props,
+ "s:driver", "ivshmem",
+ "s:id", shmem->info.alias,
+ "s:size", size,
+ "S:shm", shm,
+ "S:chardev", chardev,
+ "B:msi", shmem->msi.enabled,
+ "p:vectors", shmem->msi.vectors,
+ "T:ioeventfd", shmem->msi.ioeventfd,
+ NULL) < 0)
+ return NULL;
- if (qemuBuildDeviceAddressStr(&buf, def, &shmem->info) < 0)
+ if (qemuBuildDeviceAddressProps(props, def, &shmem->info) < 0)
return NULL;
- return virBufferContentAndReset(&buf);
+ return g_steal_pointer(&props);
}
-char *
-qemuBuildShmemDevStr(virDomainDef *def,
- virDomainShmemDef *shmem,
- virQEMUCaps *qemuCaps G_GNUC_UNUSED)
-{
- g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
- virBufferAdd(&buf, virDomainShmemModelTypeToString(shmem->model), -1);
- virBufferAsprintf(&buf, ",id=%s", shmem->info.alias);
+virJSONValue *
+qemuBuildShmemDevProps(virDomainDef *def,
+ virDomainShmemDef *shmem)
+{
+ g_autoptr(virJSONValue) props = NULL;
+ g_autofree char *chardev = NULL;
+ g_autofree char *memdev = NULL;
+ virTristateSwitch master = VIR_TRISTATE_SWITCH_ABSENT;
if (shmem->server.enabled) {
- virBufferAsprintf(&buf, ",chardev=char%s", shmem->info.alias);
+ chardev = g_strdup_printf("char%s", shmem->info.alias);
} else {
- virBufferAsprintf(&buf, ",memdev=shmmem-%s",
shmem->info.alias);
+ memdev = g_strdup_printf("shmmem-%s", shmem->info.alias);
switch (shmem->role) {
case VIR_DOMAIN_SHMEM_ROLE_MASTER:
- virBufferAddLit(&buf, ",master=on");
+ master = VIR_TRISTATE_SWITCH_ON;
break;
case VIR_DOMAIN_SHMEM_ROLE_PEER:
- virBufferAddLit(&buf, ",master=off");
+ master = VIR_TRISTATE_SWITCH_OFF;
break;
case VIR_DOMAIN_SHMEM_ROLE_DEFAULT:
case VIR_DOMAIN_SHMEM_ROLE_LAST:
@@ -9262,17 +9266,21 @@ qemuBuildShmemDevStr(virDomainDef *def,
}
}
- if (shmem->msi.vectors)
- virBufferAsprintf(&buf, ",vectors=%u", shmem->msi.vectors);
- if (shmem->msi.ioeventfd) {
- virBufferAsprintf(&buf, ",ioeventfd=%s",
- virTristateSwitchTypeToString(shmem->msi.ioeventfd));
- }
+ if (virJSONValueObjectCreate(&props,
+ "s:driver",
virDomainShmemModelTypeToString(shmem->model),
+ "s:id", shmem->info.alias,
+ "S:chardev", chardev,
+ "S:memdev", memdev,
+ "S:master", qemuOnOffAuto(master),
+ "p:vectors", shmem->msi.vectors,
+ "T:ioeventfd", shmem->msi.ioeventfd,
+ NULL) < 0)
+ return NULL;
- if (qemuBuildDeviceAddressStr(&buf, def, &shmem->info) < 0)
+ if (qemuBuildDeviceAddressProps(props, def, &shmem->info) < 0)
return NULL;
- return virBufferContentAndReset(&buf);
+ return g_steal_pointer(&props);
}
@@ -9308,7 +9316,7 @@ qemuBuildShmemCommandLine(virLogManager *logManager,
bool chardevStdioLogd)
{
g_autoptr(virJSONValue) memProps = NULL;
- g_autofree char *devstr = NULL;
+ g_autoptr(virJSONValue) devProps = NULL;
g_autofree char *chardev = NULL;
unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT |
QEMU_BUILD_CHARDEV_UNIX_FD_PASS;
@@ -9343,7 +9351,7 @@ qemuBuildShmemCommandLine(virLogManager *logManager,
switch (shmem->model) {
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM:
- devstr = qemuBuildShmemDevLegacyStr(def, shmem, qemuCaps);
+ devProps = qemuBuildShmemDevLegacyProps(def, shmem);
break;
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
@@ -9355,20 +9363,21 @@ qemuBuildShmemCommandLine(virLogManager *logManager,
G_GNUC_FALLTHROUGH;
case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL:
- devstr = qemuBuildShmemDevStr(def, shmem, qemuCaps);
+ devProps = qemuBuildShmemDevProps(def, shmem);
break;
case VIR_DOMAIN_SHMEM_MODEL_LAST:
break;
}
- if (!devstr)
+ if (!devProps)
return -1;
if (qemuCommandAddExtDevice(cmd, &shmem->info) < 0)
return -1;
- virCommandAddArgList(cmd, "-device", devstr, NULL);
+ if (qemuBuildDeviceCommandlineFromJSON(cmd, devProps, qemuCaps) < 0)
+ return -1;
if (shmem->server.enabled) {
chardev = qemuBuildChrChardevStr(logManager, secManager,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 86df734c57..3cf1671c79 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -228,10 +228,9 @@ virJSONValue *qemuBuildHotpluggableCPUProps(const virDomainVcpuDef
*vcpu)
virJSONValue *qemuBuildShmemBackendMemProps(virDomainShmemDef *shmem)
ATTRIBUTE_NONNULL(1);
-char *qemuBuildShmemDevStr(virDomainDef *def,
- virDomainShmemDef *shmem,
- virQEMUCaps *qemuCaps)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+virJSONValue *
+qemuBuildShmemDevProps(virDomainDef *def,
+ virDomainShmemDef *shmem);
virJSONValue *
qemuBuildWatchdogDevProps(const virDomainDef *def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3e0c9cf981..3ee0ccd088 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3004,7 +3004,7 @@ qemuDomainAttachShmemDevice(virQEMUDriver *driver,
virDomainShmemDef *shmem)
{
int ret = -1;
- g_autofree char *shmstr = NULL;
+ g_autoptr(virJSONValue) devProps = NULL;
g_autofree char *charAlias = NULL;
g_autofree char *memAlias = NULL;
bool release_backing = false;
@@ -3040,7 +3040,7 @@ qemuDomainAttachShmemDevice(virQEMUDriver *driver,
(qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0))
return -1;
- if (!(shmstr = qemuBuildShmemDevStr(vm->def, shmem, priv->qemuCaps)))
+ if (!(devProps = qemuBuildShmemDevProps(vm->def, shmem)))
goto cleanup;
if (shmem->server.enabled) {
@@ -3067,7 +3067,7 @@ qemuDomainAttachShmemDevice(virQEMUDriver *driver,
if (qemuDomainAttachExtensionDevice(priv->mon, &shmem->info) < 0)
goto exit_monitor;
- if (qemuMonitorAddDevice(priv->mon, shmstr) < 0) {
+ if (qemuMonitorAddDeviceProps(priv->mon, &devProps) < 0) {
ignore_value(qemuDomainDetachExtensionDevice(priv->mon,
&shmem->info));
goto exit_monitor;
}
--
2.31.1