]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuBuildShmemCommandLine: Generate via JSON
authorPeter Krempa <pkrempa@redhat.com>
Mon, 27 Sep 2021 17:26:32 +0000 (19:26 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 12 Oct 2021 08:26:03 +0000 (10:26 +0200)
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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_hotplug.c

index dfc6ccc32f13b24724bf713415be1f2056efa8d3..b468297249a31d59fbe467ac32c6f1c008e8b772 100644 (file)
@@ -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,
index 86df734c57a5fdfea72b97fb753eb6b150c0e033..3cf1671c79c4d64e737d23bb3dcec34dfb127e4e 100644 (file)
@@ -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,
index 3e0c9cf981de5c34938e11c19a71140addd98f54..3ee0ccd0881cbe36d1cf9e209065a8ae520091c0 100644 (file)
@@ -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;
     }