[PATCH 090/103] qemuBuildControllersByTypeCommandLine: Generate via JSON

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


The handlers for PCI, SCSI and USB controllers already use JSON
internally. This patch converts 'virtio-serial', 'ccid' and 'sata' to do
the same and passes out the JSON directly so that it can be used in
monitor code to avoid conversion.

>From the controllers converted in this patch only 'virtio-serial' has
special properties. QEMU thinks they have the following types:

  max_ports=<uint32>     -  (default: 31)
  vectors=<uint32>       -  (default: 2)

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_command.c | 122 +++++++++++++++-------------------------
 src/qemu/qemu_command.h |   9 +--
 src/qemu/qemu_hotplug.c |   8 +--
 3 files changed, 54 insertions(+), 85 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2f1d4b846a..81b1eb5980 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2866,16 +2866,12 @@ qemuBuildUSBControllerDevProps(const virDomainDef *domainDef,
             return NULL;
     }

-    if (qemuBuildDeviceAddressProps(props, domainDef, &def->info) < 0)
-        return NULL;
-
     return g_steal_pointer(&props);
 }


 static virJSONValue *
-qemuBuildControllerSCSIDevProps(const virDomainDef *domainDef,
-                                virDomainControllerDef *def,
+qemuBuildControllerSCSIDevProps(virDomainControllerDef *def,
                                 virQEMUCaps *qemuCaps)
 {
     g_autoptr(virJSONValue) props = NULL;
@@ -2948,16 +2944,12 @@ qemuBuildControllerSCSIDevProps(const virDomainDef *domainDef,
             return NULL;
     }

-    if (qemuBuildDeviceAddressProps(props, domainDef, &def->info) < 0)
-        return NULL;
-
     return g_steal_pointer(&props);
 }


 static int
 qemuBuildControllerPCIDevProps(virDomainControllerDef *def,
-                               const virDomainDef *domainDef,
                                virJSONValue **devprops)
 {
     g_autoptr(virJSONValue) props = NULL;
@@ -3054,9 +3046,6 @@ qemuBuildControllerPCIDevProps(virDomainControllerDef *def,
         return -1;
     }

-    if (qemuBuildDeviceAddressProps(props, domainDef, &def->info) < 0)
-        return -1;
-
     *devprops = g_steal_pointer(&props);
     return 0;
 }
@@ -3068,8 +3057,7 @@ qemuBuildControllerPCIDevProps(virDomainControllerDef *def,
  * @domainDef: domain definition
  * @def: controller definition
  * @qemuCaps: QEMU binary capabilities
- * @devstr: device string
- * @nusbcontroller: number of USB controllers
+ * @devprops: filled with JSON object describing @def
  *
  * Turn @def into a description of the controller that QEMU will understand,
  * to be used either on the command line or through the monitor.
@@ -3084,89 +3072,65 @@ qemuBuildControllerPCIDevProps(virDomainControllerDef *def,
  * Returns: 0 on success, <0 on failure
  */
 int
-qemuBuildControllerDevStr(const virDomainDef *domainDef,
-                          virDomainControllerDef *def,
-                          virQEMUCaps *qemuCaps,
-                          char **devstr)
+qemuBuildControllerDevProps(const virDomainDef *domainDef,
+                            virDomainControllerDef *def,
+                            virQEMUCaps *qemuCaps,
+                            virJSONValue **devprops)
 {
-    g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
     g_autoptr(virJSONValue) props = NULL;
-    const char *driver = NULL;

-    *devstr = NULL;
+    *devprops = NULL;

     switch ((virDomainControllerType)def->type) {
     case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
-        if (!(props = qemuBuildControllerSCSIDevProps(domainDef, def, qemuCaps)))
+        if (!(props = qemuBuildControllerSCSIDevProps(def, qemuCaps)))
             return -1;

-        driver = virJSONValueObjectGetString(props, "driver");
-
-        virBufferAsprintf(&buf, "%s,", driver);
+        break;

-        if (virQEMUBuildCommandLineJSON(props, &buf, "driver", NULL) < 0)
+    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
+        if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_CONTROLLER, def,
+                                              qemuCaps)))
             return -1;

-        *devstr = virBufferContentAndReset(&buf);
-
-        return 0;
-
-    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
-        if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_CONTROLLER, def) < 0) {
+        if (virJSONValueObjectAdd(props,
+                                  "s:id", def->info.alias,
+                                  "k:max_ports", def->opts.vioserial.ports,
+                                  "k:vectors", def->opts.vioserial.vectors,
+                                  NULL) < 0)
             return -1;
-        }

-        virBufferAsprintf(&buf, ",id=%s", def->info.alias);
-        if (def->opts.vioserial.ports != -1) {
-            virBufferAsprintf(&buf, ",max_ports=%d",
-                              def->opts.vioserial.ports);
-        }
-        if (def->opts.vioserial.vectors != -1) {
-            virBufferAsprintf(&buf, ",vectors=%d",
-                              def->opts.vioserial.vectors);
-        }
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
-        virBufferAsprintf(&buf, "usb-ccid,id=%s", def->info.alias);
+        if (virJSONValueObjectCreate(&props,
+                                     "s:driver", "usb-ccid",
+                                     "s:id", def->info.alias,
+                                     NULL) < 0)
+            return -1;
+
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
-        virBufferAsprintf(&buf, "ahci,id=%s", def->info.alias);
+        if (virJSONValueObjectCreate(&props,
+                                     "s:driver", "ahci",
+                                     "s:id", def->info.alias,
+                                     NULL) < 0)
+            return -1;
+
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_USB:
         if (!(props = qemuBuildUSBControllerDevProps(domainDef, def, qemuCaps)))
             return -1;

-        driver = virJSONValueObjectGetString(props, "driver");
-
-        virBufferAsprintf(&buf, "%s,", driver);
-
-        if (virQEMUBuildCommandLineJSON(props, &buf, "driver", NULL) < 0)
-            return -1;
-
-        *devstr = virBufferContentAndReset(&buf);
-
-        return 0;
         break;

     case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
-        if (qemuBuildControllerPCIDevProps(def, domainDef, &props) < 0)
+        if (qemuBuildControllerPCIDevProps(def, &props) < 0)
             return -1;

-        if (!props)
-            return 0;
-
-        driver = virJSONValueObjectGetString(props, "driver");
-
-        virBufferAsprintf(&buf, "%s,", driver);
-
-        if (virQEMUBuildCommandLineJSON(props, &buf, "driver", NULL) < 0)
-            return -1;
-
-        *devstr = virBufferContentAndReset(&buf);
-        return 0;
+        break;

     case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
     case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
@@ -3179,10 +3143,13 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
         return -1;
     }

-    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info) < 0)
+    if (!props)
+        return 0;
+
+    if (qemuBuildDeviceAddressProps(props, domainDef, &def->info) < 0)
         return -1;

-    *devstr = virBufferContentAndReset(&buf);
+    *devprops = g_steal_pointer(&props);
     return 0;
 }

@@ -3313,7 +3280,7 @@ qemuBuildControllersByTypeCommandLine(virCommand *cmd,

     for (i = 0; i < def->ncontrollers; i++) {
         virDomainControllerDef *cont = def->controllers[i];
-        g_autofree char *devstr = NULL;
+        g_autoptr(virJSONValue) props = NULL;

         if (cont->type != type)
             continue;
@@ -3349,16 +3316,17 @@ qemuBuildControllersByTypeCommandLine(virCommand *cmd,
             continue;
         }

-        if (qemuBuildControllerDevStr(def, cont, qemuCaps, &devstr) < 0)
+        if (qemuBuildControllerDevProps(def, cont, qemuCaps, &props) < 0)
             return -1;

-        if (devstr) {
-            if (qemuCommandAddExtDevice(cmd, &cont->info, qemuCaps) < 0)
-                return -1;
+        if (!props)
+            continue;

-            virCommandAddArg(cmd, "-device");
-            virCommandAddArg(cmd, devstr);
-        }
+        if (qemuCommandAddExtDevice(cmd, &cont->info, qemuCaps) < 0)
+            return -1;
+
+        if (qemuBuildDeviceCommandlineFromJSON(cmd, props, qemuCaps) < 0)
+            return -1;
     }

     return 0;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 29db16e729..cf57fc9a41 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -147,10 +147,11 @@ qemuBuildVHostUserFsDevStr(virDomainFSDef *fs,
                            qemuDomainObjPrivate *priv);

 /* Current, best practice */
-int qemuBuildControllerDevStr(const virDomainDef *domainDef,
-                              virDomainControllerDef *def,
-                              virQEMUCaps *qemuCaps,
-                              char **devstr);
+int
+qemuBuildControllerDevProps(const virDomainDef *domainDef,
+                            virDomainControllerDef *def,
+                            virQEMUCaps *qemuCaps,
+                            virJSONValue **devprops);

 int qemuBuildMemoryBackendProps(virJSONValue **backendProps,
                                 const char *alias,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1c0056da16..f55cedc784 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -828,7 +828,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriver *driver,
 {
     int ret = -1;
     const char* type = virDomainControllerTypeToString(controller->type);
-    g_autofree char *devstr = NULL;
+    g_autoptr(virJSONValue) devprops = NULL;
     qemuDomainObjPrivate *priv = vm->privateData;
     virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_CONTROLLER,
                                { .controller = controller } };
@@ -862,10 +862,10 @@ int qemuDomainAttachControllerDevice(virQEMUDriver *driver,
     if (qemuAssignDeviceControllerAlias(vm->def, controller) < 0)
         goto cleanup;

-    if (qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, &devstr) < 0)
+    if (qemuBuildControllerDevProps(vm->def, controller, priv->qemuCaps, &devprops) < 0)
         goto cleanup;

-    if (!devstr)
+    if (!devprops)
         goto cleanup;

     VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1);
@@ -877,7 +877,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriver *driver,
         goto exit_monitor;
     }

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

  exit_monitor:
-- 
2.31.1




More information about the libvir-list mailing list