[PATCH 069/103] qemuBuildHostdevCommandLine: Format PCI host devices via JSON

Peter Krempa pkrempa at redhat.com
Thu Oct 7 15:17:57 UTC 2021


For properties we use these are the QEMU types:
  host=<str>             - Address (bus/device/function) of the host device, example: 04:10.0
  bootindex=<int32>
  failover_pair_id=<str>

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_command.c | 69 ++++++++++++++++++++++-------------------
 src/qemu/qemu_command.h |  6 ++--
 src/qemu/qemu_hotplug.c |  6 ++--
 3 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e8043f0055..5a1ad69148 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4721,20 +4721,23 @@ qemuBuildVideoCommandLine(virCommand *cmd,
 }


-char *
-qemuBuildPCIHostdevDevStr(const virDomainDef *def,
-                          virDomainHostdevDef *dev,
-                          virQEMUCaps *qemuCaps G_GNUC_UNUSED)
+virJSONValue *
+qemuBuildPCIHostdevDevProps(const virDomainDef *def,
+                            virDomainHostdevDef *dev)
 {
-    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+    g_autoptr(virJSONValue) props = NULL;
     virDomainHostdevSubsysPCI *pcisrc = &dev->source.subsys.u.pci;
-    int backend = pcisrc->backend;
     virDomainNetTeamingInfo *teaming;
+    g_autofree char *host = g_strdup_printf(VIR_PCI_DEVICE_ADDRESS_FMT,
+                                            pcisrc->addr.domain,
+                                            pcisrc->addr.bus,
+                                            pcisrc->addr.slot,
+                                            pcisrc->addr.function);
+    const char *failover_pair_id = NULL;

     /* caller has to assign proper passthrough backend type */
-    switch ((virDomainHostdevSubsysPCIBackendType)backend) {
+    switch ((virDomainHostdevSubsysPCIBackendType) pcisrc->backend) {
     case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
-        virBufferAddLit(&buf, "vfio-pci");
         break;

     case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
@@ -4743,25 +4746,10 @@ qemuBuildPCIHostdevDevStr(const virDomainDef *def,
     case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("invalid PCI passthrough type '%s'"),
-                       virDomainHostdevSubsysPCIBackendTypeToString(backend));
+                       virDomainHostdevSubsysPCIBackendTypeToString(pcisrc->backend));
         return NULL;
     }

-    virBufferAddLit(&buf, ",host=");
-    virBufferAsprintf(&buf,
-                      VIR_PCI_DEVICE_ADDRESS_FMT,
-                      pcisrc->addr.domain,
-                      pcisrc->addr.bus,
-                      pcisrc->addr.slot,
-                      pcisrc->addr.function);
-    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
-    if (dev->info->effectiveBootIndex > 0)
-        virBufferAsprintf(&buf, ",bootindex=%u", dev->info->effectiveBootIndex);
-    if (qemuBuildDeviceAddressStr(&buf, def, dev->info) < 0)
-        return NULL;
-    if (qemuBuildRomStr(&buf, dev->info) < 0)
-        return NULL;
-
     if (dev->parentnet)
         teaming = dev->parentnet->teaming;
     else
@@ -4769,11 +4757,29 @@ qemuBuildPCIHostdevDevStr(const virDomainDef *def,

     if (teaming &&
         teaming->type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT &&
-        teaming->persistent) {
-        virBufferAsprintf(&buf,  ",failover_pair_id=%s", teaming->persistent);
-    }
+        teaming->persistent)
+        failover_pair_id = teaming->persistent;

-    return virBufferContentAndReset(&buf);
+    if (virJSONValueObjectCreate(&props,
+                                 "s:driver", "vfio-pci",
+                                 "s:host", host,
+                                 "s:id", dev->info->alias,
+                                 "p:bootindex", dev->info->effectiveBootIndex,
+                                 NULL) < 0)
+        return NULL;
+
+    if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0)
+        return NULL;
+
+    if (qemuBuildRomProps(props, dev->info) < 0)
+        return NULL;
+
+    if (virJSONValueObjectAdd(props,
+                              "S:failover_pair_id", failover_pair_id,
+                              NULL) < 0)
+        return NULL;
+
+    return g_steal_pointer(&props);
 }


@@ -5525,12 +5531,11 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
             if (qemuCommandAddExtDevice(cmd, hostdev->info, qemuCaps) < 0)
                 return -1;

-            virCommandAddArg(cmd, "-device");
-            devstr = qemuBuildPCIHostdevDevStr(def, hostdev, qemuCaps);
-            if (!devstr)
+            if (!(devprops = qemuBuildPCIHostdevDevProps(def, hostdev)))
                 return -1;
-            virCommandAddArg(cmd, devstr);

+            if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0)
+                return -1;
             break;

         /* SCSI */
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 81cdbed384..8ad87f4277 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -165,9 +165,9 @@ qemuBuildMemoryDeviceProps(const virDomainDef *def,
                            virDomainMemoryDef *mem);

 /* Current, best practice */
-char *qemuBuildPCIHostdevDevStr(const virDomainDef *def,
-                                virDomainHostdevDef *dev,
-                                virQEMUCaps *qemuCaps);
+virJSONValue *
+qemuBuildPCIHostdevDevProps(const virDomainDef *def,
+                            virDomainHostdevDef *dev);

 virJSONValue *
 qemuBuildRNGDevProps(const virDomainDef *def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ea7028eae5..67aed2c128 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1629,7 +1629,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
                                { .hostdev = hostdev } };
     virDomainDeviceInfo *info = hostdev->info;
     int ret;
-    g_autofree char *devstr = NULL;
+    g_autoptr(virJSONValue) devprops = NULL;
     bool releaseaddr = false;
     bool teardowncgroup = false;
     bool teardownlabel = false;
@@ -1706,7 +1706,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
         goto error;
     }

-    if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
+    if (!(devprops = qemuBuildPCIHostdevDevProps(vm->def, hostdev)))
         goto error;

     qemuDomainObjEnterMonitor(driver, vm);
@@ -1714,7 +1714,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
     if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0)
         goto exit_monitor;

-    if ((ret = qemuMonitorAddDevice(priv->mon, devstr)) < 0)
+    if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0)
         ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info));

  exit_monitor:
-- 
2.31.1




More information about the libvir-list mailing list