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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list