mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-18 18:45:16 +00:00
esx: Add autodetection for the SCSI controller model
This works for file-backed SCSI disk device with a datastore related source path.
This commit is contained in:
parent
afb85c5889
commit
cf8cf8a59f
@ -292,6 +292,15 @@ ethernet0.checkMACAddress = "false"
|
|||||||
|
|
||||||
<h4>SCSI controller models</h4>
|
<h4>SCSI controller models</h4>
|
||||||
<dl>
|
<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. Autodetection fails when a
|
||||||
|
SCSI controller has multiple disks attached and the SCSI controller
|
||||||
|
models referenced in the <code>.vmdk</code> files are inconsistent.
|
||||||
|
<span class="since">Since 0.8.3</span>
|
||||||
|
</dd>
|
||||||
<dt><code>buslogic</code></dt>
|
<dt><code>buslogic</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
BusLogic SCSI controller for older guests.
|
BusLogic SCSI controller for older guests.
|
||||||
|
@ -676,6 +676,7 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<attribute name="model">
|
<attribute name="model">
|
||||||
<choice>
|
<choice>
|
||||||
|
<value>auto</value>
|
||||||
<value>buslogic</value>
|
<value>buslogic</value>
|
||||||
<value>lsilogic</value>
|
<value>lsilogic</value>
|
||||||
<value>lsisas1068</value>
|
<value>lsisas1068</value>
|
||||||
|
@ -141,6 +141,7 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
|
|||||||
"virtio-serial")
|
"virtio-serial")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
VIR_ENUM_IMPL(virDomainControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
||||||
|
"auto",
|
||||||
"buslogic",
|
"buslogic",
|
||||||
"lsilogic",
|
"lsilogic",
|
||||||
"lsisas1068",
|
"lsisas1068",
|
||||||
|
@ -196,6 +196,7 @@ enum virDomainControllerType {
|
|||||||
|
|
||||||
|
|
||||||
enum virDomainControllerModel {
|
enum virDomainControllerModel {
|
||||||
|
VIR_DOMAIN_CONTROLLER_MODEL_AUTO,
|
||||||
VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC,
|
VIR_DOMAIN_CONTROLLER_MODEL_BUSLOGIC,
|
||||||
VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC,
|
VIR_DOMAIN_CONTROLLER_MODEL_LSILOGIC,
|
||||||
VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068,
|
VIR_DOMAIN_CONTROLLER_MODEL_LSISAS1068,
|
||||||
|
@ -184,6 +184,40 @@ object Event
|
|||||||
end
|
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
|
object HostCpuIdInfo
|
||||||
Int level r
|
Int level r
|
||||||
String vendor o
|
String vendor o
|
||||||
@ -194,6 +228,22 @@ object HostCpuIdInfo
|
|||||||
end
|
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
|
object HostFileSystemVolume
|
||||||
String type r
|
String type r
|
||||||
String name r
|
String name r
|
||||||
@ -225,6 +275,14 @@ object HostVmfsVolume extends HostFileSystemVolume
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
object IsoImageFileInfo extends FileInfo
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
object IsoImageFileQuery extends FileQuery
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
object LocalDatastoreInfo extends DatastoreInfo
|
object LocalDatastoreInfo extends DatastoreInfo
|
||||||
String path o
|
String path o
|
||||||
end
|
end
|
||||||
@ -424,6 +482,14 @@ object TaskInfo
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
object TemplateConfigFileInfo extends VmConfigFileInfo
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
object TemplateConfigFileQuery extends VmConfigFileQuery
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
object TraversalSpec extends SelectionSpec
|
object TraversalSpec extends SelectionSpec
|
||||||
String type r
|
String type r
|
||||||
String path r
|
String path r
|
||||||
@ -502,6 +568,82 @@ object VirtualMachineSnapshotTree
|
|||||||
end
|
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
|
object VmfsDatastoreInfo extends DatastoreInfo
|
||||||
HostVmfsVolume vmfs o
|
HostVmfsVolume vmfs o
|
||||||
end
|
end
|
||||||
@ -658,6 +800,13 @@ method RevertToSnapshot_Task returns ManagedObjectReference r
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
method SearchDatastore_Task returns ManagedObjectReference r
|
||||||
|
ManagedObjectReference _this r
|
||||||
|
String datastorePath r
|
||||||
|
HostDatastoreBrowserSearchSpec searchSpec o
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
method SessionIsActive returns Boolean r
|
method SessionIsActive returns Boolean r
|
||||||
ManagedObjectReference _this:SessionManager r
|
ManagedObjectReference _this:SessionManager r
|
||||||
String sessionID r
|
String sessionID r
|
||||||
|
@ -1123,7 +1123,10 @@ additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE
|
|||||||
|
|
||||||
additional_object_features = { "DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST,
|
additional_object_features = { "DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST,
|
||||||
"Event" : Object.FEATURE__LIST,
|
"Event" : Object.FEATURE__LIST,
|
||||||
|
"FileInfo" : Object.FEATURE__DYNAMIC_CAST,
|
||||||
|
"FileQuery" : Object.FEATURE__DYNAMIC_CAST,
|
||||||
"HostCpuIdInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
|
"HostCpuIdInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
|
||||||
|
"HostDatastoreBrowserSearchResults" : Object.FEATURE__ANY_TYPE,
|
||||||
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
|
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
|
||||||
"ObjectContent" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST,
|
"ObjectContent" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST,
|
||||||
"PerfCounterInfo" : Object.FEATURE__LIST,
|
"PerfCounterInfo" : Object.FEATURE__LIST,
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
#include "esx_vi_methods.h"
|
||||||
#include "esx_private.h"
|
#include "esx_private.h"
|
||||||
#include "esx_util.h"
|
#include "esx_util.h"
|
||||||
#include "esx_vmx.h"
|
#include "esx_vmx.h"
|
||||||
@ -433,6 +434,7 @@ def->parallels[0]...
|
|||||||
* are actually SCSI controller models in the ESX case */
|
* are actually SCSI controller models in the ESX case */
|
||||||
VIR_ENUM_DECL(esxVMX_SCSIControllerModel)
|
VIR_ENUM_DECL(esxVMX_SCSIControllerModel)
|
||||||
VIR_ENUM_IMPL(esxVMX_SCSIControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
VIR_ENUM_IMPL(esxVMX_SCSIControllerModel, VIR_DOMAIN_CONTROLLER_MODEL_LAST,
|
||||||
|
"auto", /* just to match virDomainControllerModel, will never be used */
|
||||||
"buslogic",
|
"buslogic",
|
||||||
"lsilogic",
|
"lsilogic",
|
||||||
"lsisas1068",
|
"lsisas1068",
|
||||||
@ -716,34 +718,244 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4],
|
esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
|
||||||
bool present[4])
|
virDomainDiskDefPtr def, int *model)
|
||||||
{
|
{
|
||||||
int i;
|
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_VMPVSCSI;
|
||||||
|
} 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 result = -1;
|
||||||
|
int i, k;
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virDomainControllerDefPtr controller = NULL;
|
virDomainControllerDefPtr controller;
|
||||||
|
bool controllerHasDisksAttached;
|
||||||
|
int count = 0;
|
||||||
|
int *autodetectedModels;
|
||||||
|
|
||||||
for (i = 0; i < def->ndisks; ++i) {
|
if (VIR_ALLOC_N(autodetectedModels, def->ndisks) < 0) {
|
||||||
disk = def->disks[i];
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
|
for (i = 0; i < def->ncontrollers; ++i) {
|
||||||
|
controller = def->controllers[i];
|
||||||
|
|
||||||
|
if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
|
||||||
|
// skip non-SCSI controllers
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller = NULL;
|
controllerHasDisksAttached = false;
|
||||||
|
|
||||||
for (i = 0; i < def->ncontrollers; ++i) {
|
for (k = 0; k < def->ndisks; ++k) {
|
||||||
if (def->controllers[i]->idx == disk->info.addr.drive.controller) {
|
disk = def->disks[k];
|
||||||
controller = def->controllers[i];
|
|
||||||
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
|
||||||
|
disk->info.addr.drive.controller == controller->idx) {
|
||||||
|
controllerHasDisksAttached = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller == NULL) {
|
if (! controllerHasDisksAttached) {
|
||||||
|
// skip SCSI controllers without attached disks
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx != NULL &&
|
||||||
|
controller->model == VIR_DOMAIN_CONTROLLER_MODEL_AUTO) {
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
// try to autodetect the SCSI controller model by collecting
|
||||||
|
// SCSI controller model of all disks attached to this controller
|
||||||
|
for (k = 0; k < def->ndisks; ++k) {
|
||||||
|
disk = def->disks[k];
|
||||||
|
|
||||||
|
if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
|
||||||
|
disk->info.addr.drive.controller == controller->idx) {
|
||||||
|
if (esxVMX_AutodetectSCSIControllerModel
|
||||||
|
(ctx, disk, &autodetectedModels[count]) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// autodetection fails when the disks attached to one controller
|
||||||
|
// have inconsistent SCSI controller models
|
||||||
|
for (k = 0; k < count; ++k) {
|
||||||
|
if (autodetectedModels[k] != autodetectedModels[0]) {
|
||||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Missing SCSI controller for index %d"),
|
_("Disks on SCSI controller %d have inconsistent "
|
||||||
disk->info.addr.drive.controller);
|
"controller models, cannot autodetect model"),
|
||||||
return -1;
|
controller->idx);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller->model = autodetectedModels[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller->model != -1 &&
|
if (controller->model != -1 &&
|
||||||
@ -756,14 +968,19 @@ esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4],
|
|||||||
"'controller' to be 'buslogic' or 'lsilogic' or "
|
"'controller' to be 'buslogic' or 'lsilogic' or "
|
||||||
"'lsisas1068' or 'vmpvscsi' but found '%s'"),
|
"'lsisas1068' or 'vmpvscsi' but found '%s'"),
|
||||||
virDomainControllerModelTypeToString(controller->model));
|
virDomainControllerModelTypeToString(controller->model));
|
||||||
return -1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
present[controller->idx] = true;
|
present[controller->idx] = true;
|
||||||
virtualDev[controller->idx] = controller->model;
|
virtualDev[controller->idx] = controller->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
result = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(autodetectedModels);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2620,7 +2837,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;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,12 @@ esxVMX_HandleLegacySCSIDiskDriverName(virDomainDefPtr def,
|
|||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk);
|
||||||
|
|
||||||
int
|
int
|
||||||
esxVMX_GatherSCSIControllers(virDomainDefPtr def, int virtualDev[4],
|
esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
|
||||||
bool present[4]);
|
virDomainDiskDefPtr def, int *model);
|
||||||
|
|
||||||
|
int
|
||||||
|
esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
|
||||||
|
int virtualDev[4], bool present[4]);
|
||||||
|
|
||||||
char *
|
char *
|
||||||
esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
|
esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user