esx: Add read-only storage volume access

This allows to list existing volumes and to retrieve information
about them.
This commit is contained in:
Matthias Bolte 2010-08-08 00:24:29 +02:00
parent 2c090a555b
commit 681ff75e88
5 changed files with 724 additions and 116 deletions

View File

@ -348,19 +348,7 @@ esxAutodetectSCSIControllerModel(virDomainDiskDefPtr def, int *model,
{
int result = -1;
esxVMX_Data *data = opaque;
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_FileInfo *fileInfo = NULL;
esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL;
if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK ||
@ -375,87 +363,12 @@ esxAutodetectSCSIControllerModel(virDomainDiskDefPtr def, int *model,
return 0;
}
if (esxUtil_ParseDatastorePath(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(data->ctx, datastoreName, propertyNameList,
&datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetManagedObjectReference(datastore, "browser",
&hostDatastoreBrowser,
if (esxVI_LookupFileInfoByDatastorePath(data->ctx, def->src, &fileInfo,
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(data->ctx, hostDatastoreBrowser,
datastorePath, searchSpec, &task) < 0 ||
esxVI_WaitForTaskCompletion(data->ctx, task, NULL, esxVI_Occurrence_None,
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(data->ctx, task, &taskInfo) < 0 ||
esxVI_HostDatastoreBrowserSearchResults_CastFromAnyType
(taskInfo->result, &searchResults) < 0) {
goto cleanup;
}
/* Interpret search result */
vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(searchResults->file);
vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(fileInfo);
if (vmDiskFileInfo == NULL || vmDiskFileInfo->controllerType == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
@ -485,22 +398,7 @@ esxAutodetectSCSIControllerModel(virDomainDiskDefPtr def, int *model,
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);
esxVI_FileInfo_Free(&fileInfo);
return result;
}

View File

@ -32,6 +32,7 @@
#include "logging.h"
#include "uuid.h"
#include "storage_conf.h"
#include "storage_file.h"
#include "esx_private.h"
#include "esx_storage_driver.h"
#include "esx_vi.h"
@ -310,6 +311,14 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
static virStoragePoolPtr
esxStoragePoolLookupByVolume(virStorageVolPtr volume)
{
return esxStoragePoolLookupByName(volume->conn, volume->pool);
}
static int
esxStoragePoolRefresh(virStoragePoolPtr pool, unsigned int flags)
{
@ -555,6 +564,411 @@ esxStoragePoolSetAutostart(virStoragePoolPtr pool ATTRIBUTE_UNUSED,
static int
esxStoragePoolNumberOfStorageVolumes(virStoragePoolPtr pool)
{
bool success = false;
esxPrivate *priv = pool->conn->storagePrivateData;
esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL;
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
esxVI_FileInfo *fileInfo = NULL;
int count = 0;
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_LookupDatastoreContentByDatastoreName(priv->primary, pool->name,
&searchResultsList) < 0) {
goto cleanup;
}
/* Interpret search result */
for (searchResults = searchResultsList; searchResults != NULL;
searchResults = searchResults->_next) {
for (fileInfo = searchResults->file; fileInfo != NULL;
fileInfo = fileInfo->_next) {
++count;
}
}
success = true;
cleanup:
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
return success ? count : -1;
}
static int
esxStoragePoolListStorageVolumes(virStoragePoolPtr pool, char **const names,
int maxnames)
{
bool success = false;
esxPrivate *priv = pool->conn->storagePrivateData;
esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL;
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
esxVI_FileInfo *fileInfo = NULL;
char *datastoreName = NULL;
char *directoryName = NULL;
char *fileName = NULL;
char *prefix = NULL;
int count = 0;
int i;
if (names == NULL || maxnames < 0) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s", _("Invalid argument"));
return -1;
}
if (maxnames == 0) {
return 0;
}
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_LookupDatastoreContentByDatastoreName(priv->primary, pool->name,
&searchResultsList) < 0) {
goto cleanup;
}
/* Interpret search result */
for (searchResults = searchResultsList; searchResults != NULL;
searchResults = searchResults->_next) {
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
VIR_FREE(fileName);
VIR_FREE(prefix);
if (esxUtil_ParseDatastorePath(searchResults->folderPath, &datastoreName,
&directoryName, &fileName) < 0) {
goto cleanup;
}
if (directoryName != NULL) {
if (virAsprintf(&prefix, "%s/%s", directoryName, fileName) < 0) {
virReportOOMError();
goto cleanup;
}
} else {
prefix = strdup(fileName);
if (prefix == NULL) {
virReportOOMError();
goto cleanup;
}
}
for (fileInfo = searchResults->file; fileInfo != NULL;
fileInfo = fileInfo->_next) {
if (*prefix == '\0') {
names[count] = strdup(fileInfo->path);
if (names[count] == NULL) {
virReportOOMError();
goto cleanup;
}
} else if (virAsprintf(&names[count], "%s/%s", prefix,
fileInfo->path) < 0) {
virReportOOMError();
goto cleanup;
}
++count;
}
}
success = true;
cleanup:
if (! success) {
for (i = 0; i < count; ++i) {
VIR_FREE(names[i]);
}
count = -1;
}
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
VIR_FREE(fileName);
VIR_FREE(prefix);
return count;
}
static virStorageVolPtr
esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
{
virStorageVolPtr volume = NULL;
esxPrivate *priv = pool->conn->storagePrivateData;
char *datastorePath = NULL;
esxVI_FileInfo *fileInfo = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
if (virAsprintf(&datastorePath, "[%s] %s", pool->name, name) < 0) {
virReportOOMError();
goto cleanup;
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
&fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
volume = virGetStorageVol(pool->conn, pool->name, name, datastorePath);
cleanup:
VIR_FREE(datastorePath);
esxVI_FileInfo_Free(&fileInfo);
return volume;
}
static virStorageVolPtr
esxStorageVolumeLookupByKeyOrPath(virConnectPtr conn, const char *keyOrPath)
{
virStorageVolPtr volume = NULL;
esxPrivate *priv = conn->storagePrivateData;
char *datastoreName = NULL;
char *directoryName = NULL;
char *fileName = NULL;
char *volumeName = NULL;
esxVI_FileInfo *fileInfo = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
if (esxUtil_ParseDatastorePath(keyOrPath, &datastoreName, &directoryName,
&fileName) < 0) {
goto cleanup;
}
if (directoryName != NULL) {
if (virAsprintf(&volumeName, "%s/%s", directoryName, fileName) < 0) {
virReportOOMError();
goto cleanup;
}
} else {
volumeName = strdup(fileName);
if (volumeName == NULL) {
virReportOOMError();
goto cleanup;
}
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
volume = virGetStorageVol(conn, datastoreName, volumeName, keyOrPath);
cleanup:
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
VIR_FREE(fileName);
VIR_FREE(volumeName);
esxVI_FileInfo_Free(&fileInfo);
return volume;
}
static int
esxStorageVolumeGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info)
{
int result = -1;
esxPrivate *priv = volume->conn->storagePrivateData;
char *datastorePath = NULL;
esxVI_FileInfo *fileInfo = NULL;
esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL;
memset(info, 0, sizeof (*info));
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (virAsprintf(&datastorePath, "[%s] %s", volume->pool, volume->name) < 0) {
virReportOOMError();
goto cleanup;
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
&fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(fileInfo);
info->type = VIR_STORAGE_VOL_FILE;
if (vmDiskFileInfo != NULL) {
info->capacity = vmDiskFileInfo->capacityKb->value * 1024; /* Scale from kilobyte to byte */
info->allocation = vmDiskFileInfo->fileSize->value;
} else {
info->capacity = fileInfo->fileSize->value;
info->allocation = fileInfo->fileSize->value;
}
result = 0;
cleanup:
VIR_FREE(datastorePath);
esxVI_FileInfo_Free(&fileInfo);
return result;
}
static char *
esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
{
esxPrivate *priv = volume->conn->storagePrivateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_DatastoreInfo *datastoreInfo = NULL;
virStoragePoolDef pool;
char *datastorePath = NULL;
esxVI_FileInfo *fileInfo = NULL;
esxVI_VmDiskFileInfo *vmDiskFileInfo = NULL;
esxVI_IsoImageFileInfo *isoImageFileInfo = NULL;
esxVI_FloppyImageFileInfo *floppyImageFileInfo = NULL;
virStorageVolDef def;
char *xml = NULL;
virCheckFlags(0, NULL);
memset(&pool, 0, sizeof (pool));
memset(&def, 0, sizeof (def));
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
/* Lookup storage pool type */
if (esxVI_String_AppendValueToList(&propertyNameList, "info") < 0 ||
esxVI_LookupDatastoreByName(priv->primary, volume->pool,
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "info")) {
if (esxVI_DatastoreInfo_CastFromAnyType(dynamicProperty->val,
&datastoreInfo) < 0) {
goto cleanup;
}
break;
}
}
if (esxVI_LocalDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
pool.type = VIR_STORAGE_POOL_DIR;
} else if (esxVI_NasDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
pool.type = VIR_STORAGE_POOL_NETFS;
} else if (esxVI_VmfsDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
pool.type = VIR_STORAGE_POOL_FS;
} else {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("DatastoreInfo has unexpected type"));
goto cleanup;
}
/* Lookup file info */
if (virAsprintf(&datastorePath, "[%s] %s", volume->pool, volume->name) < 0) {
virReportOOMError();
goto cleanup;
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
&fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
vmDiskFileInfo = esxVI_VmDiskFileInfo_DynamicCast(fileInfo);
isoImageFileInfo = esxVI_IsoImageFileInfo_DynamicCast(fileInfo);
floppyImageFileInfo = esxVI_FloppyImageFileInfo_DynamicCast(fileInfo);
def.name = volume->name;
def.key = datastorePath;
def.type = VIR_STORAGE_VOL_FILE;
def.target.path = datastorePath;
if (vmDiskFileInfo != NULL) {
def.capacity = vmDiskFileInfo->capacityKb->value * 1024; /* Scale from kilobyte to byte */
def.allocation = vmDiskFileInfo->fileSize->value;
def.target.format = VIR_STORAGE_FILE_VMDK;
} else if (isoImageFileInfo != NULL) {
def.capacity = fileInfo->fileSize->value;
def.allocation = fileInfo->fileSize->value;
def.target.format = VIR_STORAGE_FILE_ISO;
} else if (floppyImageFileInfo != NULL) {
def.capacity = fileInfo->fileSize->value;
def.allocation = fileInfo->fileSize->value;
def.target.format = VIR_STORAGE_FILE_RAW;
} else {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("File '%s' has unknown type"), datastorePath);
goto cleanup;
}
xml = virStorageVolDefFormat(&pool, &def);
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore);
esxVI_DatastoreInfo_Free(&datastoreInfo);
VIR_FREE(datastorePath);
esxVI_FileInfo_Free(&fileInfo);
return xml;
}
static char *
esxStorageVolumeGetPath(virStorageVolPtr volume)
{
char *path;
if (virAsprintf(&path, "[%s] %s", volume->pool, volume->name) < 0) {
virReportOOMError();
return NULL;
}
return path;
}
static int
esxStoragePoolIsActive(virStoragePoolPtr pool ATTRIBUTE_UNUSED)
{
@ -572,6 +986,7 @@ esxStoragePoolIsPersistent(virStoragePoolPtr pool ATTRIBUTE_UNUSED)
}
static virStorageDriver esxStorageDriver = {
"ESX", /* name */
esxStorageOpen, /* open */
@ -583,7 +998,7 @@ static virStorageDriver esxStorageDriver = {
NULL, /* findPoolSources */
esxStoragePoolLookupByName, /* poolLookupByName */
esxStoragePoolLookupByUUID, /* poolLookupByUUID */
NULL, /* poolLookupByVolume */
esxStoragePoolLookupByVolume, /* poolLookupByVolume */
NULL, /* poolCreateXML */
NULL, /* poolDefineXML */
NULL, /* poolBuild */
@ -596,18 +1011,18 @@ static virStorageDriver esxStorageDriver = {
esxStoragePoolGetXMLDesc, /* poolGetXMLDesc */
esxStoragePoolGetAutostart, /* poolGetAutostart */
esxStoragePoolSetAutostart, /* poolSetAutostart */
NULL, /* poolNumOfVolumes */
NULL, /* poolListVolumes */
NULL, /* volLookupByName */
NULL, /* volLookupByKey */
NULL, /* volLookupByPath */
esxStoragePoolNumberOfStorageVolumes, /* poolNumOfVolumes */
esxStoragePoolListStorageVolumes, /* poolListVolumes */
esxStorageVolumeLookupByName, /* volLookupByName */
esxStorageVolumeLookupByKeyOrPath, /* volLookupByKey */
esxStorageVolumeLookupByKeyOrPath, /* volLookupByPath */
NULL, /* volCreateXML */
NULL, /* volCreateXMLFrom */
NULL, /* volDelete */
NULL, /* volWipe */
NULL, /* volGetInfo */
NULL, /* volGetXMLDesc */
NULL, /* volGetPath */
esxStorageVolumeGetInfo, /* volGetInfo */
esxStorageVolumeDumpXML, /* volGetXMLDesc */
esxStorageVolumeGetPath, /* volGetPath */
esxStoragePoolIsActive, /* poolIsActive */
esxStoragePoolIsPersistent, /* poolIsPersistent */
};

View File

@ -2933,6 +2933,285 @@ esxVI_LookupCurrentSnapshotTree
int
esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
const char *datastorePath,
esxVI_FileInfo **fileInfo,
esxVI_Occurrence occurrence)
{
int result = -1;
char *datastoreName = NULL;
char *directoryName = NULL;
char *fileName = NULL;
char *datastorePathWithoutFileName = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL;
esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL;
esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL;
esxVI_IsoImageFileQuery *isoImageFileQuery = NULL;
esxVI_FloppyImageFileQuery *floppyImageFileQuery = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
esxVI_TaskInfo *taskInfo = NULL;
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
if (fileInfo == NULL || *fileInfo != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
if (esxUtil_ParseDatastorePath(datastorePath, &datastoreName,
&directoryName, &fileName) < 0) {
goto cleanup;
}
if (directoryName == NULL) {
if (virAsprintf(&datastorePathWithoutFileName, "[%s]",
datastoreName) < 0) {
virReportOOMError();
goto cleanup;
}
} else {
if (virAsprintf(&datastorePathWithoutFileName, "[%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_True;
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_True;
vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
if (esxVI_IsoImageFileQuery_Alloc(&isoImageFileQuery) < 0 ||
esxVI_FileQuery_AppendToList
(&searchSpec->query,
esxVI_FileQuery_DynamicCast(isoImageFileQuery)) < 0) {
goto cleanup;
}
if (esxVI_FloppyImageFileQuery_Alloc(&floppyImageFileQuery) < 0 ||
esxVI_FileQuery_AppendToList
(&searchSpec->query,
esxVI_FileQuery_DynamicCast(floppyImageFileQuery)) < 0) {
goto cleanup;
}
if (esxVI_String_Alloc(&searchSpec->matchPattern) < 0) {
goto cleanup;
}
searchSpec->matchPattern->value = fileName;
/* Search datastore for file */
if (esxVI_SearchDatastore_Task(ctx, hostDatastoreBrowser,
datastorePathWithoutFileName, searchSpec,
&task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Occurrence_None,
esxVI_Boolean_False, &taskInfoState) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_VI_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 */
if (searchResults->file == NULL) {
if (occurrence == esxVI_Occurrence_OptionalItem) {
result = 0;
goto cleanup;
} else {
ESX_VI_ERROR(VIR_ERR_NO_STORAGE_VOL,
_("No storage volume with key or path '%s'"),
datastorePath);
goto cleanup;
}
}
*fileInfo = searchResults->file;
searchResults->file = NULL;
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(datastorePathWithoutFileName);
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
esxVI_LookupDatastoreContentByDatastoreName
(esxVI_Context *ctx, const char *datastoreName,
esxVI_HostDatastoreBrowserSearchResults **searchResultsList)
{
int result = -1;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL;
esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL;
esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL;
esxVI_IsoImageFileQuery *isoImageFileQuery = NULL;
esxVI_FloppyImageFileQuery *floppyImageFileQuery = NULL;
char *datastorePath = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
esxVI_TaskInfo *taskInfo = NULL;
if (searchResultsList == NULL || *searchResultsList != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
/* Lookup Datastore and 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_True;
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_True;
vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
if (esxVI_IsoImageFileQuery_Alloc(&isoImageFileQuery) < 0 ||
esxVI_FileQuery_AppendToList
(&searchSpec->query,
esxVI_FileQuery_DynamicCast(isoImageFileQuery)) < 0) {
goto cleanup;
}
if (esxVI_FloppyImageFileQuery_Alloc(&floppyImageFileQuery) < 0 ||
esxVI_FileQuery_AppendToList
(&searchSpec->query,
esxVI_FileQuery_DynamicCast(floppyImageFileQuery)) < 0) {
goto cleanup;
}
/* Search datastore for files */
if (virAsprintf(&datastorePath, "[%s]", datastoreName) < 0) {
virReportOOMError();
goto cleanup;
}
if (esxVI_SearchDatastoreSubFolders_Task(ctx, hostDatastoreBrowser,
datastorePath, searchSpec,
&task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Occurrence_None,
esxVI_Boolean_False, &taskInfoState) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not serach in datastore '%s'"), datastoreName);
goto cleanup;
}
if (esxVI_LookupTaskInfoByTask(ctx, task, &taskInfo) < 0 ||
esxVI_HostDatastoreBrowserSearchResults_CastListFromAnyType
(taskInfo->result, searchResultsList) < 0) {
goto cleanup;
}
result = 0;
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore);
esxVI_ManagedObjectReference_Free(&hostDatastoreBrowser);
esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec);
VIR_FREE(datastorePath);
esxVI_ManagedObjectReference_Free(&task);
esxVI_TaskInfo_Free(&taskInfo);
return result;
}
int
esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,

View File

@ -399,6 +399,15 @@ int esxVI_LookupCurrentSnapshotTree
esxVI_VirtualMachineSnapshotTree **currentSnapshotTree,
esxVI_Occurrence occurrence);
int esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
const char *datastorePath,
esxVI_FileInfo **fileInfo,
esxVI_Occurrence occurrence);
int esxVI_LookupDatastoreContentByDatastoreName
(esxVI_Context *ctx, const char *datastoreName,
esxVI_HostDatastoreBrowserSearchResults **searchResultsList);
int esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,

View File

@ -813,6 +813,13 @@ method RevertToSnapshot_Task returns ManagedObjectReference r
end
method SearchDatastoreSubFolders_Task returns ManagedObjectReference r
ManagedObjectReference _this r
String datastorePath r
HostDatastoreBrowserSearchSpec searchSpec o
end
method SearchDatastore_Task returns ManagedObjectReference r
ManagedObjectReference _this r
String datastorePath r