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-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-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-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-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-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-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 @@ - ++ 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-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-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-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-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-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-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-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 @@ + + + + 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; - ++ +