[libvirt] [PATCH] esx: Add autodetection for the SCSI controller model

Matthias Bolte matthias.bolte at googlemail.com
Tue Jul 6 18:19:55 UTC 2010


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




More information about the libvir-list mailing list