This works for file-backed SCSI disk device with a datastore related source path. --- docs/drvesx.html.in | 6 ++ docs/schemas/domain.rng | 1 + src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/esx/esx_vi_generator.input | 149 +++++++++++++++++++++++++++++++++ src/esx/esx_vi_generator.py | 3 + src/esx/esx_vmx.c | 180 +++++++++++++++++++++++++++++++++++++++- src/esx/esx_vmx.h | 8 ++- 8 files changed, 344 insertions(+), 5 deletions(-) diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index f4e7530..75c24cb 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -292,6 +292,12 @@ ethernet0.checkMACAddress = "false" <h4>SCSI controller models</h4> <dl> + <dt><code>auto</code></dt> + <dd> + This isn't a actual controller model. If specified the ESX driver + tries to detect the SCSI controller model referenced in the + <code>.vmdk</code> file and use it. <span class="since">Since 0.8.3</span> + </dd> <dt><code>buslogic</code></dt> <dd> BusLogic SCSI controller for older guests. diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index b171d01..e090366 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -673,6 +673,7 @@ <optional> <attribute name="model"> <choice> + <value>auto</value> <value>buslogic</value> <value>lsilogic</value> <value>lsisas1068</value> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3cd43c4..eb7fa13 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -140,6 +140,7 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, "virtio-serial") VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST, + "auto", "buslogic", "lsilogic", "lsisas1068", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3451302..890fa0b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -196,6 +196,7 @@ enum virDomainControllerType { enum virDomainControllerModel { + VIR_DOMAIN_CONTROLLER_MODEL_AUTO, VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC, VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC, VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068, diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input index ff65178..b4b33f6 100644 --- a/src/esx/esx_vi_generator.input +++ b/src/esx/esx_vi_generator.input @@ -184,6 +184,40 @@ object Event end +object FileInfo + String path r + Long fileSize o + DateTime modification o +end + + +object FileQuery +end + + +object FileQueryFlags + Boolean fileType r + Boolean fileSize r + Boolean modification r +end + + +object FloppyImageFileInfo extends FileInfo +end + + +object FloppyImageFileQuery extends FileQuery +end + + +object FolderFileInfo extends FileInfo +end + + +object FolderFileQuery extends FileQuery +end + + object HostCpuIdInfo Int level r String vendor o @@ -194,6 +228,22 @@ object HostCpuIdInfo end +object HostDatastoreBrowserSearchResults + ManagedObjectReference datastore o + String folderPath o + FileInfo file ol +end + + +object HostDatastoreBrowserSearchSpec + FileQuery query ol + FileQueryFlags details o + Boolean searchCaseInsensitive o + String matchPattern ol + Boolean sortFoldersFirst o +end + + object HostFileSystemVolume String type r String name r @@ -225,6 +275,14 @@ object HostVmfsVolume extends HostFileSystemVolume end +object IsoImageFileInfo extends FileInfo +end + + +object IsoImageFileQuery extends FileQuery +end + + object LocalDatastoreInfo extends DatastoreInfo String path o end @@ -424,6 +482,14 @@ object TaskInfo end +object TemplateConfigFileInfo extends VmConfigFileInfo +end + + +object TemplateConfigFileQuery extends VmConfigFileQuery +end + + object TraversalSpec extends SelectionSpec String type r String path r @@ -502,6 +568,82 @@ object VirtualMachineSnapshotTree end +object VmConfigFileInfo extends FileInfo + Int configVersion o +end + + +object VmConfigFileQuery extends FileQuery + VmConfigFileQueryFilter filter o + VmConfigFileQueryFlags details o +end + + +object VmConfigFileQueryFilter + Int matchConfigVersion ol +end + + +object VmConfigFileQueryFlags + Boolean configVersion r +end + + +object VmDiskFileInfo extends FileInfo + String diskType o + Long capacityKb o + Int hardwareVersion o + String controllerType o + String diskExtents ol +end + + +object VmDiskFileQuery extends FileQuery + VmDiskFileQueryFilter filter o + VmDiskFileQueryFlags details o +end + + +object VmDiskFileQueryFilter + String diskType ol + Int matchHardwareVersion ol + String controllerType ol +end + + +object VmDiskFileQueryFlags + Boolean diskType r + Boolean capacityKb r + Boolean hardwareVersion r + Boolean controllerType o + Boolean diskExtents o +end + + +object VmLogFileInfo extends FileInfo +end + + +object VmLogFileQuery extends FileQuery +end + + +object VmNvramFileInfo extends FileInfo +end + + +object VmNvramFileQuery extends FileQuery +end + + +object VmSnapshotFileInfo extends FileInfo +end + + +object VmSnapshotFileQuery extends FileQuery +end + + object VmfsDatastoreInfo extends DatastoreInfo HostVmfsVolume vmfs o end @@ -658,6 +800,13 @@ method RevertToSnapshot_Task returns ManagedObjectReference r end +method SearchDatastore_Task returns ManagedObjectReference r + ManagedObjectReference _this r + String datastorePath r + HostDatastoreBrowserSearchSpec searchSpec o +end + + method SessionIsActive returns Boolean r ManagedObjectReference _this:SessionManager r String sessionID r diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py index ff3e3d1..82bc9b6 100755 --- a/src/esx/esx_vi_generator.py +++ b/src/esx/esx_vi_generator.py @@ -1123,7 +1123,10 @@ additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE additional_object_features = { "DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST, "Event" : Object.FEATURE__LIST, + "FileInfo" : Object.FEATURE__DYNAMIC_CAST, + "FileQuery" : Object.FEATURE__DYNAMIC_CAST, "HostCpuIdInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST, + "HostDatastoreBrowserSearchResults" : Object.FEATURE__ANY_TYPE, "ManagedObjectReference" : Object.FEATURE__ANY_TYPE, "ObjectContent" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST, "PerfCounterInfo" : Object.FEATURE__LIST, diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c index 46875f3..f57e046 100644 --- a/src/esx/esx_vmx.c +++ b/src/esx/esx_vmx.c @@ -29,6 +29,7 @@ #include "virterror_internal.h" #include "memory.h" #include "logging.h" +#include "esx_vi_methods.h" #include "esx_private.h" #include "esx_util.h" #include "esx_vmx.h" @@ -707,8 +708,172 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def, int -esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4], - bool present[4]) +esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx, + virDomainDiskDefPtr def, int *model) +{ + int result = -1; + char *datastoreName = NULL; + char *directoryName = NULL; + char *fileName = NULL; + char *datastorePath = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *datastore = NULL; + esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL; + esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL; + esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL; + esxVI_ManagedObjectReference *task = NULL; + esxVI_TaskInfoState taskInfoState; + esxVI_TaskInfo *taskInfo = NULL; + esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL; + esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL; + + if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK || + def->bus != VIR_DOMAIN_DISK_BUS_SCSI || + def->type != VIR_DOMAIN_DISK_TYPE_FILE || + def->src == NULL || + ! STRPREFIX(def->src, "[")) { + /* + * This isn't a file-based SCSI disk device with a datastore related + * source path => do nothing. + */ + return 0; + } + + if (esxUtil_ParseDatastoreRelatedPath(def->src, &datastoreName, + &directoryName, &fileName) < 0) { + goto cleanup; + } + + if (directoryName == NULL) { + if (virAsprintf(&datastorePath, "[%s]", datastoreName) < 0) { + virReportOOMError(); + goto cleanup; + } + } else { + if (virAsprintf(&datastorePath, "[%s] %s", datastoreName, + directoryName) < 0) { + virReportOOMError(); + goto cleanup; + } + } + + /* Lookup HostDatastoreBrowser */ + if (esxVI_String_AppendValueToList(&propertyNameList, "browser") < 0 || + esxVI_LookupDatastoreByName(ctx, datastoreName, propertyNameList, + &datastore, + esxVI_Occurrence_RequiredItem) < 0 || + esxVI_GetManagedObjectReference(datastore, "browser", + &hostDatastoreBrowser, + esxVI_Occurrence_RequiredItem) < 0) { + goto cleanup; + } + + /* Build HostDatastoreBrowserSearchSpec */ + if (esxVI_HostDatastoreBrowserSearchSpec_Alloc(&searchSpec) < 0 || + esxVI_FileQueryFlags_Alloc(&searchSpec->details) < 0) { + goto cleanup; + } + + searchSpec->details->fileType = esxVI_Boolean_True; + searchSpec->details->fileSize = esxVI_Boolean_False; + searchSpec->details->modification = esxVI_Boolean_False; + + if (esxVI_VmDiskFileQuery_Alloc(&vmDiskFileQuery) < 0 || + esxVI_VmDiskFileQueryFlags_Alloc(&vmDiskFileQuery->details) < 0 || + esxVI_FileQuery_AppendToList + (&searchSpec->query, + esxVI_FileQuery_DynamicCast(vmDiskFileQuery)) < 0) { + goto cleanup; + } + + vmDiskFileQuery->details->diskType = esxVI_Boolean_False; + vmDiskFileQuery->details->capacityKb = esxVI_Boolean_False; + vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False; + vmDiskFileQuery->details->controllerType = esxVI_Boolean_True; + vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False; + + if (esxVI_String_Alloc(&searchSpec->matchPattern) < 0) { + goto cleanup; + } + + searchSpec->matchPattern->value = fileName; + + /* Search datastore for file */ + if (esxVI_SearchDatastore_Task(ctx, hostDatastoreBrowser, datastorePath, + searchSpec, &task) < 0 || + esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Boolean_False, + &taskInfoState) < 0) { + goto cleanup; + } + + if (taskInfoState != esxVI_TaskInfoState_Success) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("Could not serach in datastore '%s'"), datastoreName); + goto cleanup; + } + + if (esxVI_LookupTaskInfoByTask(ctx, task, &taskInfo) < 0 || + esxVI_HostDatastoreBrowserSearchResults_CastFromAnyType + (taskInfo->result, &searchResults) < 0) { + goto cleanup; + } + + /* Interpret search result */ + vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(searchResults->file); + + if (vmDiskFileInfo == NULL || vmDiskFileInfo->controllerType == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("Could not lookup controller model for '%s'"), def->src); + goto cleanup; + } + + if (STRCASEEQ(vmDiskFileInfo->controllerType, + "VirtualBusLogicController")) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC; + } else if (STRCASEEQ(vmDiskFileInfo->controllerType, + "VirtualLsiLogicController")) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC; + } else if (STRCASEEQ(vmDiskFileInfo->controllerType, + "VirtualLsiLogicSASController")) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068; + } else if (STRCASEEQ(vmDiskFileInfo->controllerType, + "ParaVirtualSCSIController")) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_PVSCSI; + } else { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("Found unexpected controller model '%s' for disk '%s'"), + vmDiskFileInfo->controllerType, def->src); + goto cleanup; + } + + result = 0; + + cleanup: + /* Don't double free fileName */ + if (searchSpec != NULL && searchSpec->matchPattern != NULL) { + searchSpec->matchPattern->value = NULL; + } + + VIR_FREE(datastoreName); + VIR_FREE(directoryName); + VIR_FREE(fileName); + VIR_FREE(datastorePath); + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&datastore); + esxVI_ManagedObjectReference_Free(&hostDatastoreBrowser); + esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec); + esxVI_ManagedObjectReference_Free(&task); + esxVI_TaskInfo_Free(&taskInfo); + esxVI_HostDatastoreBrowserSearchResults_Free(&searchResults); + + return result; +} + + + +int +esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def, + int virtualDev[4], bool present[4]) { int i; virDomainDiskDefPtr disk; @@ -737,6 +902,14 @@ esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4], return -1; } + if (ctx != NULL && + controller->model == VIR_DOMAIN_CONTROLLER_MODEL_AUTO) { + if (esxVMX_AutodetectSCSIControllerModel(ctx, disk, + &controller->model) < 0) { + return -1; + } + } + if (controller->model != -1 && controller->model != VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC && controller->model != VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC && @@ -2611,7 +2784,8 @@ esxVMX_FormatConfig(esxVI_Context *ctx, virCapsPtr caps, virDomainDefPtr def, } } - if (esxVMX_GatherSCSIControllers(def, scsi_virtualDev, scsi_present) < 0) { + if (esxVMX_GatherSCSIControllers(ctx, def, scsi_virtualDev, + scsi_present) < 0) { goto failure; } diff --git a/src/esx/esx_vmx.h b/src/esx/esx_vmx.h index a9015fb..3ccae7a 100644 --- a/src/esx/esx_vmx.h +++ b/src/esx/esx_vmx.h @@ -48,8 +48,12 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def, virDomainDiskDefPtr disk); int -esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4], - bool present[4]); +esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx, + virDomainDiskDefPtr def, int *model); + +int +esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def, + int virtualDev[4], bool present[4]); char * esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx, -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list