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