From 82bf36e551c25e6f6e4c4623a54da75e3f8800a4 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Mon, 27 Sep 2021 19:26:32 +0200 Subject: [PATCH] qemuBuildShmemCommandLine: Generate via JSON MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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= - ID of a chardev to use as a backend ioeventfd= - on/off (default: true) master= - on/off/auto (default: "off") vectors= - (default: 1) 'ivshmem-plain' master= - on/off/auto (default: "off") memdev=> Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- 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 dfc6ccc32f..b468297249 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9230,60 +9230,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: @@ -9291,17 +9295,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); } @@ -9337,7 +9345,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; @@ -9372,7 +9380,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: @@ -9384,20 +9392,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.47.2