[libvirt] [PATCH 1/2] qemu: add two qemu caps for lsi and virtio-scsi SCSI controllers

Guannan Ren gren at redhat.com
Tue Aug 7 06:54:34 UTC 2012


Rename qemuDefaultScsiControllerModel to qemuCheckScsiControllerModel.
When scsi model is given explicitly in XML(model > 0) checking if the
underlying QEMU support it or not first, raise error on checking failure.
If the model is not given(mode <= 0), return lsi or virtio-scsi
which is supported, lsi take the priority.
---
 src/qemu/qemu_capabilities.c |    7 +++
 src/qemu/qemu_capabilities.h |    2 +
 src/qemu/qemu_command.c      |   88 ++++++++++++++++++++++++++++++-----------
 src/qemu/qemu_command.h      |    3 +-
 4 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 85c49a2..8282ad8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -169,6 +169,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
               "virtio-s390",
               "balloon-event",
 
+              "lsi", /*100*/
+              "virtio-scsi-pci",
     );
 
 struct qemu_feature_flags {
@@ -1450,6 +1452,11 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
         strstr(str, "name \"virtio-serial-s390\""))
         qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390);
 
+    if (strstr(str, "name \"lsi53c895a\""))
+        qemuCapsSet(flags, QEMU_CAPS_SCSI_LSI);
+    if (strstr(str, "name \"virtio-scsi-pci\""))
+        qemuCapsSet(flags, QEMU_CAPS_VIRIO_SCSI_PCI);
+
     /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
     if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
         strstr(str, "name \"spicevmc\""))
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index e8251dc..d2d68a9 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -135,6 +135,8 @@ enum qemuCapsFlags {
     QEMU_CAPS_NEC_USB_XHCI       = 97, /* -device nec-usb-xhci */
     QEMU_CAPS_VIRTIO_S390        = 98, /* -device virtio-*-s390 */
     QEMU_CAPS_BALLOON_EVENT      = 99, /* Async event for balloon changes */
+    QEMU_CAPS_SCSI_LSI           = 100, /* -device lsi */
+    QEMU_CAPS_VIRIO_SCSI_PCI     = 101, /* -device virtio-scsi-pci */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6ad65a6..6a4578d 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -469,19 +469,60 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
 }
 
 static int
-qemuDefaultScsiControllerModel(virDomainDefPtr def) {
-    if (STREQ(def->os.arch, "ppc64") &&
-        STREQ(def->os.machine, "pseries")) {
-        return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
+qemuCheckScsiControllerModel(virDomainDefPtr def,
+                             virBitmapPtr qemuCaps,
+                             int *model)
+{
+    if (*model > 0) {
+        switch (*model) {
+            case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
+                if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("This QEMU doesn't support "
+                                     "lsi scsi controller"));
+                    return -1;
+                }
+                break;
+            case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
+                if (!qemuCapsGet(qemuCaps, QEMU_CAPS_VIRIO_SCSI_PCI)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("This QEMU doesn't support "
+                                     "virtio scsi controller"));
+                    return -1;
+                }
+                break;
+            case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
+                /*TODO: need checking work here if necessary */
+                break;
+            default:
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("Unsupported controller model: %s"),
+                               virDomainControllerModelSCSITypeToString(*model));
+                return -1;
+        }
     } else {
-        return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
+        if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
+            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
+        } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRIO_SCSI_PCI)) {
+            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI;
+        } else if (STREQ(def->os.arch, "ppc64") &&
+                   STREQ(def->os.machine, "pseries")) {
+            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to determine model for scsi controller"));
+            return -1;
+        }
     }
+
+    return 0;
 }
 
 /* Our custom -drive naming scheme used with id= */
 static int
 qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
-                                virDomainDiskDefPtr disk)
+                                virDomainDiskDefPtr disk,
+                                virBitmapPtr qemuCaps)
 {
     const char *prefix = virDomainDiskBusTypeToString(disk->bus);
     int controllerModel = -1;
@@ -491,11 +532,10 @@ qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
             controllerModel =
                 virDomainDiskFindControllerModel(def, disk,
                                                  VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
-        }
 
-        if (controllerModel == -1 ||
-            controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO)
-            controllerModel = qemuDefaultScsiControllerModel(def);
+            if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
+                return -1;
+        }
 
         if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
             controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
@@ -533,7 +573,7 @@ qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
 {
     if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
         if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
-            return qemuAssignDeviceDiskAliasCustom(vmdef, def);
+            return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
         else
             return qemuAssignDeviceDiskAliasFixed(def);
     } else {
@@ -850,9 +890,10 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
     return 0;
 }
 
-int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
+int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
+                                      virBitmapPtr qemuCaps)
 {
-    int i, rc;
+    int i, rc = -1;
     int model;
 
     /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */
@@ -869,9 +910,10 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
 
     for (i = 0 ; i < def->ncontrollers; i++) {
         model = def->controllers[i]->model;
-        if (model == -1 &&
-            def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
-            model = qemuDefaultScsiControllerModel(def);
+        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
+            if ((qemuCheckScsiControllerModel(def, qemuCaps, &model)) < 0)
+                return rc;
+
         if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI &&
             def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
             def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
@@ -1059,7 +1101,7 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
 {
     int rc;
 
-    rc = qemuDomainAssignSpaprVIOAddresses(def);
+    rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
     if (rc)
         return rc;
 
@@ -2434,9 +2476,8 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
         controllerModel =
             virDomainDiskFindControllerModel(def, disk,
                                              VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
-        if (controllerModel == -1 ||
-            controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO)
-            controllerModel = qemuDefaultScsiControllerModel(def);
+        if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
+            goto error;
 
         if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
             if (disk->info.addr.drive.target != 0) {
@@ -2765,10 +2806,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
     switch (def->type) {
     case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
         model = def->model;
-        if (model == -1 ||
-            model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) {
-            model = qemuDefaultScsiControllerModel(domainDef);
-        }
+        if ((qemuCheckScsiControllerModel(domainDef, qemuCaps, &model)) < 0)
+            return NULL;
+
         switch (model) {
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
             virBufferAddLit(&buf, "virtio-scsi-pci");
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 3ccf4d7..7068a81 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -178,7 +178,8 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps,
 int qemuDomainAssignAddresses(virDomainDefPtr def,
                               virBitmapPtr qemuCaps,
                               virDomainObjPtr);
-int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def);
+int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
+                                      virBitmapPtr qemuCaps);
 
 int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
                                  virBitmapPtr qemuCaps,
-- 
1.7.7.6




More information about the libvir-list mailing list