]> xenbits.xensource.com Git - libvirt.git/commitdiff
vbox: Add SAS controller support
authorDawid Zamirski <dzamirski@datto.com>
Tue, 7 Nov 2017 18:49:29 +0000 (13:49 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 7 Nov 2017 20:38:43 +0000 (15:38 -0500)
In VirtualBox SAS and SCSI are separate controller types whereas libvirt
does not make such distinction. This patch adds support for attaching
the VBOX SAS controllers by mapping the 'lsisas1068' controller model in
libvirt XML to VBOX SAS controller type. If VBOX VM has disks attached
to both SCSI and SAS controller libvirt domain XML will have two
<controller type='scsci'> elements with index and model attributes set
accordingly. In this case, each respective <disk> element must have
<address> element specified to assign it to respective SCSI controller.

src/vbox/vbox_common.c
src/vbox/vbox_common.h

index 8da08240ef22832d8b22b1758706a416ee22d48f..a1d9b2e7d4c6f925317b3814c38bfe9241cd6e9a 100644 (file)
@@ -312,20 +312,27 @@ vboxGenerateMediumName(PRUint32 storageBus,
     char *name = NULL;
     int total = 0;
 
-    if ((storageBus < StorageBus_IDE) ||
-        (storageBus > StorageBus_Floppy))
-        return NULL;
-
-    if (storageBus == StorageBus_IDE) {
+    switch ((enum StorageBus) storageBus) {
+    case StorageBus_IDE:
         prefix = "hd";
         total = devicePort * 2 + deviceSlot;
-    } else if ((storageBus == StorageBus_SATA) ||
-               (storageBus == StorageBus_SCSI)) {
+
+        break;
+    case StorageBus_SATA:
+    case StorageBus_SCSI:
+    case StorageBus_SAS:
         prefix = "sd";
         total = sdCount;
-    } else if (storageBus == StorageBus_Floppy) {
+
+        break;
+    case StorageBus_Floppy:
         total = deviceSlot;
         prefix = "fd";
+
+        break;
+    case StorageBus_Null:
+
+        return NULL;
     }
 
     name = virIndexToDiskName(total, prefix);
@@ -391,11 +398,17 @@ vboxSetStorageController(virDomainControllerDefPtr controller,
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC:
             vboxModel = StorageControllerType_BusLogic;
 
+            break;
+        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068:
+            /* in vbox, lsisas has a dedicated SAS bus type with no model */
+            VBOX_UTF16_FREE(controllerName);
+            VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, &controllerName);
+            vboxBusType = StorageBus_SAS;
+
             break;
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -1034,7 +1047,7 @@ static int
 vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine)
 {
     size_t i;
-    int type, ret = 0;
+    int type, ret = 0, model = -1;
     const char *src = NULL;
     nsresult rc = 0;
     virDomainDiskDefPtr disk = NULL;
@@ -1113,6 +1126,13 @@ vboxAttachDrives(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine)
         case VIR_DOMAIN_DISK_BUS_SCSI:
             VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SCSI_NAME, &storageCtlName);
 
+            model = virDomainDeviceFindControllerModel(def, &disk->info,
+                                                       VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
+            if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) {
+                VBOX_UTF16_FREE(storageCtlName);
+                VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_SAS_NAME, &storageCtlName);
+            }
+
             break;
         case VIR_DOMAIN_DISK_BUS_FDC:
             VBOX_UTF8_TO_UTF16(VBOX_CONTROLLER_FLOPPY_NAME, &storageCtlName);
@@ -3127,6 +3147,9 @@ vboxDumpStorageControllers(virDomainDefPtr def, IMachine *machine)
 
             break;
         case StorageControllerType_LsiLogicSas:
+            model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068;
+
+            break;
         case StorageControllerType_IntelAhci:
         case StorageControllerType_I82078:
         case StorageControllerType_Null:
@@ -3195,12 +3218,13 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine)
     PRBool readOnly;
     nsresult rc;
     virDomainDiskDefPtr disk = NULL;
+    virDomainControllerDefPtr ctrl = NULL;
     char *mediumLocUtf8 = NULL;
-    size_t sdCount = 0, i;
+    size_t sdCount = 0, i, j;
 
     def->ndisks = 0;
     gVBoxAPI.UArray.vboxArrayGet(&mediumAttachments, machine,
-                                 gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine));
+                 gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine));
 
     /* get the number of attachments */
     for (i = 0; i < mediumAttachments.count; i++) {
@@ -3353,15 +3377,38 @@ vboxDumpDisks(virDomainDefPtr def, vboxDriverPtr data, IMachine *machine)
 
             break;
         case StorageBus_SCSI:
+        case StorageBus_SAS:
             disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
             sdCount++;
 
+            /* In vbox, if there's a disk attached to SAS controller, there will
+             * be libvirt SCSI controller present with model "lsi1068", and we
+             * need to find its index
+             */
+            for (j = 0; j < def->ncontrollers; j++) {
+                ctrl = def->controllers[j];
+
+                if (ctrl->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
+                    continue;
+
+                if (storageBus == StorageBus_SAS &&
+                    ctrl->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) {
+                    disk->info.addr.drive.controller = ctrl->idx;
+                    break;
+                }
+
+                if (storageBus == StorageBus_SCSI &&
+                    ctrl->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068) {
+                    disk->info.addr.drive.controller = ctrl->idx;
+                    break;
+                }
+            }
+
             break;
         case StorageBus_Floppy:
             disk->bus = VIR_DOMAIN_DISK_BUS_FDC;
 
             break;
-        case StorageBus_SAS:
         case StorageBus_Null:
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Unsupported null storage bus"));
@@ -5829,7 +5876,8 @@ vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
              * in XML, but we need to update "sdCount" so that device names match
              * in domain dumpxml and snapshot dumpxml
              */
-            if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI)
+            if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI ||
+                storageBus == StorageBus_SAS)
                 sdCount++;
 
             VBOX_RELEASE(storageController);
@@ -5890,8 +5938,10 @@ vboxSnapshotGetReadWriteDisks(virDomainSnapshotDefPtr def,
         VBOX_RELEASE(disk);
         diskCount++;
 
-        if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI)
+        if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI ||
+            storageBus == StorageBus_SAS)
             sdCount++;
+
     }
     gVBoxAPI.UArray.vboxArrayRelease(&mediumAttachments);
 
@@ -6044,7 +6094,8 @@ vboxSnapshotGetReadOnlyDisks(virDomainSnapshotDefPtr def,
              * in XML, but we need to update "sdCount" so that device names match
              * in domain dumpxml and snapshot dumpxml
              */
-            if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI)
+            if (storageBus == StorageBus_SATA || storageBus == StorageBus_SCSI ||
+                storageBus == StorageBus_SAS)
                 sdCount++;
 
             VBOX_RELEASE(storageController);
@@ -6087,7 +6138,8 @@ vboxSnapshotGetReadOnlyDisks(virDomainSnapshotDefPtr def,
         } else if (storageBus == StorageBus_SATA) {
             sdCount++;
             def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SATA;
-        } else if (storageBus == StorageBus_SCSI) {
+        } else if (storageBus == StorageBus_SCSI ||
+                   storageBus == StorageBus_SAS) {
             sdCount++;
             def->dom->disks[diskCount]->bus = VIR_DOMAIN_DISK_BUS_SCSI;
         } else if (storageBus == StorageBus_Floppy) {
index 5dc87239d4f974d2d49dec09b39502ad4bb399ab..05636fea22a9b1645cc21c3be6f71205f8fb4f82 100644 (file)
@@ -332,6 +332,7 @@ enum HardDiskVariant
 # define VBOX_CONTROLLER_FLOPPY_NAME "Floppy Controller"
 # define VBOX_CONTROLLER_SATA_NAME "SATA Controller"
 # define VBOX_CONTROLLER_SCSI_NAME "SCSI Controller"
+# define VBOX_CONTROLLER_SAS_NAME "SAS Controller"
 
 /* Simplied definitions in vbox_CAPI_*.h */