6d3351
From 1da246305bff2d60828a08024cb9db5873fef49a Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <1da246305bff2d60828a08024cb9db5873fef49a@dist-git>
6d3351
From: Andrea Bolognani <abologna@redhat.com>
6d3351
Date: Mon, 17 Jul 2017 12:09:04 +0200
6d3351
Subject: [PATCH] qemu: Allow qemuBuildControllerDevStr() to return NULL
6d3351
6d3351
We will soon need to be able to return a NULL pointer
6d3351
without the caller considering that an error: to make
6d3351
it possible, change the return type to int and use
6d3351
an out parameter for the string instead.
6d3351
6d3351
Add some documentation for the function as well.
6d3351
6d3351
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
6d3351
Reviewed-by: Laine Stump <laine@laine.org>
6d3351
(cherry picked from commit 0e943cec9e0ce10565fa4d94b06eae4e46a2925d)
6d3351
6d3351
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1431193
6d3351
6d3351
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
---
6d3351
 src/qemu/qemu_command.c | 55 ++++++++++++++++++++++++++++++++++++-------------
6d3351
 src/qemu/qemu_command.h |  9 ++++----
6d3351
 src/qemu/qemu_hotplug.c |  5 ++++-
6d3351
 3 files changed, 50 insertions(+), 19 deletions(-)
6d3351
6d3351
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
6d3351
index 7ad3d16ea8..9e075e14d2 100644
6d3351
--- a/src/qemu/qemu_command.c
6d3351
+++ b/src/qemu/qemu_command.c
6d3351
@@ -2702,23 +2702,46 @@ qemuCheckSCSIControllerIOThreads(const virDomainDef *domainDef,
6d3351
 }
6d3351
 
6d3351
 
6d3351
-char *
6d3351
+/**
6d3351
+ * qemuBuildControllerDevStr:
6d3351
+ * @domainDef: domain definition
6d3351
+ * @def: controller definition
6d3351
+ * @qemuCaps: QEMU binary capabilities
6d3351
+ * @devstr: device string
6d3351
+ * @nusbcontroller: number of USB controllers
6d3351
+ *
6d3351
+ * Turn @def into a description of the controller that QEMU will understand,
6d3351
+ * to be used either on the command line or through the monitor.
6d3351
+ *
6d3351
+ * The description will be returned in @devstr and can be NULL, eg. when
6d3351
+ * passing in one of the built-in controllers. The returned string must be
6d3351
+ * freed by the caller.
6d3351
+ *
6d3351
+ * The number pointed to by @nusbcontroller will be increased by one every
6d3351
+ * time the description for a USB controller has been generated successfully.
6d3351
+ *
6d3351
+ * Returns: 0 on success, <0 on failure
6d3351
+ */
6d3351
+int
6d3351
 qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
                           virDomainControllerDefPtr def,
6d3351
                           virQEMUCapsPtr qemuCaps,
6d3351
+                          char **devstr,
6d3351
                           int *nusbcontroller)
6d3351
 {
6d3351
     virBuffer buf = VIR_BUFFER_INITIALIZER;
6d3351
     int model = def->model;
6d3351
     const char *modelName = NULL;
6d3351
 
6d3351
+    *devstr = NULL;
6d3351
+
6d3351
     if (!qemuCheckCCWS390AddressSupport(domainDef, def->info, qemuCaps,
6d3351
                                         "controller"))
6d3351
-        return NULL;
6d3351
+        return -1;
6d3351
 
6d3351
     if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
6d3351
         if ((qemuDomainSetSCSIControllerModel(domainDef, qemuCaps, &model)) < 0)
6d3351
-            return NULL;
6d3351
+            return -1;
6d3351
     }
6d3351
 
6d3351
     if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
6d3351
@@ -2726,22 +2749,22 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
         if (def->queues) {
6d3351
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
                            _("'queues' is only supported by virtio-scsi controller"));
6d3351
-            return NULL;
6d3351
+            return -1;
6d3351
         }
6d3351
         if (def->cmd_per_lun) {
6d3351
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
                            _("'cmd_per_lun' is only supported by virtio-scsi controller"));
6d3351
-            return NULL;
6d3351
+            return -1;
6d3351
         }
6d3351
         if (def->max_sectors) {
6d3351
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
                            _("'max_sectors' is only supported by virtio-scsi controller"));
6d3351
-            return NULL;
6d3351
+            return -1;
6d3351
         }
6d3351
         if (def->ioeventfd) {
6d3351
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6d3351
                            _("'ioeventfd' is only supported by virtio-scsi controller"));
6d3351
-            return NULL;
6d3351
+            return -1;
6d3351
         }
6d3351
     }
6d3351
 
6d3351
@@ -3156,11 +3179,12 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
     if (virBufferCheckError(&buf) < 0)
6d3351
         goto error;
6d3351
 
6d3351
-    return virBufferContentAndReset(&buf;;
6d3351
+    *devstr = virBufferContentAndReset(&buf;;
6d3351
+    return 0;
6d3351
 
6d3351
  error:
6d3351
     virBufferFreeAndReset(&buf;;
6d3351
-    return NULL;
6d3351
+    return -1;
6d3351
 }
6d3351
 
6d3351
 
6d3351
@@ -3255,12 +3279,15 @@ qemuBuildControllerDevCommandLine(virCommandPtr cmd,
6d3351
                 continue;
6d3351
             }
6d3351
 
6d3351
-            virCommandAddArg(cmd, "-device");
6d3351
-            if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps,
6d3351
-                                                     &usbcontroller)))
6d3351
+            if (qemuBuildControllerDevStr(def, cont, qemuCaps,
6d3351
+                                          &devstr, &usbcontroller) < 0)
6d3351
                 return -1;
6d3351
-            virCommandAddArg(cmd, devstr);
6d3351
-            VIR_FREE(devstr);
6d3351
+
6d3351
+            if (devstr) {
6d3351
+                virCommandAddArg(cmd, "-device");
6d3351
+                virCommandAddArg(cmd, devstr);
6d3351
+                VIR_FREE(devstr);
6d3351
+            }
6d3351
         }
6d3351
     }
6d3351
 
6d3351
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
6d3351
index 09cb00ee9b..9a2ab29e9a 100644
6d3351
--- a/src/qemu/qemu_command.h
6d3351
+++ b/src/qemu/qemu_command.h
6d3351
@@ -118,10 +118,11 @@ char *qemuBuildDriveDevStr(const virDomainDef *def,
6d3351
                            virQEMUCapsPtr qemuCaps);
6d3351
 
6d3351
 /* Current, best practice */
6d3351
-char *qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
-                                virDomainControllerDefPtr def,
6d3351
-                                virQEMUCapsPtr qemuCaps,
6d3351
-                                int *nusbcontroller);
6d3351
+int qemuBuildControllerDevStr(const virDomainDef *domainDef,
6d3351
+                              virDomainControllerDefPtr def,
6d3351
+                              virQEMUCapsPtr qemuCaps,
6d3351
+                              char **devstr,
6d3351
+                              int *nusbcontroller);
6d3351
 
6d3351
 int qemuBuildMemoryBackendStr(virJSONValuePtr *backendProps,
6d3351
                               const char **backendType,
6d3351
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
6d3351
index 316bc7d41e..476e2b81a3 100644
6d3351
--- a/src/qemu/qemu_hotplug.c
6d3351
+++ b/src/qemu/qemu_hotplug.c
6d3351
@@ -523,7 +523,10 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
6d3351
     if (qemuAssignDeviceControllerAlias(vm->def, priv->qemuCaps, controller) < 0)
6d3351
         goto cleanup;
6d3351
 
6d3351
-    if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL)))
6d3351
+    if (qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, &devstr, NULL) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    if (!devstr)
6d3351
         goto cleanup;
6d3351
 
6d3351
     if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0)
6d3351
-- 
6d3351
2.13.3
6d3351