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
---
src/esx/esx_driver.c | 8 +-
src/esx/esx_storage_driver.c | 107 ++++++++++++++------------
src/esx/esx_util.c | 22 +++---
src/esx/esx_util.h | 5 +-
src/esx/esx_vi.c | 171 ++++++++++++++++++++--------------------
src/esx/esx_vi.h | 6 ++
src/esx/esx_vi_generator.input | 13 +++
src/esx/esx_vi_generator.py | 3 +-
src/esx/esx_vmx.c | 65 +++++++--------
src/esx/esx_vmx.h | 3 +-
tests/esxutilstest.c | 14 ++--
11 files changed, 221 insertions(+), 196 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index fd87078..d824371 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2193,8 +2193,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
goto cleanup;
}
- if (esxUtil_ParseDatastoreRelatedPath(vmPathName, &datastoreName,
- &directoryName, &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(vmPathName, &datastoreName, &directoryName,
+ &fileName) < 0) {
goto cleanup;
}
@@ -2572,8 +2572,8 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml
ATTRIBUTE_UNUSED)
goto cleanup;
}
- if (esxUtil_ParseDatastoreRelatedPath(disk->src, &datastoreName,
- &directoryName, &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(disk->src, &datastoreName, &directoryName,
+ &fileName) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index b0ccc32..e0680a1 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -196,61 +196,64 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
esxPrivate *priv = conn->storagePrivateData;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
- esxVI_Boolean accessible = esxVI_Boolean_Undefined;
- char *summaryUrl = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_DatastoreHostMount *datastoreHostMountList = NULL;
+ esxVI_DatastoreHostMount *datastoreHostMount = NULL;
char *suffix = NULL;
int suffixLength;
char uuid_string[VIR_UUID_STRING_BUFLEN] =
"00000000-00000000-0000-000000000000";
unsigned char uuid[VIR_UUID_BUFLEN];
- char *realName = NULL;
virStoragePoolPtr pool = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxVI_String_AppendValueListToList(&propertyNameList,
- "summary.accessible\0"
- "summary.name\0"
- "summary.url\0") < 0 ||
+ if (esxVI_String_AppendValueToList(&propertyNameList, "host") < 0
||
esxVI_LookupDatastoreByName(priv->primary, name,
propertyNameList, &datastore,
- esxVI_Occurrence_RequiredItem) < 0 ||
- esxVI_GetBoolean(datastore, "summary.accessible",
- &accessible, esxVI_Occurrence_RequiredItem) < 0) {
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
/*
- * Datastores don't have a UUID. We can use the 'summary.url' property
as
- * source for a "UUID" on ESX, because the property value has this format:
+ * Datastores don't have a UUID. We can use the 'host.mountInfo.path'
+ * property as source for a "UUID" on ESX, because the property value has
+ * this format:
*
- * summary.url = /vmfs/volumes/4b0beca7-7fd401f3-1d7f-000ae484a6a3
- * summary.url = /vmfs/volumes/b24b7a78-9d82b4f5 (short format)
+ * host.mountInfo.path = /vmfs/volumes/4b0beca7-7fd401f3-1d7f-000ae484a6a3
+ * host.mountInfo.path = /vmfs/volumes/b24b7a78-9d82b4f5 (short format)
*
- * The 'summary.url' property comes in two forms, with a complete
"UUID"
- * and a short "UUID".
+ * The 'host.mountInfo.path' property comes in two forms, with a complete
+ * "UUID" and a short "UUID".
*
* 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:
* The object name of virtual machine contains an integer, we use that as
* domain ID.
- *
- * The 'summary.url' property of an inaccessible datastore is invalid.
*/
- /* FIXME: Need to handle this for a vpx:// connection */
- if (accessible == esxVI_Boolean_True && priv->host != NULL &&
- priv->host->productVersion & esxVI_ProductVersion_ESX) {
- if (esxVI_GetStringValue(datastore, "summary.url", &summaryUrl,
- esxVI_Occurrence_RequiredItem) < 0) {
- goto cleanup;
+ for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "host")) {
+ if (esxVI_DatastoreHostMount_CastListFromAnyType
+ (dynamicProperty->val, &datastoreHostMountList) < 0) {
+ goto cleanup;
+ }
+
+ break;
}
+ }
- if ((suffix = STRSKIP(summaryUrl, "/vmfs/volumes/")) == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Datastore URL '%s' has unexpected prefix,
"
- "expecting '/vmfs/volumes/' prefix"),
summaryUrl);
- goto cleanup;
+ for (datastoreHostMount = datastoreHostMountList; datastoreHostMount != NULL;
+ datastoreHostMount = datastoreHostMount->_next) {
+ if (STRNEQ(priv->primary->hostSystem->_reference->value,
+ datastoreHostMount->key->value)) {
+ continue;
+ }
+
+ if ((suffix = STRSKIP(datastoreHostMount->mountInfo->path,
+ "/vmfs/volumes/")) == NULL) {
+ break;
}
suffixLength = strlen(suffix);
@@ -266,8 +269,8 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
*/
memcpy(uuid_string, suffix, suffixLength);
} else {
- VIR_WARN("Datastore URL suffix '%s' has unexpected format,
"
- "cannot deduce a UUID from it", suffix);
+ VIR_WARN("Datastore host mount path suffix '%s' has unexpected
"
+ "format, cannot deduce a UUID from it", suffix);
}
}
@@ -278,16 +281,12 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
goto cleanup;
}
- if (esxVI_GetStringValue(datastore, "summary.name", &realName,
- esxVI_Occurrence_RequiredItem) < 0) {
- goto cleanup;
- }
-
- pool = virGetStoragePool(conn, realName, uuid);
+ pool = virGetStoragePool(conn, name, uuid);
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore);
+ esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
return pool;
}
@@ -301,6 +300,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
char uuid_string[VIR_UUID_STRING_BUFLEN] = "";
+ char *absolutePath = NULL;
char *name = 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 -------->
* 4b0beca7-7fd4-01f3-1d7f-000ae484a6a3 -> 4b0beca7-7fd401f3-1d7f-000ae484a6a3
@@ -317,14 +317,15 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
virUUIDFormat(uuid, uuid_string);
memmove(uuid_string + 13, uuid_string + 14, 22 + 1);
- /*
- * Use esxVI_LookupDatastoreByName because it also does try to match
"UUID"
- * part of the 'summary.url' property if there is no name match.
- */
+ if (virAsprintf(&absolutePath, "/vmfs/volumes/%s", uuid_string) < 0)
{
+ virReportOOMError();
+ goto cleanup;
+ }
+
if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name")
< 0 ||
- esxVI_LookupDatastoreByName(priv->primary, uuid_string,
- propertyNameList, &datastore,
- esxVI_Occurrence_OptionalItem) < 0) {
+ esxVI_LookupDatastoreByAbsolutePath(priv->primary, absolutePath,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_OptionalItem) < 0) {
goto cleanup;
}
@@ -338,9 +339,16 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
if (datastore == NULL && STREQ(uuid_string + 17,
"-0000-000000000000")) {
uuid_string[17] = '\0';
- if (esxVI_LookupDatastoreByName(priv->primary, uuid_string,
- propertyNameList, &datastore,
- esxVI_Occurrence_RequiredItem) < 0) {
+ VIR_FREE(absolutePath);
+
+ 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;
}
}
@@ -348,7 +356,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
if (datastore == NULL) {
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'"),
uuid_string);
@@ -363,6 +371,7 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char
*uuid)
pool = virGetStoragePool(conn, name, uuid);
cleanup:
+ VIR_FREE(absolutePath);
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&datastore);
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 75a9aaf..7c7c841 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -274,12 +274,11 @@ esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id)
int
-esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
- char **datastoreName,
- char **directoryName, char **fileName)
+esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
+ char **directoryName, char **fileName)
{
int result = -1;
- char *copyOfDatastoreRelatedPath = NULL;
+ char *copyOfDatastorePath = NULL;
char *tmp = NULL;
char *saveptr = NULL;
char *preliminaryDatastoreName = NULL;
@@ -293,18 +292,17 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
return -1;
}
- if (esxVI_String_DeepCopyValue(©OfDatastoreRelatedPath,
- datastoreRelatedPath) < 0) {
+ if (esxVI_String_DeepCopyValue(©OfDatastorePath, datastorePath) < 0) {
goto cleanup;
}
/* Expected format: '[<datastore>] <path>' */
- if ((tmp = STRSKIP(copyOfDatastoreRelatedPath, "[")) == NULL ||
+ if ((tmp = STRSKIP(copyOfDatastorePath, "[")) == NULL ||
(preliminaryDatastoreName = strtok_r(tmp, "]", &saveptr)) == NULL
||
(directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Datastore related path '%s' doesn't have expected
format "
- "'[<datastore>] <path>'"),
datastoreRelatedPath);
+ _("Datastore path '%s' doesn't have expected format
"
+ "'[<datastore>] <path>'"),
datastorePath);
goto cleanup;
}
@@ -323,8 +321,8 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
if (*separator == '\0') {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Datastore related path '%s' doesn't reference a
file"),
- datastoreRelatedPath);
+ _("Datastore path '%s' doesn't reference a
file"),
+ datastorePath);
goto cleanup;
}
@@ -348,7 +346,7 @@ esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
VIR_FREE(*fileName);
}
- VIR_FREE(copyOfDatastoreRelatedPath);
+ VIR_FREE(copyOfDatastorePath);
return result;
}
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 99ce81d..5799730 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -51,9 +51,8 @@ void esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri);
int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
-int esxUtil_ParseDatastoreRelatedPath(const char *datastoreRelatedPath,
- char **datastoreName,
- char **directoryName, char **fileName);
+int esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
+ char **directoryName, char **fileName);
int esxUtil_ResolveHostname(const char *hostname,
char *ipAddress, size_t ipAddress_length);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 9f2ac36..f421502 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -2422,10 +2422,7 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
esxVI_String *completePropertyNameList = NULL;
esxVI_ObjectContent *datastoreList = NULL;
esxVI_ObjectContent *candidate = NULL;
- esxVI_DynamicProperty *dynamicProperty = NULL;
- esxVI_Boolean accessible = esxVI_Boolean_Undefined;
- size_t offset = 14; /* = strlen("/vmfs/volumes/") */
- int numInaccessibleDatastores = 0;
+ char *name_candidate;
if (datastore == NULL || *datastore != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
@@ -2435,118 +2432,123 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char
*name,
/* Get all datastores */
if (esxVI_String_DeepCopyList(&completePropertyNameList,
propertyNameList) < 0 ||
- esxVI_String_AppendValueListToList(&completePropertyNameList,
- "summary.accessible\0"
- "summary.name\0"
- "summary.url\0") < 0 ||
+ esxVI_String_AppendValueToList(&completePropertyNameList,
+ "summary.name") < 0 ||
esxVI_LookupDatastoreList(ctx, completePropertyNameList,
&datastoreList) < 0) {
goto cleanup;
}
- if (datastoreList == NULL) {
- if (occurrence == esxVI_Occurrence_OptionalItem) {
- goto success;
- } else {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("No datastores available"));
+ /* Search for a matching datastore */
+ for (candidate = datastoreList; candidate != NULL;
+ candidate = candidate->_next) {
+ name_candidate = NULL;
+
+ if (esxVI_GetStringValue(candidate, "summary.name",
&name_candidate,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
+
+ if (STREQ(name_candidate, name)) {
+ if (esxVI_ObjectContent_DeepCopy(datastore, candidate) < 0) {
+ goto cleanup;
+ }
+
+ // Found datastore with matching name
+ goto success;
+ }
+ }
+
+ if (*datastore == NULL && occurrence != esxVI_Occurrence_OptionalItem) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find datastore with name '%s'"),
name);
+ goto cleanup;
+ }
+
+ success:
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&completePropertyNameList);
+ esxVI_ObjectContent_Free(&datastoreList);
+
+ return result;
+}
+
+
+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) {
- accessible = esxVI_Boolean_Undefined;
+ esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
for (dynamicProperty = candidate->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "summary.accessible")) {
- if (esxVI_AnyType_ExpectType(dynamicProperty->val,
- esxVI_Type_Boolean) < 0) {
+ if (STREQ(dynamicProperty->name, "host")) {
+ if (esxVI_DatastoreHostMount_CastListFromAnyType
+ (dynamicProperty->val, &datastoreHostMountList) < 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;
- }
-
- if (accessible == esxVI_Boolean_False) {
- ++numInaccessibleDatastores;
+ if (datastoreHostMountList == NULL) {
+ continue;
}
- 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;
- }
+ for (datastoreHostMount = datastoreHostMountList;
+ datastoreHostMount != NULL;
+ datastoreHostMount = datastoreHostMount->_next) {
+ if (STRNEQ(ctx->hostSystem->_reference->value,
+ datastoreHostMount->key->value)) {
+ continue;
+ }
- if (esxVI_AnyType_ExpectType(dynamicProperty->val,
- esxVI_Type_String) < 0) {
+ if (STRPREFIX(absolutePath, datastoreHostMount->mountInfo->path)) {
+ if (esxVI_ObjectContent_DeepCopy(datastore, candidate) < 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 mount path */
+ goto success;
}
}
}
- if (occurrence != esxVI_Occurrence_OptionalItem) {
- if (numInaccessibleDatastores > 0) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Could not find datastore '%s', maybe it's
"
- "inaccessible"), name);
- } else {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Could not find datastore '%s'"), name);
- }
-
+ 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;
}
@@ -2556,6 +2558,7 @@ esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char *name,
cleanup:
esxVI_String_Free(&completePropertyNameList);
esxVI_ObjectContent_Free(&datastoreList);
+ esxVI_DatastoreHostMount_Free(&datastoreHostMountList);
return result;
}
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index a23c56d..fdd15f1 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -364,6 +364,12 @@ int esxVI_LookupDatastoreByName(esxVI_Context *ctx, const char
*name,
esxVI_ObjectContent **datastore,
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,
esxVI_ManagedObjectReference *task,
esxVI_TaskInfo **taskInfo);
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index b4b33f6..ab50ea5 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -146,6 +146,12 @@ object ChoiceOption extends OptionType
end
+object DatastoreHostMount
+ ManagedObjectReference key r
+ HostMountInfo mountInfo r
+end
+
+
object DatastoreInfo
String name r
String url r
@@ -251,6 +257,13 @@ object HostFileSystemVolume
end
+object HostMountInfo
+ String path o
+ String accessMode r
+ Boolean accessible o
+end
+
+
object HostNasVolume extends HostFileSystemVolume
String remoteHost r
String remotePath r
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 44c3493..e3c3d14 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -1127,7 +1127,8 @@ additional_enum_features = { "ManagedEntityStatus" :
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,
"FileInfo" :
Object.FEATURE__DYNAMIC_CAST,
"FileQuery" :
Object.FEATURE__DYNAMIC_CAST,
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
index 807c6db..1a5e8d3 100644
--- a/src/esx/esx_vmx.c
+++ b/src/esx/esx_vmx.c
@@ -749,8 +749,8 @@ esxVMX_AutodetectSCSIControllerModel(esxVI_Context *ctx,
return 0;
}
- if (esxUtil_ParseDatastoreRelatedPath(def->src, &datastoreName,
- &directoryName, &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(def->src, &datastoreName, &directoryName,
+ &fileName) < 0) {
goto cleanup;
}
@@ -986,19 +986,19 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr
def,
char *
-esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
- const char *absolutePath)
+esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath)
{
bool success = false;
char *copyOfAbsolutePath = NULL;
char *tmp = NULL;
char *saveptr = NULL;
- char *datastoreRelatedPath = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+
+ char *datastorePath = NULL;
char *preliminaryDatastoreName = NULL;
char *directoryAndFileName = NULL;
- esxVI_DynamicProperty *dynamicProperty = NULL;
- esxVI_ObjectContent *datastore = NULL;
- const char *datastoreName = NULL;
+ char *datastoreName = NULL;
if (esxVI_String_DeepCopyValue(©OfAbsolutePath, absolutePath) < 0) {
return NULL;
@@ -1015,30 +1015,26 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
}
if (ctx != NULL) {
- if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName,
- NULL, &datastore,
- esxVI_Occurrence_OptionalItem) < 0) {
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "summary.name") < 0 ||
+ esxVI_LookupDatastoreByAbsolutePath(ctx, absolutePath,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_OptionalItem) < 0) {
goto cleanup;
}
- if (datastore != NULL) {
- for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
- dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "summary.accessible")) {
- /* Ignore it */
- } else if (STREQ(dynamicProperty->name, "summary.name")) {
- if (esxVI_AnyType_ExpectType(dynamicProperty->val,
- esxVI_Type_String) < 0) {
- goto cleanup;
- }
+ if (datastore == NULL) {
+ if (esxVI_LookupDatastoreByName(ctx, preliminaryDatastoreName,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+ }
- datastoreName = dynamicProperty->val->string;
- break;
- } else if (STREQ(dynamicProperty->name, "summary.url")) {
- /* Ignore it */
- } else {
- VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
- }
+ if (datastore != NULL) {
+ if (esxVI_GetStringValue(datastore, "summary.name",
&datastoreName,
+ esxVI_Occurrence_RequiredItem)) {
+ goto cleanup;
}
}
@@ -1053,7 +1049,7 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
datastoreName = preliminaryDatastoreName;
}
- if (virAsprintf(&datastoreRelatedPath, "[%s] %s", datastoreName,
+ if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
directoryAndFileName) < 0) {
virReportOOMError();
goto cleanup;
@@ -1065,13 +1061,14 @@ esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
cleanup:
if (! success) {
- VIR_FREE(datastoreRelatedPath);
+ VIR_FREE(datastorePath);
}
VIR_FREE(copyOfAbsolutePath);
+ esxVI_String_Free(&propertyNameList);
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/")) {
/* Found absolute path referencing a file inside a datastore */
- return esxVMX_AbsolutePathToDatastoreRelatedPath(ctx, fileName);
+ return esxVMX_AbsolutePathToDatastorePath(ctx, fileName);
} else if (STRPREFIX(fileName, "/")) {
/* Found absolute path referencing a file outside a datastore */
src = strdup(fileName);
@@ -2625,8 +2622,8 @@ esxVMX_FormatFileName(esxVI_Context *ctx ATTRIBUTE_UNUSED, const
char *src)
if (STRPREFIX(src, "[")) {
/* Found potential datastore related path */
- if (esxUtil_ParseDatastoreRelatedPath(src, &datastoreName,
- &directoryName, &fileName) < 0)
{
+ if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
+ &fileName) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_vmx.h b/src/esx/esx_vmx.h
index 3ccae7a..bda98f0 100644
--- a/src/esx/esx_vmx.h
+++ b/src/esx/esx_vmx.h
@@ -56,8 +56,7 @@ esxVMX_GatherSCSIControllers(esxVI_Context *ctx, virDomainDefPtr def,
int virtualDev[4], bool present[4]);
char *
-esxVMX_AbsolutePathToDatastoreRelatedPath(esxVI_Context *ctx,
- const char *absolutePath);
+esxVMX_AbsolutePathToDatastorePath(esxVI_Context *ctx, const char *absolutePath);
diff --git a/tests/esxutilstest.c b/tests/esxutilstest.c
index 2a13282..09470ed 100644
--- a/tests/esxutilstest.c
+++ b/tests/esxutilstest.c
@@ -95,7 +95,7 @@ testDiskNameToIndex(const void *data ATTRIBUTE_UNUSED)
struct testPath {
- const char *datastoreRelatedPath;
+ const char *datastorePath;
int result;
const char *datastoreName;
const char *directoryName;
@@ -111,7 +111,7 @@ static struct testPath paths[] = {
};
static int
-testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED)
+testParseDatastorePath(const void *data ATTRIBUTE_UNUSED)
{
int i, result = 0;
char *datastoreName = NULL;
@@ -123,9 +123,9 @@ testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED)
VIR_FREE(directoryName);
VIR_FREE(fileName);
- if (esxUtil_ParseDatastoreRelatedPath(paths[i].datastoreRelatedPath,
- &datastoreName, &directoryName,
- &fileName) != paths[i].result) {
+ if (esxUtil_ParseDatastorePath(paths[i].datastorePath,
+ &datastoreName, &directoryName,
+ &fileName) != paths[i].result) {
goto failure;
}
@@ -242,7 +242,7 @@ mymain(int argc, char **argv)
virSetErrorFunc(NULL, testQuietError);
-# define DO_TEST(_name) \
+# define DO_TEST(_name) \
do { \
if (virtTestRun("VMware "#_name, 1, test##_name,
\
NULL) < 0) { \
@@ -252,7 +252,7 @@ mymain(int argc, char **argv)
DO_TEST(IndexToDiskName);
DO_TEST(DiskNameToIndex);
- DO_TEST(ParseDatastoreRelatedPath);
+ DO_TEST(ParseDatastorePath);
DO_TEST(ConvertDateTimeToCalendarTime);
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
--
1.7.0.4