diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index 3c48c772a8..bc7e1a0201 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -308,6 +308,21 @@ ethernet0.checkMACAddress = "false"

Here a domain XML snippet:

+
+    ...
+    <disk type='file' device='disk'>
+      <source file='[local-storage] Fedora11/Fedora11.vmdk'/>
+      <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='lsilogic'/>
+    ...
+
+

+ The controller element is supported since 0.8.2. + Prior to this <driver name='lsilogic'/> was abused to + specify the SCSI controller model. This attribute usage is deprecated now. +

     ...
     <disk type='file' device='disk'>
@@ -393,7 +408,7 @@ ide0:0.startConnected = "false"
 ethernet0.present = "true"
 ethernet0.networkName = "VM Network"
 ethernet0.addressType = "vpx"
-ethernet0.address = "00:50:56:91:48:c7"
+ethernet0.generatedAddress = "00:50:56:91:48:c7"
 chipset.onlineStandby = "false"
 guestOSAltName = "Red Hat Enterprise Linux 5 (32-Bit)"
 guestOS = "rhel5"
@@ -434,10 +449,11 @@ Enter root password for example.com:
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <driver name='lsilogic'/>
       <source file='[local-storage] Fedora11/Fedora11.vmdk'/>
       <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
+    <controller type='scsi' index='0' model='lsilogic'/>
     <interface type='bridge'>
       <mac address='00:50:56:91:48:c7'/>
       <source bridge='VM Network'/>
@@ -465,10 +481,11 @@ $ cat > demo.xml << EOF
   </os>
   <devices>
     <disk type='file' device='disk'>
-      <driver name='lsilogic'/>
       <source file='[local-storage] Fedora11/Fedora11.vmdk'/>
       <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
+    <controller type='scsi' index='0' model='lsilogic'/>
     <interface type='bridge'>
       <mac address='00:50:56:25:48:c7'/>
       <source bridge='VM Network'/>
@@ -517,7 +534,9 @@ ethernet0.address = "00:50:56:25:48:C7"
     <disk type='file' device='disk'>
       <source file='[local-storage] Fedora11/Fedora11.vmdk'/>
       <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
+    <controller type='scsi' index='0'/>
     <interface type='bridge'>
       <mac address='00:50:56:25:48:c7'/>
       <source bridge='VM Network'/>
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index f50e090df0..acf89089e8 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2153,8 +2153,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
         goto cleanup;
     }
 
-    def = esxVMX_ParseConfig(priv->host, vmx, datastoreName, directoryName,
-                             priv->host->productVersion);
+    def = esxVMX_ParseConfig(priv->host, priv->caps, vmx, datastoreName,
+                             directoryName, priv->host->productVersion);
 
     if (def != NULL) {
         xml = virDomainDefFormat(def, flags);
@@ -2194,7 +2194,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
         return NULL;
     }
 
-    def = esxVMX_ParseConfig(priv->host, nativeConfig, "?", "?",
+    def = esxVMX_ParseConfig(priv->host, priv->caps, nativeConfig, "?", "?",
                              priv->host->productVersion);
 
     if (def != NULL) {
@@ -2229,7 +2229,8 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
         return NULL;
     }
 
-    vmx = esxVMX_FormatConfig(priv->host, def, priv->host->productVersion);
+    vmx = esxVMX_FormatConfig(priv->host, priv->caps, def,
+                              priv->host->productVersion);
 
     virDomainDefFree(def);
 
@@ -2457,7 +2458,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
     }
 
     /* Build VMX from domain XML */
-    vmx = esxVMX_FormatConfig(priv->host, def, priv->host->productVersion);
+    vmx = esxVMX_FormatConfig(priv->host, priv->caps, def,
+                              priv->host->productVersion);
 
     if (vmx == NULL) {
         goto cleanup;
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
index 675318f3db..032f5bc88e 100644
--- a/src/esx/esx_vmx.c
+++ b/src/esx/esx_vmx.c
@@ -23,6 +23,8 @@
 
 #include 
 
+#include 
+
 #include "internal.h"
 #include "virterror_internal.h"
 #include "memory.h"
@@ -78,9 +80,9 @@ def->os
 ################################################################################
 ## disks #######################################################################
 
-                                        scsi[0..3]:[0..6,8..15] -> :
-                                        ide[0..1]:[0..1]        -> :
-                                        floppy[0..1]            -> 
+                                        scsi[0..3]:[0..6,8..15] -> : with 1 bus per controller
+                                        ide[0..1]:[0..1]        -> : with 1 controller
+                                        floppy[0..1]            ->  with 1 controller and 1 bus per controller
 
 def->disks[0]...
 
@@ -100,7 +102,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_DISK      <=>   scsi0:0.deviceType = "scsi-hardDisk"    # defaults to ?
 ->bus = _DISK_BUS_SCSI
 ->src = .vmdk              <=>   scsi0:0.fileName = ".vmdk"
-->dst = sd[ * 15 +  mapped to [a-z]+]
+->dst = sd[ * 15 +  mapped to [a-z]+]
 ->driverName =            <=>   scsi0.virtualDev = ""           # default depends on guestOS value
 ->driverType
 ->cachemode                       <=>   scsi0:0.writeThrough = ""        # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT
@@ -124,7 +126,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_DISK      <=>   ide0:0.deviceType = "ata-hardDisk"      # defaults to ?
 ->bus = _DISK_BUS_IDE
 ->src = .vmdk              <=>   ide0:0.fileName = ".vmdk"
-->dst = hd[ * 2 +  mapped to [a-z]+]
+->dst = hd[ * 2 +  mapped to [a-z]+]
 ->driverName
 ->driverType
 ->cachemode                       <=>   ide0:0.writeThrough = ""         # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT
@@ -144,7 +146,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_CDROM     <=>   scsi0:0.deviceType = "cdrom-image"      # defaults to ?
 ->bus = _DISK_BUS_SCSI
 ->src = .iso               <=>   scsi0:0.fileName = ".iso"
-->dst = sd[ * 15 +  mapped to [a-z]+]
+->dst = sd[ * 15 +  mapped to [a-z]+]
 ->driverName =            <=>   scsi0.virtualDev = ""           # default depends on guestOS value
 ->driverType
 ->cachemode
@@ -163,7 +165,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_CDROM     <=>   ide0:0.deviceType = "cdrom-image"       # defaults to ?
 ->bus = _DISK_BUS_IDE
 ->src = .iso               <=>   ide0:0.fileName = ".iso"
-->dst = hd[ * 2 +  mapped to [a-z]+]
+->dst = hd[ * 2 +  mapped to [a-z]+]
 ->driverName
 ->driverType
 ->cachemode
@@ -183,7 +185,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_CDROM     <=>   scsi0:0.deviceType = "atapi-cdrom"      # defaults to ?
 ->bus = _DISK_BUS_SCSI
 ->src =                    <=>   scsi0:0.fileName = ""            # e.g. "/dev/scd0" ?
-->dst = sd[ * 16 +  mapped to [a-z]+]
+->dst = sd[ * 15 +  mapped to [a-z]+]
 ->driverName =            <=>   scsi0.virtualDev = ""           # default depends on guestOS value
 ->driverType
 ->cachemode
@@ -203,7 +205,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_CDROM     <=>   ide0:0.deviceType = "atapi-cdrom"       # defaults to ?
 ->bus = _DISK_BUS_IDE
 ->src =                    <=>   ide0:0.fileName = ""             # e.g. "/dev/scd0"
-->dst = hd[ * 2 +  mapped to [a-z]+]
+->dst = hd[ * 2 +  mapped to [a-z]+]
 ->driverName
 ->driverType
 ->cachemode
@@ -223,7 +225,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_FLOPPY
 ->bus = _DISK_BUS_FDC
 ->src = .flp               <=>   floppy0.fileName = ".flp"
-->dst = fd[ mapped to [a-z]+]
+->dst = fd[ mapped to [a-z]+]
 ->driverName
 ->driverType
 ->cachemode
@@ -243,7 +245,7 @@ def->disks[0]...
 ->device = _DISK_DEVICE_FLOPPY
 ->bus = _DISK_BUS_FDC
 ->src =                    <=>   floppy0.fileName = ""            # e.g. "/dev/fd0"
-->dst = fd[ mapped to [a-z]+]
+->dst = fd[ mapped to [a-z]+]
 ->driverName
 ->driverType
 ->cachemode
@@ -429,7 +431,7 @@ def->parallels[0]...
 
 
 int
-esxVMX_SCSIDiskNameToControllerAndID(const char *name, int *controller, int *id)
+esxVMX_SCSIDiskNameToControllerAndUnit(const char *name, int *controller, int *unit)
 {
     int idx;
 
@@ -448,7 +450,7 @@ esxVMX_SCSIDiskNameToControllerAndID(const char *name, int *controller, int *id)
         return -1;
     }
 
-    /* Each of the 4 SCSI controllers offers 15 IDs for devices */
+    /* Each of the 4 SCSI controllers has 1 bus with 15 units each for devices */
     if (idx >= (4 * 15)) {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                   _("SCSI disk index (parsed from '%s') is too large"), name);
@@ -456,11 +458,11 @@ esxVMX_SCSIDiskNameToControllerAndID(const char *name, int *controller, int *id)
     }
 
     *controller = idx / 15;
-    *id = idx % 15;
+    *unit = idx % 15;
 
-    /* Skip the controller ifself with ID 7 */
-    if (*id >= 7) {
-        ++(*id);
+    /* Skip the controller ifself at unit 7 */
+    if (*unit >= 7) {
+        ++(*unit);
     }
 
     return 0;
@@ -469,7 +471,7 @@ esxVMX_SCSIDiskNameToControllerAndID(const char *name, int *controller, int *id)
 
 
 int
-esxVMX_IDEDiskNameToControllerAndID(const char *name, int *controller, int *id)
+esxVMX_IDEDiskNameToBusAndUnit(const char *name, int *bus, int *unit)
 {
     int idx;
 
@@ -488,15 +490,15 @@ esxVMX_IDEDiskNameToControllerAndID(const char *name, int *controller, int *id)
         return -1;
     }
 
-    /* Each of the 2 IDE controllers offers 2 IDs for devices */
+    /* The IDE controller has 2 buses with 2 units each for devices */
     if (idx >= (2 * 2)) {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                   _("IDE disk index (parsed from '%s') is too large"), name);
         return -1;
     }
 
-    *controller = idx / 2;
-    *id = idx % 2;
+    *bus = idx / 2;
+    *unit = idx % 2;
 
     return 0;
 }
@@ -504,7 +506,7 @@ esxVMX_IDEDiskNameToControllerAndID(const char *name, int *controller, int *id)
 
 
 int
-esxVMX_FloppyDiskNameToController(const char *name, int *controller)
+esxVMX_FloppyDiskNameToUnit(const char *name, int *unit)
 {
     int idx;
 
@@ -523,13 +525,14 @@ esxVMX_FloppyDiskNameToController(const char *name, int *controller)
         return -1;
     }
 
+    /* The FDC controller has 1 bus with 2 units for devices */
     if (idx >= 2) {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                   _("Floppy disk index (parsed from '%s') is too large"), name);
         return -1;
     }
 
-    *controller = idx;
+    *unit = idx;
 
     return 0;
 }
@@ -537,13 +540,180 @@ esxVMX_FloppyDiskNameToController(const char *name, int *controller)
 
 
 int
-esxVMX_GatherSCSIControllers(virDomainDefPtr def, char *virtualDev[4],
-                             int present[4])
+esxVMX_VerifyDiskAddress(virCapsPtr caps, virDomainDiskDefPtr disk)
 {
-    virDomainDiskDefPtr disk;
-    int i, controller, id;
+    virDomainDiskDef def;
+    virDomainDeviceDriveAddressPtr drive;
+
+    memset(&def, 0, sizeof(def));
+
+    if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Unsupported disk address type '%s'"),
+                  virDomainDeviceAddressTypeToString(disk->info.type));
+        return -1;
+    }
+
+    drive = &disk->info.addr.drive;
+
+    def.dst = disk->dst;
+    def.bus = disk->bus;
+
+    if (virDomainDiskDefAssignAddress(caps, &def) < 0) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+                  _("Could not verify disk address"));
+        return -1;
+    }
+
+    if (def.info.addr.drive.controller != drive->controller ||
+        def.info.addr.drive.bus != drive->bus ||
+        def.info.addr.drive.unit != drive->unit) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Disk address %d:%d:%d doesn't match target device '%s'"),
+                  drive->controller, drive->bus, drive->unit, disk->dst);
+        return -1;
+    }
+
+    /* drive->{controller|bus|unit} is unsigned, no >= 0 checks are necessary */
+    if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+        if (drive->controller > 3) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("SCSI controller index %d out of [0..3] range"),
+                      drive->controller);
+            return -1;
+        }
+
+        if (drive->bus != 0) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("SCSI bus index %d out of [0] range"),
+                      drive->bus);
+            return -1;
+        }
+
+        if (drive->unit > 15 || drive->unit == 7) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("SCSI unit index %d out of [0..6,8..15] range"),
+                      drive->unit);
+            return -1;
+        }
+    } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
+        if (drive->controller != 0) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("IDE controller index %d out of [0] range"),
+                      drive->controller);
+            return -1;
+        }
+
+        if (drive->bus > 1) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("IDE bus index %d out of [0..1] range"),
+                      drive->bus);
+            return -1;
+        }
+
+        if (drive->unit > 1) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("IDE unit index %d out of [0..1] range"),
+                      drive->unit);
+            return -1;
+        }
+    } else if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
+        if (drive->controller != 0) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("FDC controller index %d out of [0] range"),
+                      drive->controller);
+            return -1;
+        }
+
+        if (drive->bus != 0) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("FDC bus index %d out of [0] range"),
+                      drive->bus);
+            return -1;
+        }
+
+        if (drive->unit > 1) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("FDC unit index %d out of [0..1] range"),
+                      drive->unit);
+            return -1;
+        }
+    } else {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Unsupported bus type '%s'"),
+                  virDomainDiskBusTypeToString(disk->bus));
+        return -1;
+    }
+
+    return 0;
+}
+
+
+
+int
+esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
+                                      virDomainDiskDefPtr disk)
+{
+    char *tmp;
+    int model, i;
+    virDomainControllerDefPtr controller = NULL;
+
+    if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI || disk->driverName == NULL) {
+        return 0;
+    }
+
+    tmp = disk->driverName;
+
+    for (; *tmp != '\0'; ++tmp) {
+        *tmp = c_tolower(*tmp);
+    }
+
+    model = virDomainControllerModelTypeFromString(disk->driverName);
+
+    if (model < 0) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Unknown driver name '%s'"), disk->driverName);
+        return -1;
+    }
+
+    for (i = 0; i < def->ncontrollers; ++i) {
+        if (def->controllers[i]->idx == disk->info.addr.drive.controller) {
+            controller = def->controllers[i];
+            break;
+        }
+    }
+
+    if (controller == NULL) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Missing SCSI controller for index %d"),
+                  disk->info.addr.drive.controller);
+        return -1;
+    }
+
+    if (controller->model == -1) {
+        controller->model = model;
+    } else if (controller->model != model) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Inconsistent SCSI controller model ('%s' is not '%s') "
+                    "for SCSI controller index %d"), disk->driverName,
+                  virDomainControllerModelTypeToString(controller->model),
+                  controller->idx);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+
+int
+esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4],
+                             bool present[4])
+{
+    int i;
+    virDomainDiskDefPtr disk;
+    virDomainControllerDefPtr controller = NULL;
 
-    /* Check for continuous use of the same virtualDev per SCSI controller */
     for (i = 0; i < def->ndisks; ++i) {
         disk = def->disks[i];
 
@@ -551,34 +721,36 @@ esxVMX_GatherSCSIControllers(virDomainDefPtr def, char *virtualDev[4],
             continue;
         }
 
-        if (disk->driverName != NULL &&
-            STRCASENEQ(disk->driverName, "buslogic") &&
-            STRCASENEQ(disk->driverName, "lsilogic") &&
-            STRCASENEQ(disk->driverName, "lsisas1068")) {
+        controller = NULL;
+
+        for (i = 0; i < def->ncontrollers; ++i) {
+            if (def->controllers[i]->idx == disk->info.addr.drive.controller) {
+                controller = def->controllers[i];
+                break;
+            }
+        }
+
+        if (controller == NULL) {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                      _("Expecting domain XML entry 'devices/disk/target' to "
-                        "be 'buslogic' or 'lsilogic' or 'lsisas1068' but found '%s'"),
-                      disk->driverName);
+                      _("Missing SCSI controller for index %d"),
+                      disk->info.addr.drive.controller);
             return -1;
         }
 
-        if (esxVMX_SCSIDiskNameToControllerAndID(disk->dst, &controller,
-                                                 &id) < 0) {
-            return -1;
-        }
-
-        present[controller] = 1;
-
-        if (virtualDev[controller] == NULL) {
-            virtualDev[controller] = disk->driverName;
-        } else if (disk->driverName == NULL ||
-                   STRCASENEQ(virtualDev[controller], disk->driverName)) {
+        if (controller->model != -1 &&
+            controller->model != VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC &&
+            controller->model != VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC &&
+            controller->model != VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068) {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                      _("Inconsistent driver usage ('%s' is not '%s') on SCSI "
-                        "controller index %d"), virtualDev[controller],
-                      disk->driverName ? disk->driverName : "?", controller);
+                      _("Expecting domain XML attribute 'model' of entry "
+                        "'controller' to be 'buslogic' or 'lsilogic' or "
+                        "'lsisas1068' but found '%s'"),
+                      virDomainControllerModelTypeToString(controller->model));
             return -1;
         }
+
+        present[controller->idx] = true;
+        virtualDev[controller->idx] = controller->model;
     }
 
     return 0;
@@ -725,7 +897,7 @@ esxVMX_ParseFileName(esxVI_Context *ctx, const char *fileName,
 
 
 virDomainDefPtr
-esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
+esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
                    const char *datastoreName, const char *directoryName,
                    esxVI_ProductVersion productVersion)
 {
@@ -740,10 +912,11 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     char *sched_cpu_affinity = NULL;
     char *guestOS = NULL;
     int controller;
+    int bus;
     int port;
     int present; // boolean
-    char *scsi_virtualDev = NULL;
-    int id;
+    int scsi_virtualDev[4] = { -1, -1, -1, -1 };
+    int unit;
 
     conf = virConfReadMem(vmx, strlen(vmx), VIR_CONF_FLAG_VMX_FORMAT);
 
@@ -970,12 +1143,11 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
         goto cleanup;
     }
 
-/*
-    def->emulator
-    def->features*/
+    /* def:features */
+    /* FIXME */
 
-/*
-    def->localtime*/
+    /* def:clock */
+    /* FIXME */
 
     /* def:graphics */
     if (VIR_ALLOC_N(def->graphics, 1) < 0) {
@@ -1003,10 +1175,8 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
 
     /* def:disks (scsi) */
     for (controller = 0; controller < 4; ++controller) {
-        VIR_FREE(scsi_virtualDev);
-
         if (esxVMX_ParseSCSIController(conf, controller, &present,
-                                       &scsi_virtualDev) < 0) {
+                                       &scsi_virtualDev[controller]) < 0) {
             goto cleanup;
         }
 
@@ -1014,18 +1184,18 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
             continue;
         }
 
-        for (id = 0; id < 16; ++id) {
-            if (id == 7) {
+        for (unit = 0; unit < 16; ++unit) {
+            if (unit == 7) {
                 /*
-                 * SCSI ID 7 is assigned to the SCSI controller and cannot be
+                 * SCSI unit 7 is assigned to the SCSI controller and cannot be
                  * used for disk devices.
                  */
                 continue;
             }
 
-            if (esxVMX_ParseDisk(ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
-                                 VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
-                                 scsi_virtualDev, datastoreName, directoryName,
+            if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
+                                 VIR_DOMAIN_DISK_BUS_SCSI, controller, unit,
+                                 datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto cleanup;
             }
@@ -1035,9 +1205,9 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
                 continue;
             }
 
-            if (esxVMX_ParseDisk(ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
-                                 VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
-                                 scsi_virtualDev, datastoreName, directoryName,
+            if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
+                                 VIR_DOMAIN_DISK_BUS_SCSI, controller, unit,
+                                 datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto cleanup;
             }
@@ -1049,11 +1219,11 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     }
 
     /* def:disks (ide) */
-    for (controller = 0; controller < 2; ++controller) {
-        for (id = 0; id < 2; ++id) {
-            if (esxVMX_ParseDisk(ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
-                                 VIR_DOMAIN_DISK_BUS_IDE, controller, id,
-                                 NULL, datastoreName, directoryName,
+    for (bus = 0; bus < 2; ++bus) {
+        for (unit = 0; unit < 2; ++unit) {
+            if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
+                                 VIR_DOMAIN_DISK_BUS_IDE, bus, unit,
+                                 datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto cleanup;
             }
@@ -1063,9 +1233,9 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
                 continue;
             }
 
-            if (esxVMX_ParseDisk(ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
-                                 VIR_DOMAIN_DISK_BUS_IDE, controller, id,
-                                 NULL, datastoreName, directoryName,
+            if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
+                                 VIR_DOMAIN_DISK_BUS_IDE, bus, unit,
+                                 datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto cleanup;
             }
@@ -1077,9 +1247,9 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     }
 
     /* def:disks (floppy) */
-    for (controller = 0; controller < 2; ++controller) {
-        if (esxVMX_ParseDisk(ctx, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
-                             VIR_DOMAIN_DISK_BUS_FDC, controller, -1, NULL,
+    for (unit = 0; unit < 2; ++unit) {
+        if (esxVMX_ParseDisk(ctx, caps, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
+                             VIR_DOMAIN_DISK_BUS_FDC, 0, unit,
                              datastoreName, directoryName,
                              &def->disks[def->ndisks]) < 0) {
             goto cleanup;
@@ -1090,6 +1260,27 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
         }
     }
 
+    /* def:controllers */
+    if (virDomainDefAddImplicitControllers(def) < 0) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not add controllers"));
+        goto cleanup;
+    }
+
+    for (controller = 0; controller < def->ncontrollers; ++controller) {
+        if (def->controllers[controller]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
+            if (def->controllers[controller]->idx < 0 ||
+                def->controllers[controller]->idx > 3) {
+                ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                          _("SCSI controller index %d out of [0..3] range"),
+                          def->controllers[controller]->idx);
+                goto cleanup;
+            }
+
+            def->controllers[controller]->model =
+              scsi_virtualDev[def->controllers[controller]->idx];
+        }
+    }
+
     /* def:fss */
     /* FIXME */
 
@@ -1130,8 +1321,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     def->nserials = 0;
 
     for (port = 0; port < 4; ++port) {
-        if (esxVMX_ParseSerial(ctx, conf, port, datastoreName,
-                               directoryName,
+        if (esxVMX_ParseSerial(ctx, conf, port, datastoreName, directoryName,
                                &def->serials[def->nserials]) < 0) {
             goto cleanup;
         }
@@ -1150,8 +1340,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     def->nparallels = 0;
 
     for (port = 0; port < 3; ++port) {
-        if (esxVMX_ParseParallel(ctx, conf, port, datastoreName,
-                                 directoryName,
+        if (esxVMX_ParseParallel(ctx, conf, port, datastoreName, directoryName,
                                  &def->parallels[def->nparallels]) < 0) {
             goto cleanup;
         }
@@ -1172,7 +1361,6 @@ esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
     virConfFree(conf);
     VIR_FREE(sched_cpu_affinity);
     VIR_FREE(guestOS);
-    VIR_FREE(scsi_virtualDev);
 
     return def;
 }
@@ -1245,12 +1433,14 @@ esxVMX_ParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def)
 
 int
 esxVMX_ParseSCSIController(virConfPtr conf, int controller, int *present,
-                           char **virtualDev)
+                           int *virtualDev)
 {
     char present_name[32];
     char virtualDev_name[32];
+    char *virtualDev_string = NULL;
+    char *tmp;
 
-    if (virtualDev == NULL || *virtualDev != NULL) {
+    if (virtualDev == NULL || *virtualDev != -1) {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
         return -1;
     }
@@ -1274,24 +1464,36 @@ esxVMX_ParseSCSIController(virConfPtr conf, int controller, int *present,
         return 0;
     }
 
-    if (esxUtil_GetConfigString(conf, virtualDev_name, virtualDev, 1) < 0) {
+    if (esxUtil_GetConfigString(conf, virtualDev_name, &virtualDev_string,
+                                1) < 0) {
         goto failure;
     }
 
-    if (*virtualDev != NULL &&
-        STRCASENEQ(*virtualDev, "buslogic") &&
-        STRCASENEQ(*virtualDev, "lsilogic") &&
-        STRCASENEQ(*virtualDev, "lsisas1068")) {
-        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                  _("Expecting VMX entry '%s' to be 'buslogic' or 'lsilogic' or "
-                    "'lsisas1068' but found '%s'"), virtualDev_name, *virtualDev);
-        goto failure;
+    if (virtualDev_string != NULL) {
+        tmp = virtualDev_string;
+
+        for (; *tmp != '\0'; ++tmp) {
+            *tmp = c_tolower(*tmp);
+        }
+
+        *virtualDev = virDomainControllerModelTypeFromString(virtualDev_string);
+
+        if (*virtualDev == -1 ||
+            (*virtualDev != VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC &&
+             *virtualDev != VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC &&
+             *virtualDev != VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068)) {
+            ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                      _("Expecting VMX entry '%s' to be 'buslogic' or 'lsilogic' "
+                        "or 'lsisas1068' but found '%s'"), virtualDev_name,
+                        virtualDev_string);
+            goto failure;
+        }
     }
 
     return 0;
 
   failure:
-    VIR_FREE(*virtualDev);
+    VIR_FREE(virtualDev_string);
 
     return -1;
 }
@@ -1314,29 +1516,26 @@ struct _virDomainDiskDef {
 };*/
 
 int
-esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
-                 int controller, int id, const char *virtualDev,
+esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
+                 int device, int busType, int controllerOrBus, int unit,
                  const char *datastoreName, const char *directoryName,
                  virDomainDiskDefPtr *def)
 {
     /*
-     *     device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
-     *        bus = VIR_DOMAIN_DISK_BUS_SCSI
-     * controller = [0..3]
-     *         id = [0..6,8..15]
-     * virtualDev = {'buslogic', 'lsilogic', 'lsisas1068'}
+     *          device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
+     *         busType = VIR_DOMAIN_DISK_BUS_SCSI
+     * controllerOrBus = [0..3] -> controller
+     *            unit = [0..6,8..15]
      *
-     *     device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
-     *        bus = VIR_DOMAIN_DISK_BUS_IDE
-     * controller = [0..1]
-     *         id = [0..1]
-     * virtualDev = NULL
+     *          device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
+     *         busType = VIR_DOMAIN_DISK_BUS_IDE
+     * controllerOrBus = [0..1] -> bus
+     *            unit = [0..1]
      *
-     *     device = VIR_DOMAIN_DISK_DEVICE_FLOPPY
-     *        bus = VIR_DOMAIN_DISK_BUS_FDC
-     * controller = [0..1]
-     *         id = -1
-     * virtualDev = NULL
+     *          device = VIR_DOMAIN_DISK_DEVICE_FLOPPY
+     *         busType = VIR_DOMAIN_DISK_BUS_FDC
+     * controllerOrBus = [0]
+     *            unit = [0..1]
      */
 
     int result = -1;
@@ -1374,66 +1573,58 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
     }
 
     (*def)->device = device;
-    (*def)->bus = bus;
+    (*def)->bus = busType;
 
     /* def:dst, def:driverName */
     if (device == VIR_DOMAIN_DISK_DEVICE_DISK ||
         device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
-        if (bus == VIR_DOMAIN_DISK_BUS_SCSI) {
-            if (controller < 0 || controller > 3) {
+        if (busType == VIR_DOMAIN_DISK_BUS_SCSI) {
+            if (controllerOrBus < 0 || controllerOrBus > 3) {
                 ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                           _("SCSI controller index %d out of [0..3] range"),
-                          controller);
+                          controllerOrBus);
                 goto cleanup;
             }
 
-            if (id < 0 || id > 15 || id == 7) {
+            if (unit < 0 || unit > 15 || unit == 7) {
                 ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                          _("SCSI ID %d out of [0..6,8..15] range"), id);
+                          _("SCSI unit index %d out of [0..6,8..15] range"),
+                          unit);
                 goto cleanup;
             }
 
-            if (virAsprintf(&prefix, "scsi%d:%d", controller, id) < 0) {
+            if (virAsprintf(&prefix, "scsi%d:%d", controllerOrBus, unit) < 0) {
                 virReportOOMError();
                 goto cleanup;
             }
 
             (*def)->dst =
                virIndexToDiskName
-                 (controller * 15 + (id < 7 ? id : id - 1), "sd");
+                 (controllerOrBus * 15 + (unit < 7 ? unit : unit - 1), "sd");
 
             if ((*def)->dst == NULL) {
                 goto cleanup;
             }
-
-            if (virtualDev != NULL) {
-                (*def)->driverName = strdup(virtualDev);
-
-                if ((*def)->driverName == NULL) {
-                    virReportOOMError();
-                    goto cleanup;
-                }
-            }
-        } else if (bus == VIR_DOMAIN_DISK_BUS_IDE) {
-            if (controller < 0 || controller > 1) {
+        } else if (busType == VIR_DOMAIN_DISK_BUS_IDE) {
+            if (controllerOrBus < 0 || controllerOrBus > 1) {
                 ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                          _("IDE controller index %d out of [0..1] range"),
-                          controller);
+                          _("IDE bus index %d out of [0..1] range"),
+                          controllerOrBus);
                 goto cleanup;
             }
 
-            if (id < 0 || id > 1) {
+            if (unit < 0 || unit > 1) {
                 ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                          _("IDE ID %d out of [0..1] range"), id);
+                          _("IDE unit index %d out of [0..1] range"), unit);
                 goto cleanup;
             }
 
-            if (virAsprintf(&prefix, "ide%d:%d", controller, id) < 0) {
+            if (virAsprintf(&prefix, "ide%d:%d", controllerOrBus, unit) < 0) {
                 virReportOOMError();
                 goto cleanup;
             }
 
-            (*def)->dst = virIndexToDiskName(controller * 2 + id, "hd");
+            (*def)->dst = virIndexToDiskName(controllerOrBus * 2 + unit, "hd");
 
             if ((*def)->dst == NULL) {
                 goto cleanup;
@@ -1441,25 +1632,32 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
         } else {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                       _("Unsupported bus type '%s' for device type '%s'"),
-                      virDomainDiskBusTypeToString(bus),
+                      virDomainDiskBusTypeToString(busType),
                       virDomainDiskDeviceTypeToString(device));
             goto cleanup;
         }
     } else if (device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
-        if (bus == VIR_DOMAIN_DISK_BUS_FDC) {
-            if (controller < 0 || controller > 1) {
+        if (busType == VIR_DOMAIN_DISK_BUS_FDC) {
+            if (controllerOrBus != 0) {
                 ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
-                          _("Floppy controller index %d out of [0..1] range"),
-                          controller);
+                          _("FDC controller index %d out of [0] range"),
+                          controllerOrBus);
                 goto cleanup;
             }
 
-            if (virAsprintf(&prefix, "floppy%d", controller) < 0) {
+            if (unit < 0 || unit > 1) {
+                ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                          _("FDC unit index %d out of [0..1] range"),
+                          unit);
+                goto cleanup;
+            }
+
+            if (virAsprintf(&prefix, "floppy%d", unit) < 0) {
                 virReportOOMError();
                 goto cleanup;
             }
 
-            (*def)->dst = virIndexToDiskName(controller, "fd");
+            (*def)->dst = virIndexToDiskName(unit, "fd");
 
             if ((*def)->dst == NULL) {
                 goto cleanup;
@@ -1467,7 +1665,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
         } else {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                       _("Unsupported bus type '%s' for device type '%s'"),
-                      virDomainDiskBusTypeToString(bus),
+                      virDomainDiskBusTypeToString(busType),
                       virDomainDiskDeviceTypeToString(device));
             goto cleanup;
         }
@@ -1541,7 +1739,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
     if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
         if (virFileHasSuffix(fileName, ".vmdk")) {
             if (deviceType != NULL) {
-                if (bus == VIR_DOMAIN_DISK_BUS_SCSI &&
+                if (busType == VIR_DOMAIN_DISK_BUS_SCSI &&
                     STRCASENEQ(deviceType, "scsi-hardDisk") &&
                     STRCASENEQ(deviceType, "disk")) {
                     ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -1549,7 +1747,7 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
                                 "or 'disk' but found '%s'"), deviceType_name,
                               deviceType);
                     goto cleanup;
-                } else if (bus == VIR_DOMAIN_DISK_BUS_IDE &&
+                } else if (busType == VIR_DOMAIN_DISK_BUS_IDE &&
                            STRCASENEQ(deviceType, "ata-hardDisk") &&
                            STRCASENEQ(deviceType, "disk")) {
                     ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -1560,16 +1758,6 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
                 }
             }
 
-            if (writeThrough && virtualDev == NULL) {
-                /*
-                 * FIXME: If no virtualDev is explicit specified need to get
-                 *        the default based on the guestOS. The mechanism to
-                 *        obtain the default is currently missing
-                 */
-                VIR_WARN0("No explicit SCSI driver specified in VMX config, "
-                          "cannot represent explicit specified cachemode");
-            }
-
             (*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
             (*def)->src = esxVMX_ParseFileName(ctx, fileName, datastoreName,
                                                directoryName);
@@ -1666,6 +1854,12 @@ esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
         goto cleanup;
     }
 
+    if (virDomainDiskDefAssignAddress(caps, *def) < 0) {
+        ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                  _("Could not assign address to disk '%s'"), (*def)->src);
+        goto cleanup;
+    }
+
     result = 0;
 
   cleanup:
@@ -2239,13 +2433,15 @@ esxVMX_FormatFileName(esxVI_Context *ctx ATTRIBUTE_UNUSED, const char *src)
 
 
 char *
-esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
+esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
                     esxVI_ProductVersion productVersion)
 {
     int i;
     int sched_cpu_affinity_length;
     unsigned char zero[VIR_UUID_BUFLEN];
     virBuffer buffer = VIR_BUFFER_INITIALIZER;
+    bool scsi_present[4] = { false, false, false, false };
+    int scsi_virtualDev[4] = { -1, -1, -1, -1 };
 
     memset(zero, 0, VIR_UUID_BUFLEN);
 
@@ -2398,8 +2594,12 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
     }
 
     /* def:disks */
-    int scsi_present[4] = { 0, 0, 0, 0 };
-    char *scsi_virtualDev[4] = { NULL, NULL, NULL, NULL };
+    for (i = 0; i < def->ndisks; ++i) {
+        if (esxVMX_VerifyDiskAddress(caps, def->disks[i]) < 0 ||
+            esxVMX_HandleLegacySCSIDiskDriverName(def, def->disks[i]) < 0) {
+            goto failure;
+        }
+    }
 
     if (esxVMX_GatherSCSIControllers(def, scsi_virtualDev, scsi_present) < 0) {
         goto failure;
@@ -2409,9 +2609,10 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
         if (scsi_present[i]) {
             virBufferVSprintf(&buffer, "scsi%d.present = \"true\"\n", i);
 
-            if (scsi_virtualDev[i] != NULL) {
+            if (scsi_virtualDev[i] != -1) {
                 virBufferVSprintf(&buffer, "scsi%d.virtualDev = \"%s\"\n", i,
-                                  scsi_virtualDev[i]);
+                                  virDomainControllerModelTypeToString
+                                    (scsi_virtualDev[i]));
             }
         }
     }
@@ -2543,7 +2744,7 @@ int
 esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
                       virBufferPtr buffer)
 {
-    int controller, id;
+    int controllerOrBus, unit;
     const char *busName = NULL;
     const char *entryPrefix = NULL;
     const char *deviceTypePrefix = NULL;
@@ -2559,8 +2760,8 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
         entryPrefix = "scsi";
         deviceTypePrefix = "scsi";
 
-        if (esxVMX_SCSIDiskNameToControllerAndID(def->dst, &controller,
-                                                 &id) < 0) {
+        if (esxVMX_SCSIDiskNameToControllerAndUnit(def->dst, &controllerOrBus,
+                                                   &unit) < 0) {
             return -1;
         }
     } else if (def->bus == VIR_DOMAIN_DISK_BUS_IDE) {
@@ -2568,8 +2769,8 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
         entryPrefix = "ide";
         deviceTypePrefix = "ata";
 
-        if (esxVMX_IDEDiskNameToControllerAndID(def->dst, &controller,
-                                                &id) < 0) {
+        if (esxVMX_IDEDiskNameToBusAndUnit(def->dst, &controllerOrBus,
+                                           &unit) < 0) {
             return -1;
         }
     } else {
@@ -2588,9 +2789,9 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
     }
 
     virBufferVSprintf(buffer, "%s%d:%d.present = \"true\"\n",
-                      entryPrefix, controller, id);
+                      entryPrefix, controllerOrBus, unit);
     virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"%s-hardDisk\"\n",
-                      entryPrefix, controller, id, deviceTypePrefix);
+                      entryPrefix, controllerOrBus, unit, deviceTypePrefix);
 
     if (def->src != NULL) {
         if (! virFileHasSuffix(def->src, ".vmdk")) {
@@ -2607,7 +2808,7 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
         }
 
         virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
-                          entryPrefix, controller, id, fileName);
+                          entryPrefix, controllerOrBus, unit, fileName);
 
         VIR_FREE(fileName);
     }
@@ -2615,7 +2816,7 @@ esxVMX_FormatHardDisk(esxVI_Context *ctx, virDomainDiskDefPtr def,
     if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
         if (def->cachemode == VIR_DOMAIN_DISK_CACHE_WRITETHRU) {
             virBufferVSprintf(buffer, "%s%d:%d.writeThrough = \"true\"\n",
-                              entryPrefix, controller, id);
+                              entryPrefix, controllerOrBus, unit);
         } else if (def->cachemode != VIR_DOMAIN_DISK_CACHE_DEFAULT) {
             ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
                       _("%s harddisk '%s' has unsupported cache mode '%s'"),
@@ -2634,7 +2835,7 @@ int
 esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
                    virBufferPtr buffer)
 {
-    int controller, id;
+    int controllerOrBus, unit;
     const char *busName = NULL;
     const char *entryPrefix = NULL;
     char *fileName = NULL;
@@ -2648,16 +2849,16 @@ esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
         busName = "SCSI";
         entryPrefix = "scsi";
 
-        if (esxVMX_SCSIDiskNameToControllerAndID(def->dst, &controller,
-                                                 &id) < 0) {
+        if (esxVMX_SCSIDiskNameToControllerAndUnit(def->dst, &controllerOrBus,
+                                                   &unit) < 0) {
             return -1;
         }
     } else if (def->bus == VIR_DOMAIN_DISK_BUS_IDE) {
         busName = "IDE";
         entryPrefix = "ide";
 
-        if (esxVMX_IDEDiskNameToControllerAndID(def->dst, &controller,
-                                                &id) < 0) {
+        if (esxVMX_IDEDiskNameToBusAndUnit(def->dst, &controllerOrBus,
+                                           &unit) < 0) {
             return -1;
         }
     } else {
@@ -2668,11 +2869,11 @@ esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
     }
 
     virBufferVSprintf(buffer, "%s%d:%d.present = \"true\"\n",
-                      entryPrefix, controller, id);
+                      entryPrefix, controllerOrBus, unit);
 
     if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
         virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"cdrom-image\"\n",
-                          entryPrefix, controller, id);
+                          entryPrefix, controllerOrBus, unit);
 
         if (def->src != NULL) {
             if (! virFileHasSuffix(def->src, ".iso")) {
@@ -2689,17 +2890,17 @@ esxVMX_FormatCDROM(esxVI_Context *ctx, virDomainDiskDefPtr def,
             }
 
             virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
-                              entryPrefix, controller, id, fileName);
+                              entryPrefix, controllerOrBus, unit, fileName);
 
             VIR_FREE(fileName);
         }
     } else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
         virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"atapi-cdrom\"\n",
-                          entryPrefix, controller, id);
+                          entryPrefix, controllerOrBus, unit);
 
         if (def->src != NULL) {
             virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
-                              entryPrefix, controller, id, def->src);
+                              entryPrefix, controllerOrBus, unit, def->src);
         }
     } else {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -2720,7 +2921,7 @@ int
 esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
                     virBufferPtr buffer)
 {
-    int controller;
+    int unit;
     char *fileName = NULL;
 
     if (def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
@@ -2728,15 +2929,14 @@ esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
         return -1;
     }
 
-    if (esxVMX_FloppyDiskNameToController(def->dst, &controller) < 0) {
+    if (esxVMX_FloppyDiskNameToUnit(def->dst, &unit) < 0) {
         return -1;
     }
 
-    virBufferVSprintf(buffer, "floppy%d.present = \"true\"\n", controller);
+    virBufferVSprintf(buffer, "floppy%d.present = \"true\"\n", unit);
 
     if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
-        virBufferVSprintf(buffer, "floppy%d.fileType = \"file\"\n",
-                          controller);
+        virBufferVSprintf(buffer, "floppy%d.fileType = \"file\"\n", unit);
 
         if (def->src != NULL) {
             if (! virFileHasSuffix(def->src, ".flp")) {
@@ -2753,17 +2953,16 @@ esxVMX_FormatFloppy(esxVI_Context *ctx, virDomainDiskDefPtr def,
             }
 
             virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
-                              controller, fileName);
+                              unit, fileName);
 
             VIR_FREE(fileName);
         }
     } else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
-        virBufferVSprintf(buffer, "floppy%d.fileType = \"device\"\n",
-                          controller);
+        virBufferVSprintf(buffer, "floppy%d.fileType = \"device\"\n", unit);
 
         if (def->src != NULL) {
             virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
-                              controller, def->src);
+                              unit, def->src);
         }
     } else {
         ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/esx/esx_vmx.h b/src/esx/esx_vmx.h
index 081b67d872..9b66ab8d06 100644
--- a/src/esx/esx_vmx.h
+++ b/src/esx/esx_vmx.h
@@ -29,17 +29,25 @@
 # include "esx_vi.h"
 
 int
-esxVMX_SCSIDiskNameToControllerAndID(const char *name, int *controller, int *id);
+esxVMX_SCSIDiskNameToControllerAndUnit(const char *name, int *controller,
+                                       int *unit);
 
 int
-esxVMX_IDEDiskNameToControllerAndID(const char *name, int *controller, int *id);
+esxVMX_IDEDiskNameToBusAndUnit(const char *name, int *bus, int *unit);
 
 int
-esxVMX_FloppyDiskNameToController(const char *name, int *controller);
+esxVMX_FloppyDiskNameToUnit(const char *name, int *unit);
 
 int
-esxVMX_GatherSCSIControllers(virDomainDefPtr conf, char *virtualDev[4],
-                             int present[4]);
+esxVMX_VerifyDiskAddress(virCapsPtr caps, virDomainDiskDefPtr disk);
+
+int
+esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
+                                      virDomainDiskDefPtr disk);
+
+int
+esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4],
+                             bool present[4]);
 
 char *
 esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
@@ -56,7 +64,7 @@ esxVMX_ParseFileName(esxVI_Context *ctx, const char *fileName,
                      const char *datastoreName, const char *directoryName);
 
 virDomainDefPtr
-esxVMX_ParseConfig(esxVI_Context *ctx, const char *vmx,
+esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
                    const char *datastoreName, const char *directoryName,
                    esxVI_ProductVersion productVersion);
 
@@ -65,11 +73,11 @@ esxVMX_ParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def);
 
 int
 esxVMX_ParseSCSIController(virConfPtr conf, int controller, int *present,
-                           char **virtualDev);
+                           int *virtualDev);
 
 int
-esxVMX_ParseDisk(esxVI_Context *ctx, virConfPtr conf, int device, int bus,
-                 int controller, int id, const char *virtualDev,
+esxVMX_ParseDisk(esxVI_Context *ctx, virCapsPtr caps, virConfPtr conf,
+                 int device, int busType, int controllerOrBus, int unit,
                  const char *datastoreName, const char *directoryName,
                  virDomainDiskDefPtr *def);
 int
@@ -95,7 +103,7 @@ char *
 esxVMX_FormatFileName(esxVI_Context *ctx, const char *src);
 
 char *
-esxVMX_FormatConfig(esxVI_Context *ctx, virDomainDefPtr def,
+esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def,
                     esxVI_ProductVersion productVersion);
 
 int
diff --git a/tests/vmx2xmldata/vmx2xml-case-insensitive-1.xml b/tests/vmx2xmldata/vmx2xml-case-insensitive-1.xml
index 3131bb2c1b..b47e128605 100644
--- a/tests/vmx2xmldata/vmx2xml-case-insensitive-1.xml
+++ b/tests/vmx2xmldata/vmx2xml-case-insensitive-1.xml
@@ -13,10 +13,11 @@
   destroy
   
     
-      
       
       
+      
+ diff --git a/tests/vmx2xmldata/vmx2xml-case-insensitive-2.xml b/tests/vmx2xmldata/vmx2xml-case-insensitive-2.xml index 766172f991..4974f4e75f 100644 --- a/tests/vmx2xmldata/vmx2xml-case-insensitive-2.xml +++ b/tests/vmx2xmldata/vmx2xml-case-insensitive-2.xml @@ -13,10 +13,11 @@ destroy - +
+ diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml index 12c431e42b..1905f9be92 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-device.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml index c88d90e77e..b9cf1f9c4e 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml index 55ea5e22ea..1bb42be1be 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-device.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml index ebd57180ed..bdcb0b06e3 100644 --- a/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml +++ b/tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml index 7cda8b5d99..fd50008fc2 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml @@ -13,10 +13,11 @@ destroy - +
+ diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml index 95fb40b42d..e98b67972f 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml @@ -13,31 +13,40 @@ destroy - + +
- +
+
+
+
+
+ + + + diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml index ea30c434ba..6d18209270 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml @@ -13,18 +13,23 @@ destroy - +
+
+
+ + + diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml index 3a4c6ae71b..5b8fbb97bc 100644 --- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml +++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml @@ -13,10 +13,11 @@ destroy - +
+ diff --git a/tests/vmx2xmldata/vmx2xml-floppy-device.xml b/tests/vmx2xmldata/vmx2xml-floppy-device.xml index 3991f735c2..4ae16d562b 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-device.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-device.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-floppy-file.xml b/tests/vmx2xmldata/vmx2xml-floppy-file.xml index 5c2e7e3f9b..5ab538ed1c 100644 --- a/tests/vmx2xmldata/vmx2xml-floppy-file.xml +++ b/tests/vmx2xmldata/vmx2xml-floppy-file.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml index 89a70a4bfb..0c308bc530 100644 --- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml +++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml @@ -15,7 +15,9 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml index 5f23d60450..7b6158f316 100644 --- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml @@ -15,7 +15,9 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml index 6f54b277fd..b926db57c2 100644 --- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml @@ -15,7 +15,9 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml index 5b8d64ed0d..5803f4bded 100644 --- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml +++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml @@ -15,7 +15,9 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-harddisk-ide-file.xml b/tests/vmx2xmldata/vmx2xml-harddisk-ide-file.xml index 59041bda67..7699fbb83b 100644 --- a/tests/vmx2xmldata/vmx2xml-harddisk-ide-file.xml +++ b/tests/vmx2xmldata/vmx2xml-harddisk-ide-file.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-harddisk-scsi-file.xml b/tests/vmx2xmldata/vmx2xml-harddisk-scsi-file.xml index 2609f8c905..b04597be38 100644 --- a/tests/vmx2xmldata/vmx2xml-harddisk-scsi-file.xml +++ b/tests/vmx2xmldata/vmx2xml-harddisk-scsi-file.xml @@ -14,6 +14,8 @@ +
+ diff --git a/tests/vmx2xmldata/vmx2xml-scsi-driver.xml b/tests/vmx2xmldata/vmx2xml-scsi-driver.xml index 1fa9ac45fb..d39415d162 100644 --- a/tests/vmx2xmldata/vmx2xml-scsi-driver.xml +++ b/tests/vmx2xmldata/vmx2xml-scsi-driver.xml @@ -12,19 +12,22 @@ destroy - +
- +
- +
+ + + diff --git a/tests/vmx2xmldata/vmx2xml-scsi-writethrough.xml b/tests/vmx2xmldata/vmx2xml-scsi-writethrough.xml index f1c40830d3..66e22ae04d 100644 --- a/tests/vmx2xmldata/vmx2xml-scsi-writethrough.xml +++ b/tests/vmx2xmldata/vmx2xml-scsi-writethrough.xml @@ -12,9 +12,11 @@ destroy - + +
+ diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c index 0a8b99efcb..f1d24711b9 100644 --- a/tests/vmx2xmltest.c +++ b/tests/vmx2xmltest.c @@ -13,9 +13,59 @@ static char *progname = NULL; static char *abs_srcdir = NULL; +static virCapsPtr caps = NULL; # define MAX_FILE 4096 +static void +testCapsInit(void) +{ + virCapsGuestPtr guest = NULL; + + caps = virCapabilitiesNew("i686", 1, 1); + + if (caps == NULL) { + return; + } + + virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); + virCapabilitiesAddHostMigrateTransport(caps, "esx"); + + caps->hasWideScsiBus = true; + + /* i686 guest */ + guest = + virCapabilitiesAddGuest(caps, "hvm", "i686", 32, NULL, NULL, 0, NULL); + + if (guest == NULL) { + goto failure; + } + + if (virCapabilitiesAddGuestDomain(guest, "vmware", NULL, NULL, 0, + NULL) == NULL) { + goto failure; + } + + /* x86_64 guest */ + guest = + virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64, NULL, NULL, 0, NULL); + + if (guest == NULL) { + goto failure; + } + + if (virCapabilitiesAddGuestDomain(guest, "vmware", NULL, NULL, 0, + NULL) == NULL) { + goto failure; + } + + return; + + failure: + virCapabilitiesFree(caps); + caps = NULL; +} + static int testCompareFiles(const char *vmx, const char *xml, esxVI_ProductVersion productVersion) @@ -37,7 +87,7 @@ testCompareFiles(const char *vmx, const char *xml, goto failure; } - def = esxVMX_ParseConfig(NULL, vmxData, "datastore", "directory", + def = esxVMX_ParseConfig(NULL, caps, vmxData, "datastore", "directory", productVersion); if (def == NULL) { @@ -123,6 +173,12 @@ mymain(int argc, char **argv) } \ } while (0) + testCapsInit(); + + if (caps == NULL) { + return EXIT_FAILURE; + } + DO_TEST("case-insensitive-1", "case-insensitive-1", esxVI_ProductVersion_ESX35); DO_TEST("case-insensitive-2", "case-insensitive-2", esxVI_ProductVersion_ESX35); @@ -176,6 +232,8 @@ mymain(int argc, char **argv) DO_TEST("gsx-in-the-wild-3", "gsx-in-the-wild-3", esxVI_ProductVersion_ESX35); DO_TEST("gsx-in-the-wild-4", "gsx-in-the-wild-4", esxVI_ProductVersion_ESX35); + virCapabilitiesFree(caps); + return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c index 14901fa8a8..0a9bc5389c 100644 --- a/tests/xml2vmxtest.c +++ b/tests/xml2vmxtest.c @@ -18,7 +18,7 @@ static virCapsPtr caps = NULL; # define MAX_FILE 4096 static void -testESXCapsInit(void) +testCapsInit(void) { virCapsGuestPtr guest = NULL; @@ -28,9 +28,11 @@ testESXCapsInit(void) return; } - virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x50, 0x56 }); + virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); virCapabilitiesAddHostMigrateTransport(caps, "esx"); + caps->hasWideScsiBus = true; + /* i686 guest */ guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32, NULL, NULL, 0, NULL); @@ -90,7 +92,7 @@ testCompareFiles(const char *xml, const char *vmx, goto failure; } - formatted = esxVMX_FormatConfig(NULL, def, productVersion); + formatted = esxVMX_FormatConfig(NULL, caps, def, productVersion); if (formatted == NULL) { goto failure; @@ -165,7 +167,7 @@ mymain(int argc, char **argv) } \ } while (0) - testESXCapsInit(); + testCapsInit(); if (caps == NULL) { return EXIT_FAILURE;