esx: Make storage pool lookup by name and UUID more robust

Don't rely on summary.url anymore, because its value is different
between an esx:// and vpx:// connection. Use host.mountInfo.path
instead.

Don't fallback to lookup by UUID (actually lookup by absolute path)
in esxVI_LookupDatastoreByName when lookup by name fails. Add a
seperate function for this: esxVI_LookupDatastoreByAbsolutePath
This commit is contained in:
Matthias Bolte 2010-08-01 19:53:00 +02:00
parent e4938ce2f1
commit 5254546bba
11 changed files with 237 additions and 212 deletions

View File

@ -2193,8 +2193,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
goto cleanup; goto cleanup;
} }
if (esxUtil_ParseDatastoreRelatedPath(vmPathName, &datastoreName, if (esxUtil_ParseDatastorePath(vmPathName, &datastoreName, &directoryName,
&directoryName, &fileName) < 0) { &fileName) < 0) {
goto cleanup; goto cleanup;
} }
@ -2572,8 +2572,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
goto cleanup; goto cleanup;
} }
if (esxUtil_ParseDatastoreRelatedPath(disk->src, &datastoreName, if (esxUtil_ParseDatastorePath(disk->src, &datastoreName, &directoryName,
&directoryName, &fileName) < 0) { &fileName) < 0) {
goto cleanup; goto cleanup;
} }

View File

@ -196,61 +196,64 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
esxPrivate *priv = conn->storagePrivateData; esxPrivate *priv = conn->storagePrivateData;
esxVI_String *propertyNameList = NULL; esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL; esxVI_ObjectContent *datastore = NULL;
esxVI_Boolean accessible = esxVI_Boolean_Undefined; esxVI_DynamicProperty *dynamicProperty = NULL;
char *summaryUrl = NULL; esxVI_DatastoreHostMount *datastoreHostMountList = NULL;
esxVI_DatastoreHostMount *datastoreHostMount = NULL;
char *suffix = NULL; char *suffix = NULL;
int suffixLength; int suffixLength;
char uuid_string[VIR_UUID_STRING_BUFLEN] = "00000000-00000000-0000-000000000000"; char uuid_string[VIR_UUID_STRING_BUFLEN] = "00000000-00000000-0000-000000000000";
unsigned char uuid[VIR_UUID_BUFLEN]; unsigned char uuid[VIR_UUID_BUFLEN];
char *realName = NULL;
virStoragePoolPtr pool = NULL; virStoragePoolPtr pool = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) { if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL; return NULL;
} }
if (esxVI_String_AppendValueListToList(&propertyNameList, if (esxVI_String_AppendValueToList(&propertyNameList, "host") < 0 ||
"summary.accessible\0"
"summary.name\0"
"summary.url\0") < 0 ||
esxVI_LookupDatastoreByName(priv->primary, name, esxVI_LookupDatastoreByName(priv->primary, name,
propertyNameList, &datastore, propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0 || esxVI_Occurrence_RequiredItem) < 0) {
esxVI_GetBoolean(datastore, "summary.accessible",
&accessible, esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup; goto cleanup;
} }
/* /*
* Datastores don't have a UUID. We can use the 'summary.url' property as * Datastores don't have a UUID. We can use the 'host.mountInfo.path'
* source for a "UUID" on ESX, because the property value has this format: * property as source for a "UUID" on ESX, because the property value has
* this format:
* *
* summary.url = /vmfs/volumes/4b0beca7-7fd401f3-1d7f-000ae484a6a3 * host.mountInfo.path = /vmfs/volumes/4b0beca7-7fd401f3-1d7f-000ae484a6a3
* summary.url = /vmfs/volumes/b24b7a78-9d82b4f5 (short format) * host.mountInfo.path = /vmfs/volumes/b24b7a78-9d82b4f5 (short format)
* *
* The 'summary.url' property comes in two forms, with a complete "UUID" * The 'host.mountInfo.path' property comes in two forms, with a complete
* and a short "UUID". * "UUID" and a short "UUID".
* *
* But this trailing "UUID" is not guaranteed to be there. On the other * But this trailing "UUID" is not guaranteed to be there. On the other
* hand we already rely on another implementation detail of the ESX server: * hand we already rely on another implementation detail of the ESX server:
* The object name of virtual machine contains an integer, we use that as * The object name of virtual machine contains an integer, we use that as
* domain ID. * domain ID.
*
* The 'summary.url' property of an inaccessible datastore is invalid.
*/ */
/* FIXME: Need to handle this for a vpx:// connection */ for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
if (accessible == esxVI_Boolean_True && priv->host != NULL && dynamicProperty = dynamicProperty->_next) {
priv->host->productVersion & esxVI_ProductVersion_ESX) { if (STREQ(dynamicProperty->name, "host")) {
if (esxVI_GetStringValue(datastore, "summary.url", &summaryUrl, if (esxVI_DatastoreHostMount_CastListFromAnyType
esxVI_Occurrence_RequiredItem) < 0) { (dynamicProperty->val, &datastoreHostMountList) < 0) {
goto cleanup; goto cleanup;
}
break;
}
}
for (datastoreHostMount = datastoreHostMountList; datastoreHostMount != NULL;
datastoreHostMount = datastoreHostMount->_next) {
if (STRNEQ(priv->primary->hostSystem->_reference->value,
datastoreHostMount->key->value)) {
continue;
} }
if ((suffix = STRSKIP(summaryUrl, "/vmfs/volumes/")) == NULL) { if ((suffix = STRSKIP(datastoreHostMount->mountInfo->path,
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "/vmfs/volumes/")) == NULL) {
_("Datastore URL '%s' has unexpected prefix, " break;
"expecting '/vmfs/volumes/' prefix"), summaryUrl);
goto cleanup;
} }
suffixLength = strlen(suffix); suffixLength = strlen(suffix);
@ -266,8 +269,8 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
*/ */
memcpy(uuid_string, suffix, suffixLength); memcpy(uuid_string, suffix, suffixLength);
} else { } else {
VIR_WARN("Datastore URL suffix '%s' has unexpected format, " VIR_WARN("Datastore host mount path suffix '%s' has unexpected "
"cannot deduce a UUID from it", suffix); "format, cannot deduce a UUID from it", suffix);
} }
} }
@ -278,16 +281,12 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
goto cleanup; goto cleanup;
} }
if (esxVI_GetStringValue(datastore, "summary.name", &realName, pool = virGetStoragePool(conn, name, uuid);
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
pool = virGetStoragePool(conn, realName, uuid);
cleanup: cleanup:
esxVI_String_Free(&propertyNameList); esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore); esxVI_ObjectContent_Free(&datastore);
esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
return pool; return pool;
} }
@ -301,6 +300,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
esxVI_String *propertyNameList = NULL; esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL; esxVI_ObjectContent *datastore = NULL;
char uuid_string[VIR_UUID_STRING_BUFLEN] = ""; char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
char *absolutePath = NULL;
char *name = NULL; char *name = NULL;
virStoragePoolPtr pool = NULL; virStoragePoolPtr pool = NULL;
@ -309,7 +309,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
} }
/* /*
* Convert from UUID to datastore URL form by stripping the second '-': * Convert UUID to 'host.mountInfo.path' form by stripping the second '-':
* *
* <---- 14 ----><-------- 22 --------> <---- 13 ---><-------- 22 --------> * <---- 14 ----><-------- 22 --------> <---- 13 ---><-------- 22 -------->
* 4b0beca7-7fd4-01f3-1d7f-000ae484a6a3 -> 4b0beca7-7fd401f3-1d7f-000ae484a6a3 * 4b0beca7-7fd4-01f3-1d7f-000ae484a6a3 -> 4b0beca7-7fd401f3-1d7f-000ae484a6a3
@ -317,14 +317,15 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
virUUIDFormat(uuid, uuid_string); virUUIDFormat(uuid, uuid_string);
memmove(uuid_string + 13, uuid_string + 14, 22 + 1); memmove(uuid_string + 13, uuid_string + 14, 22 + 1);
/* if (virAsprintf(&absolutePath, "/vmfs/volumes/%s", uuid_string) < 0) {
* Use esxVI_LookupDatastoreByName because it also does try to match "UUID" virReportOOMError();
* part of the 'summary.url' property if there is no name match. goto cleanup;
*/ }
if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 || if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 ||
esxVI_LookupDatastoreByName(priv->primary, uuid_string, esxVI_LookupDatastoreByAbsolutePath(priv->primary, absolutePath,
propertyNameList, &datastore, propertyNameList, &datastore,
esxVI_Occurrence_OptionalItem) < 0) { esxVI_Occurrence_OptionalItem) < 0) {
goto cleanup; goto cleanup;
} }
@ -338,9 +339,16 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
if (datastore == NULL && STREQ(uuid_string + 17, "-0000-000000000000")) { if (datastore == NULL && STREQ(uuid_string + 17, "-0000-000000000000")) {
uuid_string[17] = '\0'; uuid_string[17] = '\0';
if (esxVI_LookupDatastoreByName(priv->primary, uuid_string, VIR_FREE(absolutePath);
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0) { if (virAsprintf(&absolutePath, "/vmfs/volumes/%s", uuid_string) < 0) {
virReportOOMError();
goto cleanup;
}
if (esxVI_LookupDatastoreByAbsolutePath(priv->primary, absolutePath,
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup; goto cleanup;
} }
} }
@ -348,7 +356,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
if (datastore == NULL) { if (datastore == NULL) {
virUUIDFormat(uuid, uuid_string); virUUIDFormat(uuid, uuid_string);
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, ESX_VI_ERROR(VIR_ERR_NO_STORAGE_POOL,
_("Could not find datastore with UUID '%s'"), _("Could not find datastore with UUID '%s'"),
uuid_string); uuid_string);
@ -363,6 +371,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
pool = virGetStoragePool(conn, name, uuid); pool = virGetStoragePool(conn, name, uuid);
cleanup: cleanup:
VIR_FREE(absolutePath);
esxVI_String_Free(&propertyNameList); esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore); esxVI_ObjectContent_Free(&datastore);

View File

@ -274,12 +274,11 @@ esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id)
int int
esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath, esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
char **datastoreName, char **directoryName, char **fileName)
char **directoryName, char **fileName)
{ {
int result = -1; int result = -1;
char *copyOfDatastoreRelatedPath = NULL; char *copyOfDatastorePath = NULL;
char *tmp = NULL; char *tmp = NULL;
char *saveptr = NULL; char *saveptr = NULL;
char *preliminaryDatastoreName = NULL; char *preliminaryDatastoreName = NULL;
@ -293,18 +292,17 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
return -1; return -1;
} }
if (esxVI_String_DeepCopyValue(&copyOfDatastoreRelatedPath, if (esxVI_String_DeepCopyValue(&copyOfDatastorePath, datastorePath) < 0) {
datastoreRelatedPath) < 0) {
goto cleanup; goto cleanup;
} }
/* Expected format: '[<datastore>] <path>' */ /* Expected format: '[<datastore>] <path>' */
if ((tmp = STRSKIP(copyOfDatastoreRelatedPath, "[")) == NULL || if ((tmp = STRSKIP(copyOfDatastorePath, "[")) == NULL ||
(preliminaryDatastoreName = strtok_r(tmp, "]", &saveptr)) == NULL || (preliminaryDatastoreName = strtok_r(tmp, "]", &saveptr)) == NULL ||
(directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) { (directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't have expected format " _("Datastore path '%s' doesn't have expected format "
"'[<datastore>] <path>'"), datastoreRelatedPath); "'[<datastore>] <path>'"), datastorePath);
goto cleanup; goto cleanup;
} }
@ -323,8 +321,8 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
if (*separator == '\0') { if (*separator == '\0') {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore related path '%s' doesn't reference a file"), _("Datastore path '%s' doesn't reference a file"),
datastoreRelatedPath); datastorePath);
goto cleanup; goto cleanup;
} }
@ -348,7 +346,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
VIR_FREE(*fileName); VIR_FREE(*fileName);
} }
VIR_FREE(copyOfDatastoreRelatedPath); VIR_FREE(copyOfDatastorePath);
return result; return result;
} }

View File

@ -51,9 +51,8 @@ void esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri);
int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id); int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
int esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath, int esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
char **datastoreName, char **directoryName, char **fileName);
char **directoryName, char **fileName);
int esxUtil_ResolveHostname(const char *hostname, int esxUtil_ResolveHostname(const char *hostname,
char *ipAddress, size_t ipAddress_length); char *ipAddress, size_t ipAddress_length);

View File

@ -2422,10 +2422,7 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
esxVI_String *completePropertyNameList = NULL; esxVI_String *completePropertyNameList = NULL;
esxVI_ObjectContent *datastoreList = NULL; esxVI_ObjectContent *datastoreList = NULL;
esxVI_ObjectContent *candidate = NULL; esxVI_ObjectContent *candidate = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL; char *name_candidate;
esxVI_Boolean accessible = esxVI_Boolean_Undefined;
size_t offset = 14; /* = strlen("/vmfs/volumes/") */
int numInaccessibleDatastores = 0;
if (datastore == NULL || *datastore != NULL) { if (datastore == NULL || *datastore != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
@ -2435,118 +2432,36 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
/* Get all datastores */ /* Get all datastores */
if (esxVI_String_DeepCopyList(&completePropertyNameList, if (esxVI_String_DeepCopyList(&completePropertyNameList,
propertyNameList) < 0 || propertyNameList) < 0 ||
esxVI_String_AppendValueListToList(&completePropertyNameList, esxVI_String_AppendValueToList(&completePropertyNameList,
"summary.accessible\0" "summary.name") < 0 ||
"summary.name\0"
"summary.url\0") < 0 ||
esxVI_LookupDatastoreList(ctx, completePropertyNameList, esxVI_LookupDatastoreList(ctx, completePropertyNameList,
&datastoreList) < 0) { &datastoreList) < 0) {
goto cleanup; goto cleanup;
} }
if (datastoreList == NULL) {
if (occurrence == esxVI_Occurrence_OptionalItem) {
goto success;
} else {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("No datastores available"));
goto cleanup;
}
}
/* Search for a matching datastore */ /* Search for a matching datastore */
for (candidate = datastoreList; candidate != NULL; for (candidate = datastoreList; candidate != NULL;
candidate = candidate->_next) { candidate = candidate->_next) {
accessible = esxVI_Boolean_Undefined; name_candidate = NULL;
for (dynamicProperty = candidate->propSet; dynamicProperty != NULL; if (esxVI_GetStringValue(candidate, "summary.name", &name_candidate,
dynamicProperty = dynamicProperty->_next) { esxVI_Occurrence_RequiredItem) < 0) {
if (STREQ(dynamicProperty->name, "summary.accessible")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_Boolean) < 0) {
goto cleanup;
}
accessible = dynamicProperty->val->boolean;
break;
}
}
if (accessible == esxVI_Boolean_Undefined) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Got incomplete response while querying for the "
"datastore 'summary.accessible' property"));
goto cleanup; goto cleanup;
} }
if (accessible == esxVI_Boolean_False) { if (STREQ(name_candidate, name)) {
++numInaccessibleDatastores; if (esxVI_ObjectContent_DeepCopy(datastore, candidate) < 0) {
} goto cleanup;
for (dynamicProperty = candidate->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "summary.name")) {
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
goto cleanup;
}
if (STREQ(dynamicProperty->val->string, name)) {
if (esxVI_ObjectContent_DeepCopy(datastore,
candidate) < 0) {
goto cleanup;
}
/* Found datastore with matching name */
goto success;
}
} else if (STREQ(dynamicProperty->name, "summary.url") &&
ctx->productVersion & esxVI_ProductVersion_ESX) {
if (accessible == esxVI_Boolean_False) {
/*
* The 'summary.url' property of an inaccessible datastore
* is invalid and cannot be used to identify the datastore.
*/
continue;
}
if (esxVI_AnyType_ExpectType(dynamicProperty->val,
esxVI_Type_String) < 0) {
goto cleanup;
}
if (! STRPREFIX(dynamicProperty->val->string,
"/vmfs/volumes/")) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore URL '%s' has unexpected prefix, "
"expecting '/vmfs/volumes/' prefix"),
dynamicProperty->val->string);
goto cleanup;
}
if (STREQ(dynamicProperty->val->string + offset, name)) {
if (esxVI_ObjectContent_DeepCopy(datastore,
candidate) < 0) {
goto cleanup;
}
/* Found datastore with matching URL suffix */
goto success;
}
} }
// Found datastore with matching name
goto success;
} }
} }
if (occurrence != esxVI_Occurrence_OptionalItem) { if (*datastore == NULL && occurrence != esxVI_Occurrence_OptionalItem) {
if (numInaccessibleDatastores > 0) { ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not find datastore with name '%s'"), name);
_("Could not find datastore '%s', maybe it's "
"inaccessible"), name);
} else {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not find datastore '%s'"), name);
}
goto cleanup; goto cleanup;
} }
@ -2561,6 +2476,94 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
} }
int
esxVI_LookupDatastoreByAbsolutePath(esxVI_Context *ctx,
const char *absolutePath,
esxVI_String *propertyNameList,
esxVI_ObjectContent **datastore,
esxVI_Occurrence occurrence)
{
int result = -1;
esxVI_String *completePropertyNameList = NULL;
esxVI_ObjectContent *datastoreList = NULL;
esxVI_ObjectContent *candidate = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_DatastoreHostMount *datastoreHostMountList = NULL;
esxVI_DatastoreHostMount *datastoreHostMount = NULL;
if (datastore == NULL || *datastore != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
/* Get all datastores */
if (esxVI_String_DeepCopyList(&completePropertyNameList,
propertyNameList) < 0 ||
esxVI_String_AppendValueToList(&completePropertyNameList, "host") < 0 ||
esxVI_LookupDatastoreList(ctx, completePropertyNameList,
&datastoreList) < 0) {
goto cleanup;
}
/* Search for a matching datastore */
for (candidate = datastoreList; candidate != NULL;
candidate = candidate->_next) {
esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
for (dynamicProperty = candidate->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "host")) {
if (esxVI_DatastoreHostMount_CastListFromAnyType
(dynamicProperty->val, &datastoreHostMountList) < 0) {
goto cleanup;
}
break;
}
}
if (datastoreHostMountList == NULL) {
continue;
}
for (datastoreHostMount = datastoreHostMountList;
datastoreHostMount != NULL;
datastoreHostMount = datastoreHostMount->_next) {
if (STRNEQ(ctx->hostSystem->_reference->value,
datastoreHostMount->key->value)) {
continue;
}
if (STRPREFIX(absolutePath, datastoreHostMount->mountInfo->path)) {
if (esxVI_ObjectContent_DeepCopy(datastore, candidate) < 0) {
goto cleanup;
}
/* Found datastore with matching mount path */
goto success;
}
}
}
if (*datastore == NULL && occurrence != esxVI_Occurrence_OptionalItem) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not find datastore containing absolute path '%s'"),
absolutePath);
goto cleanup;
}
success:
result = 0;
cleanup:
esxVI_String_Free(&completePropertyNameList);
esxVI_ObjectContent_Free(&datastoreList);
esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
return result;
}
int int
esxVI_LookupTaskInfoByTask(esxVI_Context *ctx, esxVI_LookupTaskInfoByTask(esxVI_Context *ctx,

View File

@ -364,6 +364,12 @@ int esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
esxVI_ObjectContent **datastore, esxVI_ObjectContent **datastore,
esxVI_Occurrence occurrence); esxVI_Occurrence occurrence);
int esxVI_LookupDatastoreByAbsolutePath(esxVI_Context *ctx,
const char *absolutePath,
esxVI_String *propertyNameList,
esxVI_ObjectContent **datastore,
esxVI_Occurrence occurrence);
int esxVI_LookupTaskInfoByTask(esxVI_Context *ctx, int esxVI_LookupTaskInfoByTask(esxVI_Context *ctx,
esxVI_ManagedObjectReference *task, esxVI_ManagedObjectReference *task,
esxVI_TaskInfo **taskInfo); esxVI_TaskInfo **taskInfo);

View File

@ -146,6 +146,12 @@ object ChoiceOption extends OptionType
end end
object DatastoreHostMount
ManagedObjectReference key r
HostMountInfo mountInfo r
end
object DatastoreInfo object DatastoreInfo
String name r String name r
String url r String url r
@ -251,6 +257,13 @@ object HostFileSystemVolume
end end
object HostMountInfo
String path o
String accessMode r
Boolean accessible o
end
object HostNasVolume extends HostFileSystemVolume object HostNasVolume extends HostFileSystemVolume
String remoteHost r String remoteHost r
String remotePath r String remotePath r

View File

@ -1127,7 +1127,8 @@ additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE
"VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE } "VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE }
additional_object_features = { "DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST, additional_object_features = { "DatastoreHostMount" : Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE,
"DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST,
"Event" : Object.FEATURE__LIST, "Event" : Object.FEATURE__LIST,
"FileInfo" : Object.FEATURE__DYNAMIC_CAST, "FileInfo" : Object.FEATURE__DYNAMIC_CAST,
"FileQuery" : Object.FEATURE__DYNAMIC_CAST, "FileQuery" : Object.FEATURE__DYNAMIC_CAST,

View File

@ -749,8 +749,8 @@ esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
return 0; return 0;
} }
if (esxUtil_ParseDatastoreRelatedPath(def->src, &datastoreName, if (esxUtil_ParseDatastorePath(def->src, &datastoreName, &directoryName,
&directoryName, &fileName) < 0) { &fileName) < 0) {
goto cleanup; goto cleanup;
} }
@ -986,19 +986,19 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
char * char *
esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx, esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath)
const char *absolutePath)
{ {
bool success = false; bool success = false;
char *copyOfAbsolutePath = NULL; char *copyOfAbsolutePath = NULL;
char *tmp = NULL; char *tmp = NULL;
char *saveptr = NULL; char *saveptr = NULL;
char *datastoreRelatedPath = NULL; esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
char *datastorePath = NULL;
char *preliminaryDatastoreName = NULL; char *preliminaryDatastoreName = NULL;
char *directoryAndFileName = NULL; char *directoryAndFileName = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL; char *datastoreName = NULL;
esxVI_ObjectContent *datastore = NULL;
const char *datastoreName = NULL;
if (esxVI_String_DeepCopyValue(&copyOfAbsolutePath, absolutePath) < 0) { if (esxVI_String_DeepCopyValue(&copyOfAbsolutePath, absolutePath) < 0) {
return NULL; return NULL;
@ -1015,30 +1015,26 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
} }
if (ctx != NULL) { if (ctx != NULL) {
if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName, if (esxVI_String_AppendValueToList(&propertyNameList,
NULL, &datastore, "summary.name") < 0 ||
esxVI_Occurrence_OptionalItem) < 0) { esxVI_LookupDatastoreByAbsolutePath(ctx, absolutePath,
propertyNameList, &datastore,
esxVI_Occurrence_OptionalItem) < 0) {
goto cleanup; goto cleanup;
} }
if (datastore != NULL) { if (datastore == NULL) {
for (dynamicProperty = datastore->propSet; dynamicProperty != NULL; if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName,
dynamicProperty = dynamicProperty->_next) { propertyNameList, &datastore,
if (STREQ(dynamicProperty->name, "summary.accessible")) { esxVI_Occurrence_OptionalItem) < 0) {
/* Ignore it */ goto cleanup;
} else if (STREQ(dynamicProperty->name, "summary.name")) { }
if (esxVI_AnyType_ExpectType(dynamicProperty->val, }
esxVI_Type_String) < 0) {
goto cleanup;
}
datastoreName = dynamicProperty->val->string; if (datastore != NULL) {
break; if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName,
} else if (STREQ(dynamicProperty->name, "summary.url")) { esxVI_Occurrence_RequiredItem)) {
/* Ignore it */ goto cleanup;
} else {
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
}
} }
} }
@ -1053,7 +1049,7 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
datastoreName = preliminaryDatastoreName; datastoreName = preliminaryDatastoreName;
} }
if (virAsprintf(&datastoreRelatedPath, "[%s] %s", datastoreName, if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
directoryAndFileName) < 0) { directoryAndFileName) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
@ -1065,13 +1061,14 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
cleanup: cleanup:
if (! success) { if (! success) {
VIR_FREE(datastoreRelatedPath); VIR_FREE(datastorePath);
} }
VIR_FREE(copyOfAbsolutePath); VIR_FREE(copyOfAbsolutePath);
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore); esxVI_ObjectContent_Free(&datastore);
return datastoreRelatedPath; return datastorePath;
} }
@ -1088,7 +1085,7 @@ esxVMX_ParseFileName(esxVI_Context *ctx, const char *fileName,
if (STRPREFIX(fileName, "/vmfs/volumes/")) { if (STRPREFIX(fileName, "/vmfs/volumes/")) {
/* Found absolute path referencing a file inside a datastore */ /* Found absolute path referencing a file inside a datastore */
return esxVMX_AbsolutePathToDatastoreRelatedPath(ctx, fileName); return esxVMX_AbsolutePathToDatastorePath(ctx, fileName);
} else if (STRPREFIX(fileName, "/")) { } else if (STRPREFIX(fileName, "/")) {
/* Found absolute path referencing a file outside a datastore */ /* Found absolute path referencing a file outside a datastore */
src = strdup(fileName); src = strdup(fileName);
@ -2625,8 +2622,8 @@ esxVMX_FormatFileName(esxVI_Context *ctx ATTRIBUTE_UNUSED, const char *src)
if (STRPREFIX(src, "[")) { if (STRPREFIX(src, "[")) {
/* Found potential datastore related path */ /* Found potential datastore related path */
if (esxUtil_ParseDatastoreRelatedPath(src, &datastoreName, if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
&directoryName, &fileName) < 0) { &fileName) < 0) {
goto cleanup; goto cleanup;
} }

View File

@ -56,8 +56,7 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
int virtualDev[4], bool present[4]); int virtualDev[4], bool present[4]);
char * char *
esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx, esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath);
const char *absolutePath);

View File

@ -95,7 +95,7 @@ testDiskNameToIndex(const void *data ATTRIBUTE_UNUSED)
struct testPath { struct testPath {
const char *datastoreRelatedPath; const char *datastorePath;
int result; int result;
const char *datastoreName; const char *datastoreName;
const char *directoryName; const char *directoryName;
@ -111,7 +111,7 @@ static struct testPath paths[] = {
}; };
static int static int
testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED) testParseDatastorePath(const void *data ATTRIBUTE_UNUSED)
{ {
int i, result = 0; int i, result = 0;
char *datastoreName = NULL; char *datastoreName = NULL;
@ -123,9 +123,9 @@ testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED)
VIR_FREE(directoryName); VIR_FREE(directoryName);
VIR_FREE(fileName); VIR_FREE(fileName);
if (esxUtil_ParseDatastoreRelatedPath(paths[i].datastoreRelatedPath, if (esxUtil_ParseDatastorePath(paths[i].datastorePath,
&datastoreName, &directoryName, &datastoreName, &directoryName,
&fileName) != paths[i].result) { &fileName) != paths[i].result) {
goto failure; goto failure;
} }
@ -242,7 +242,7 @@ mymain(int argc, char **argv)
virSetErrorFunc(NULL, testQuietError); virSetErrorFunc(NULL, testQuietError);
# define DO_TEST(_name) \ # define DO_TEST(_name) \
do { \ do { \
if (virtTestRun("VMware "#_name, 1, test##_name, \ if (virtTestRun("VMware "#_name, 1, test##_name, \
NULL) < 0) { \ NULL) < 0) { \
@ -252,7 +252,7 @@ mymain(int argc, char **argv)
DO_TEST(IndexToDiskName); DO_TEST(IndexToDiskName);
DO_TEST(DiskNameToIndex); DO_TEST(DiskNameToIndex);
DO_TEST(ParseDatastoreRelatedPath); DO_TEST(ParseDatastorePath);
DO_TEST(ConvertDateTimeToCalendarTime); DO_TEST(ConvertDateTimeToCalendarTime);
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE; return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;