mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
esx: Use the VirtualDisk UUID as storage volume key
VirtualDisks are .vmdk file based. Other files in a datastore like .iso or .flp files don't have a UUID attached, fall back to the path as key for them.
This commit is contained in:
parent
e5a3c0b35d
commit
635f01ae28
@ -697,7 +697,7 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
|
|||||||
virStorageVolPtr volume = NULL;
|
virStorageVolPtr volume = NULL;
|
||||||
esxPrivate *priv = pool->conn->storagePrivateData;
|
esxPrivate *priv = pool->conn->storagePrivateData;
|
||||||
char *datastorePath = NULL;
|
char *datastorePath = NULL;
|
||||||
esxVI_FileInfo *fileInfo = NULL;
|
char *key = NULL;
|
||||||
|
|
||||||
if (esxVI_EnsureSession(priv->primary) < 0) {
|
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -708,17 +708,16 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
|
if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary,
|
||||||
false, &fileInfo,
|
datastorePath, &key) < 0) {
|
||||||
esxVI_Occurrence_RequiredItem) < 0) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume = virGetStorageVol(pool->conn, pool->name, name, datastorePath);
|
volume = virGetStorageVol(pool->conn, pool->name, name, key);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(datastorePath);
|
VIR_FREE(datastorePath);
|
||||||
esxVI_FileInfo_Free(&fileInfo);
|
VIR_FREE(key);
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
@ -726,36 +725,170 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
|
|||||||
|
|
||||||
|
|
||||||
static virStorageVolPtr
|
static virStorageVolPtr
|
||||||
esxStorageVolumeLookupByKeyOrPath(virConnectPtr conn, const char *keyOrPath)
|
esxStorageVolumeLookupByPath(virConnectPtr conn, const char *path)
|
||||||
{
|
{
|
||||||
virStorageVolPtr volume = NULL;
|
virStorageVolPtr volume = NULL;
|
||||||
esxPrivate *priv = conn->storagePrivateData;
|
esxPrivate *priv = conn->storagePrivateData;
|
||||||
char *datastoreName = NULL;
|
char *datastoreName = NULL;
|
||||||
char *directoryAndFileName = NULL;
|
char *directoryAndFileName = NULL;
|
||||||
esxVI_FileInfo *fileInfo = NULL;
|
char *key = NULL;
|
||||||
|
|
||||||
if (esxVI_EnsureSession(priv->primary) < 0) {
|
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esxUtil_ParseDatastorePath(keyOrPath, &datastoreName, NULL,
|
if (esxUtil_ParseDatastorePath(path, &datastoreName, NULL,
|
||||||
&directoryAndFileName) < 0) {
|
&directoryAndFileName) < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath,
|
if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, path,
|
||||||
false, &fileInfo,
|
&key) < 0) {
|
||||||
esxVI_Occurrence_RequiredItem) < 0) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume = virGetStorageVol(conn, datastoreName, directoryAndFileName,
|
volume = virGetStorageVol(conn, datastoreName, directoryAndFileName, key);
|
||||||
keyOrPath);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(datastoreName);
|
VIR_FREE(datastoreName);
|
||||||
VIR_FREE(directoryAndFileName);
|
VIR_FREE(directoryAndFileName);
|
||||||
esxVI_FileInfo_Free(&fileInfo);
|
VIR_FREE(key);
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static virStorageVolPtr
|
||||||
|
esxStorageVolumeLookupByKey(virConnectPtr conn, const char *key)
|
||||||
|
{
|
||||||
|
virStorageVolPtr volume = NULL;
|
||||||
|
esxPrivate *priv = conn->storagePrivateData;
|
||||||
|
esxVI_String *propertyNameList = NULL;
|
||||||
|
esxVI_ObjectContent *datastoreList = NULL;
|
||||||
|
esxVI_ObjectContent *datastore = NULL;
|
||||||
|
char *datastoreName = NULL;
|
||||||
|
esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL;
|
||||||
|
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
|
||||||
|
char *directoryAndFileName = NULL;
|
||||||
|
size_t length;
|
||||||
|
char *datastorePath = NULL;
|
||||||
|
char *volumeName = NULL;
|
||||||
|
esxVI_FileInfo *fileInfo = NULL;
|
||||||
|
char *uuid_string = NULL;
|
||||||
|
char key_candidate[VIR_UUID_STRING_BUFLEN] = "";
|
||||||
|
|
||||||
|
if (STRPREFIX(key, "[")) {
|
||||||
|
/* Key is probably a datastore path */
|
||||||
|
return esxStorageVolumeLookupByPath(conn, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxVI_EnsureSession(priv->primary) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup all datastores */
|
||||||
|
if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 ||
|
||||||
|
esxVI_LookupDatastoreList(priv->primary, propertyNameList,
|
||||||
|
&datastoreList) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (datastore = datastoreList; datastore != NULL;
|
||||||
|
datastore = datastore->_next) {
|
||||||
|
datastoreName = NULL;
|
||||||
|
|
||||||
|
if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName,
|
||||||
|
esxVI_Occurrence_RequiredItem) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup datastore content */
|
||||||
|
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
|
||||||
|
|
||||||
|
if (esxVI_LookupDatastoreContentByDatastoreName
|
||||||
|
(priv->primary, datastoreName, &searchResultsList) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interpret search result */
|
||||||
|
for (searchResults = searchResultsList; searchResults != NULL;
|
||||||
|
searchResults = searchResults->_next) {
|
||||||
|
VIR_FREE(directoryAndFileName);
|
||||||
|
|
||||||
|
if (esxUtil_ParseDatastorePath(searchResults->folderPath, NULL,
|
||||||
|
NULL, &directoryAndFileName) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip trailing separators */
|
||||||
|
length = strlen(directoryAndFileName);
|
||||||
|
|
||||||
|
while (length > 0 && directoryAndFileName[length - 1] == '/') {
|
||||||
|
directoryAndFileName[length - 1] = '\0';
|
||||||
|
--length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build datastore path and query the UUID */
|
||||||
|
for (fileInfo = searchResults->file; fileInfo != NULL;
|
||||||
|
fileInfo = fileInfo->_next) {
|
||||||
|
VIR_FREE(datastorePath);
|
||||||
|
|
||||||
|
if (length < 1) {
|
||||||
|
if (virAsprintf(&volumeName, "%s",
|
||||||
|
fileInfo->path) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else if (virAsprintf(&volumeName, "%s/%s",
|
||||||
|
directoryAndFileName,
|
||||||
|
fileInfo->path) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
|
||||||
|
volumeName) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) == NULL) {
|
||||||
|
/* Only a VirtualDisk has a UUID */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(uuid_string);
|
||||||
|
|
||||||
|
if (esxVI_QueryVirtualDiskUuid
|
||||||
|
(priv->primary, datastorePath,
|
||||||
|
priv->primary->datacenter->_reference,
|
||||||
|
&uuid_string) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxUtil_ReformatUuid(uuid_string, key_candidate) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STREQ(key, key_candidate)) {
|
||||||
|
/* Found matching UUID */
|
||||||
|
volume = virGetStorageVol(conn, datastoreName,
|
||||||
|
volumeName, key);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
esxVI_String_Free(&propertyNameList);
|
||||||
|
esxVI_ObjectContent_Free(&datastoreList);
|
||||||
|
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
|
||||||
|
VIR_FREE(directoryAndFileName);
|
||||||
|
VIR_FREE(datastorePath);
|
||||||
|
VIR_FREE(volumeName);
|
||||||
|
VIR_FREE(uuid_string);
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
@ -782,6 +915,8 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
|
|||||||
esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL;
|
esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL;
|
||||||
esxVI_ManagedObjectReference *task = NULL;
|
esxVI_ManagedObjectReference *task = NULL;
|
||||||
esxVI_TaskInfoState taskInfoState;
|
esxVI_TaskInfoState taskInfoState;
|
||||||
|
char *uuid_string = NULL;
|
||||||
|
char key[VIR_UUID_STRING_BUFLEN] = "";
|
||||||
|
|
||||||
virCheckFlags(0, NULL);
|
virCheckFlags(0, NULL);
|
||||||
|
|
||||||
@ -932,6 +1067,16 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
|
|||||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create volume"));
|
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create volume"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath,
|
||||||
|
priv->primary->datacenter->_reference,
|
||||||
|
&uuid_string) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxUtil_ReformatUuid(uuid_string, key) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Creation of %s volumes is not supported"),
|
_("Creation of %s volumes is not supported"),
|
||||||
@ -939,7 +1084,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
volume = virGetStorageVol(pool->conn, pool->name, def->name, datastorePath);
|
volume = virGetStorageVol(pool->conn, pool->name, def->name, key);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (virtualDiskSpec != NULL) {
|
if (virtualDiskSpec != NULL) {
|
||||||
@ -957,6 +1102,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
|
|||||||
esxVI_FileInfo_Free(&fileInfo);
|
esxVI_FileInfo_Free(&fileInfo);
|
||||||
esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
|
esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
|
||||||
esxVI_ManagedObjectReference_Free(&task);
|
esxVI_ManagedObjectReference_Free(&task);
|
||||||
|
VIR_FREE(uuid_string);
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
@ -1087,7 +1233,12 @@ esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
|
|||||||
floppyImageFileInfo = esxVI_FloppyImageFileInfo_DynamicCast(fileInfo);
|
floppyImageFileInfo = esxVI_FloppyImageFileInfo_DynamicCast(fileInfo);
|
||||||
|
|
||||||
def.name = volume->name;
|
def.name = volume->name;
|
||||||
def.key = datastorePath;
|
|
||||||
|
if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, datastorePath,
|
||||||
|
&def.key) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
def.type = VIR_STORAGE_VOL_FILE;
|
def.type = VIR_STORAGE_VOL_FILE;
|
||||||
def.target.path = datastorePath;
|
def.target.path = datastorePath;
|
||||||
|
|
||||||
@ -1120,6 +1271,7 @@ esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
|
|||||||
esxVI_DatastoreInfo_Free(&datastoreInfo);
|
esxVI_DatastoreInfo_Free(&datastoreInfo);
|
||||||
VIR_FREE(datastorePath);
|
VIR_FREE(datastorePath);
|
||||||
esxVI_FileInfo_Free(&fileInfo);
|
esxVI_FileInfo_Free(&fileInfo);
|
||||||
|
VIR_FREE(def.key);
|
||||||
|
|
||||||
return xml;
|
return xml;
|
||||||
}
|
}
|
||||||
@ -1186,8 +1338,8 @@ static virStorageDriver esxStorageDriver = {
|
|||||||
esxStoragePoolNumberOfStorageVolumes, /* poolNumOfVolumes */
|
esxStoragePoolNumberOfStorageVolumes, /* poolNumOfVolumes */
|
||||||
esxStoragePoolListStorageVolumes, /* poolListVolumes */
|
esxStoragePoolListStorageVolumes, /* poolListVolumes */
|
||||||
esxStorageVolumeLookupByName, /* volLookupByName */
|
esxStorageVolumeLookupByName, /* volLookupByName */
|
||||||
esxStorageVolumeLookupByKeyOrPath, /* volLookupByKey */
|
esxStorageVolumeLookupByKey, /* volLookupByKey */
|
||||||
esxStorageVolumeLookupByKeyOrPath, /* volLookupByPath */
|
esxStorageVolumeLookupByPath, /* volLookupByPath */
|
||||||
esxStorageVolumeCreateXML, /* volCreateXML */
|
esxStorageVolumeCreateXML, /* volCreateXML */
|
||||||
NULL, /* volCreateXMLFrom */
|
NULL, /* volCreateXMLFrom */
|
||||||
NULL, /* volDelete */
|
NULL, /* volDelete */
|
||||||
|
@ -602,3 +602,22 @@ esxUtil_GetConfigBoolean(virConfPtr conf, const char *name, bool *boolean_,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
esxUtil_ReformatUuid(const char *input, char *output)
|
||||||
|
{
|
||||||
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||||
|
|
||||||
|
if (virUUIDParse(input, uuid) < 0) {
|
||||||
|
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Could not parse UUID from string '%s'"),
|
||||||
|
input);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virUUIDFormat(uuid, output);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -69,4 +69,6 @@ int esxUtil_GetConfigLong(virConfPtr conf, const char *name, long long *number,
|
|||||||
int esxUtil_GetConfigBoolean(virConfPtr conf, const char *name, bool *boolean_,
|
int esxUtil_GetConfigBoolean(virConfPtr conf, const char *name, bool *boolean_,
|
||||||
bool default_, bool optional);
|
bool default_, bool optional);
|
||||||
|
|
||||||
|
int esxUtil_ReformatUuid(const char *input, char *output);
|
||||||
|
|
||||||
#endif /* __ESX_UTIL_H__ */
|
#endif /* __ESX_UTIL_H__ */
|
||||||
|
@ -3253,6 +3253,59 @@ esxVI_LookupDatastoreContentByDatastoreName
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
|
||||||
|
const char *datastorePath,
|
||||||
|
char **key)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
esxVI_FileInfo *fileInfo = NULL;
|
||||||
|
char *uuid_string = NULL;
|
||||||
|
|
||||||
|
if (key == NULL || *key != NULL) {
|
||||||
|
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxVI_LookupFileInfoByDatastorePath(ctx, datastorePath, false, &fileInfo,
|
||||||
|
esxVI_Occurrence_RequiredItem) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) != NULL) {
|
||||||
|
/* VirtualDisks have a UUID, use it as key */
|
||||||
|
if (esxVI_QueryVirtualDiskUuid(ctx, datastorePath,
|
||||||
|
ctx->datacenter->_reference,
|
||||||
|
&uuid_string) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_ALLOC_N(*key, VIR_UUID_STRING_BUFLEN) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (esxUtil_ReformatUuid(uuid_string, *key) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Other files don't have a UUID, fall back to the path as key */
|
||||||
|
if (esxVI_String_DeepCopyValue(key, datastorePath) < 0) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
esxVI_FileInfo_Free(&fileInfo);
|
||||||
|
VIR_FREE(uuid_string);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
esxVI_HandleVirtualMachineQuestion
|
esxVI_HandleVirtualMachineQuestion
|
||||||
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
|
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
|
||||||
|
@ -409,6 +409,10 @@ int esxVI_LookupDatastoreContentByDatastoreName
|
|||||||
(esxVI_Context *ctx, const char *datastoreName,
|
(esxVI_Context *ctx, const char *datastoreName,
|
||||||
esxVI_HostDatastoreBrowserSearchResults **searchResultsList);
|
esxVI_HostDatastoreBrowserSearchResults **searchResultsList);
|
||||||
|
|
||||||
|
int esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
|
||||||
|
const char *datastorePath,
|
||||||
|
char **key);
|
||||||
|
|
||||||
int esxVI_HandleVirtualMachineQuestion
|
int esxVI_HandleVirtualMachineQuestion
|
||||||
(esxVI_Context *ctx,
|
(esxVI_Context *ctx,
|
||||||
esxVI_ManagedObjectReference *virtualMachine,
|
esxVI_ManagedObjectReference *virtualMachine,
|
||||||
|
@ -801,6 +801,13 @@ method QueryPerfCounter returns PerfCounterInfo ol
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
method QueryVirtualDiskUuid returns String r
|
||||||
|
ManagedObjectReference _this:VirtualDiskManager r
|
||||||
|
String name r
|
||||||
|
ManagedObjectReference datacenter o
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
method RebootGuest
|
method RebootGuest
|
||||||
ManagedObjectReference _this r
|
ManagedObjectReference _this r
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user