struct _esxVMX_Data {
esxVI_Context *ctx;
- const char *datastoreName;
- const char *directoryName;
+ char *datastorePathWithoutFileName;
};
if (strchr(fileName, '/') == NULL && strchr(fileName, '\\') == NULL) {
/* Plain file name, use same directory as for the .vmx file */
- if (virAsprintf(&datastorePath, "[%s] %s/%s", data->datastoreName,
- data->directoryName, fileName) < 0) {
+ if (virAsprintf(&datastorePath, "%s/%s",
+ data->datastorePathWithoutFileName, fileName) < 0) {
virReportOOMError();
goto cleanup;
}
bool success = false;
esxVMX_Data *data = opaque;
char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
+ char *directoryAndFileName = NULL;
esxVI_ObjectContent *datastore = NULL;
esxVI_DatastoreHostMount *hostMount = NULL;
char separator = '/';
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *tmp;
- int length;
+ size_t length;
char *absolutePath = NULL;
/* Parse datastore path and lookup datastore */
- if (esxUtil_ParseDatastorePath(datastorePath, &datastoreName,
- &directoryName, &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(datastorePath, &datastoreName, NULL,
+ &directoryAndFileName) < 0) {
goto cleanup;
}
- if (esxVI_LookupDatastoreByName(data->ctx, datastoreName,
- NULL, &datastore,
+ if (esxVI_LookupDatastoreByName(data->ctx, datastoreName, NULL, &datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_LookupDatastoreHostMount(data->ctx, datastore->obj,
&hostMount) < 0) {
--length;
}
- /* Format as <mount>[/<directory>]/<file> */
+ /* Format as <mount>[/<directory>]/<file>, convert / to \ when necessary */
virBufferAdd(&buffer, hostMount->mountInfo->path, length);
- if (directoryName != NULL) {
- /* Convert / to \ when necessary */
- if (separator != '/') {
- tmp = directoryName;
-
- while (*tmp != '\0') {
- if (*tmp == '/') {
- *tmp = separator;
- }
+ if (separator != '/') {
+ tmp = directoryAndFileName;
- ++tmp;
+ while (*tmp != '\0') {
+ if (*tmp == '/') {
+ *tmp = separator;
}
- }
- virBufferAddChar(&buffer, separator);
- virBufferAdd(&buffer, directoryName, -1);
+ ++tmp;
+ }
}
virBufferAddChar(&buffer, separator);
- virBufferAdd(&buffer, fileName, -1);
+ virBufferAdd(&buffer, directoryAndFileName, -1);
if (virBufferError(&buffer)) {
virReportOOMError();
}
VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
+ VIR_FREE(directoryAndFileName);
esxVI_ObjectContent_Free(&datastore);
esxVI_DatastoreHostMount_Free(&hostMount);
char *vmPathName = NULL;
char *datastoreName = NULL;
char *directoryName = NULL;
- char *fileName = NULL;
+ char *directoryAndFileName = NULL;
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *url = NULL;
char *vmx = NULL;
}
if (esxUtil_ParseDatastorePath(vmPathName, &datastoreName, &directoryName,
- &fileName) < 0) {
+ &directoryAndFileName) < 0) {
goto cleanup;
}
virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
domain->conn->uri->server, domain->conn->uri->port);
-
- if (directoryName != NULL) {
- virBufferURIEncodeString(&buffer, directoryName);
- virBufferAddChar(&buffer, '/');
- }
-
- virBufferURIEncodeString(&buffer, fileName);
+ virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
virBufferURIEncodeString(&buffer, priv->primary->datacenter->name);
virBufferAddLit(&buffer, "&dsName=");
}
data.ctx = priv->primary;
- data.datastoreName = datastoreName;
- data.directoryName = directoryName;
+
+ if (directoryName == NULL) {
+ if (virAsprintf(&data.datastorePathWithoutFileName, "[%s]",
+ datastoreName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ if (virAsprintf(&data.datastorePathWithoutFileName, "[%s] %s",
+ datastoreName, directoryName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
ctx.opaque = &data;
ctx.parseFileName = esxParseVMXFileName;
esxVI_ObjectContent_Free(&virtualMachine);
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
- VIR_FREE(fileName);
+ VIR_FREE(directoryAndFileName);
VIR_FREE(url);
+ VIR_FREE(data.datastorePathWithoutFileName);
VIR_FREE(vmx);
virDomainDefFree(def);
}
data.ctx = priv->primary;
- data.datastoreName = "?";
- data.directoryName = "?";
+ data.datastorePathWithoutFileName = (char *)"[?] ?";
ctx.opaque = &data;
ctx.parseFileName = esxParseVMXFileName;
}
data.ctx = priv->primary;
- data.datastoreName = NULL;
- data.directoryName = NULL;
+ data.datastorePathWithoutFileName = NULL;
ctx.opaque = &data;
ctx.parseFileName = NULL;
esxVMX_Data data;
char *datastoreName = NULL;
char *directoryName = NULL;
- char *fileName = NULL;
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *url = NULL;
char *datastoreRelatedPath = NULL;
/* Build VMX from domain XML */
data.ctx = priv->primary;
- data.datastoreName = NULL;
- data.directoryName = NULL;
+ data.datastorePathWithoutFileName = NULL;
ctx.opaque = &data;
ctx.parseFileName = NULL;
}
if (esxUtil_ParseDatastorePath(disk->src, &datastoreName, &directoryName,
- &fileName) < 0) {
+ NULL) < 0) {
goto cleanup;
}
- if (! virFileHasSuffix(fileName, ".vmdk")) {
+ if (! virFileHasSuffix(disk->src, ".vmdk")) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting source '%s' of first file-based harddisk to "
"be a VMDK image"), disk->src);
VIR_FREE(vmx);
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
- VIR_FREE(fileName);
VIR_FREE(url);
VIR_FREE(datastoreRelatedPath);
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL;
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
esxVI_FileInfo *fileInfo = NULL;
- char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
- char *prefix = NULL;
+ char *directoryAndFileName = NULL;
+ size_t length;
int count = 0;
int i;
/* Interpret search result */
for (searchResults = searchResultsList; searchResults != NULL;
searchResults = searchResults->_next) {
- VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
- VIR_FREE(prefix);
+ VIR_FREE(directoryAndFileName);
- if (esxUtil_ParseDatastorePath(searchResults->folderPath, &datastoreName,
- &directoryName, &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(searchResults->folderPath, NULL, NULL,
+ &directoryAndFileName) < 0) {
goto cleanup;
}
- if (directoryName != NULL) {
- if (virAsprintf(&prefix, "%s/%s", directoryName, fileName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- prefix = strdup(fileName);
+ /* Strip trailing separators */
+ length = strlen(directoryAndFileName);
- if (prefix == NULL) {
- virReportOOMError();
- goto cleanup;
- }
+ while (length > 0 && directoryAndFileName[length - 1] == '/') {
+ directoryAndFileName[length - 1] = '\0';
+ --length;
}
+ /* Build volume names */
for (fileInfo = searchResults->file; fileInfo != NULL;
fileInfo = fileInfo->_next) {
- if (*prefix == '\0') {
+ if (length < 1) {
names[count] = strdup(fileInfo->path);
if (names[count] == NULL) {
virReportOOMError();
goto cleanup;
}
- } else if (virAsprintf(&names[count], "%s/%s", prefix,
+ } else if (virAsprintf(&names[count], "%s/%s", directoryAndFileName,
fileInfo->path) < 0) {
virReportOOMError();
goto cleanup;
}
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
- VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
- VIR_FREE(prefix);
+ VIR_FREE(directoryAndFileName);
return count;
}
virStorageVolPtr volume = NULL;
esxPrivate *priv = conn->storagePrivateData;
char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
- char *volumeName = NULL;
+ char *directoryAndFileName = NULL;
esxVI_FileInfo *fileInfo = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxUtil_ParseDatastorePath(keyOrPath, &datastoreName, &directoryName,
- &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(keyOrPath, &datastoreName, NULL,
+ &directoryAndFileName) < 0) {
goto cleanup;
}
- if (directoryName != NULL) {
- if (virAsprintf(&volumeName, "%s/%s", directoryName, fileName) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- volumeName = strdup(fileName);
-
- if (volumeName == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- }
-
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
- volume = virGetStorageVol(conn, datastoreName, volumeName, keyOrPath);
+ volume = virGetStorageVol(conn, datastoreName, directoryAndFileName,
+ keyOrPath);
cleanup:
VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
- VIR_FREE(volumeName);
+ VIR_FREE(directoryAndFileName);
esxVI_FileInfo_Free(&fileInfo);
return volume;
int
esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
- char **directoryName, char **fileName)
+ char **directoryName, char **directoryAndFileName)
{
int result = -1;
char *copyOfDatastorePath = NULL;
char *tmp = NULL;
char *saveptr = NULL;
char *preliminaryDatastoreName = NULL;
- char *directoryAndFileName = NULL;
- char *separator = NULL;
+ char *preliminaryDirectoryAndFileName = NULL;
+ char *preliminaryFileName = NULL;
- if (datastoreName == NULL || *datastoreName != NULL ||
- directoryName == NULL || *directoryName != NULL ||
- fileName == NULL || *fileName != NULL) {
+ if ((datastoreName != NULL && *datastoreName != NULL) ||
+ (directoryName != NULL && *directoryName != NULL) ||
+ (directoryAndFileName != NULL && *directoryAndFileName != NULL)) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
goto cleanup;
}
- /* Expected format: '[<datastore>] <path>' */
- if ((tmp = STRSKIP(copyOfDatastorePath, "[")) == NULL ||
- (preliminaryDatastoreName = strtok_r(tmp, "]", &saveptr)) == NULL ||
- (directoryAndFileName = strtok_r(NULL, "", &saveptr)) == NULL) {
+ /* Expected format: '[<datastore>] <path>' where <path> is optional */
+ if ((tmp = STRSKIP(copyOfDatastorePath, "[")) == NULL || *tmp == ']' ||
+ (preliminaryDatastoreName = strtok_r(tmp, "]", &saveptr)) == NULL) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Datastore path '%s' doesn't have expected format "
"'[<datastore>] <path>'"), datastorePath);
goto cleanup;
}
- if (esxVI_String_DeepCopyValue(datastoreName,
+ if (datastoreName != NULL &&
+ esxVI_String_DeepCopyValue(datastoreName,
preliminaryDatastoreName) < 0) {
goto cleanup;
}
- directoryAndFileName += strspn(directoryAndFileName, " ");
+ preliminaryDirectoryAndFileName = strtok_r(NULL, "", &saveptr);
- /* Split <path> into <directory>/<file>, where <directory> is optional */
- separator = strrchr(directoryAndFileName, '/');
+ if (preliminaryDirectoryAndFileName == NULL) {
+ preliminaryDirectoryAndFileName = (char *)"";
+ } else {
+ preliminaryDirectoryAndFileName +=
+ strspn(preliminaryDirectoryAndFileName, " ");
+ }
+
+ if (directoryAndFileName != NULL &&
+ esxVI_String_DeepCopyValue(directoryAndFileName,
+ preliminaryDirectoryAndFileName) < 0) {
+ goto cleanup;
+ }
- if (separator != NULL) {
- *separator++ = '\0';
+ if (directoryName != NULL) {
+ /* Split <path> into <directory>/<file> */
+ preliminaryFileName = strrchr(preliminaryDirectoryAndFileName, '/');
- if (*separator == '\0') {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Datastore path '%s' doesn't reference a file"),
- datastorePath);
- goto cleanup;
+ if (preliminaryFileName != NULL) {
+ *preliminaryFileName++ = '\0';
}
if (esxVI_String_DeepCopyValue(directoryName,
- directoryAndFileName) < 0 ||
- esxVI_String_DeepCopyValue(fileName, separator) < 0) {
- goto cleanup;
- }
- } else {
- if (esxVI_String_DeepCopyValue(fileName, directoryAndFileName) < 0) {
+ preliminaryDirectoryAndFileName) < 0) {
goto cleanup;
}
}
cleanup:
if (result < 0) {
- VIR_FREE(*datastoreName);
- VIR_FREE(*directoryName);
- VIR_FREE(*fileName);
+ if (datastoreName != NULL) {
+ VIR_FREE(*datastoreName);
+ }
+
+ if (directoryName != NULL) {
+ VIR_FREE(*directoryName);
+ }
+
+ if (directoryAndFileName != NULL) {
+ VIR_FREE(*directoryAndFileName);
+ }
}
VIR_FREE(copyOfDatastorePath);
int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
int esxUtil_ParseDatastorePath(const char *datastorePath, char **datastoreName,
- char **directoryName, char **fileName);
+ char **directoryName, char **directoryAndFileName);
int esxUtil_ResolveHostname(const char *hostname,
char *ipAddress, size_t ipAddress_length);
int result = -1;
char *datastoreName = NULL;
char *directoryName = NULL;
+ char *directoryAndFileName = NULL;
char *fileName = NULL;
+ size_t length;
char *datastorePathWithoutFileName = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *datastore = NULL;
}
if (esxUtil_ParseDatastorePath(datastorePath, &datastoreName,
- &directoryName, &fileName) < 0) {
+ &directoryName, &directoryAndFileName) < 0) {
goto cleanup;
}
- if (directoryName == NULL) {
+ if (STREQ(directoryName, directoryAndFileName)) {
+ /*
+ * The <path> part of the datatore path didn't contain a '/', assume
+ * that the <path> part is actually the file name.
+ */
if (virAsprintf(&datastorePathWithoutFileName, "[%s]",
datastoreName) < 0) {
virReportOOMError();
goto cleanup;
}
+
+ if (esxVI_String_DeepCopyValue(&fileName, directoryAndFileName) < 0) {
+ goto cleanup;
+ }
} else {
if (virAsprintf(&datastorePathWithoutFileName, "[%s] %s",
datastoreName, directoryName) < 0) {
virReportOOMError();
goto cleanup;
}
+
+ length = strlen(directoryName);
+
+ if (directoryAndFileName[length] != '/' ||
+ directoryAndFileName[length + 1] == '\0') {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Datastore path '%s' doesn't reference a file"),
+ datastorePath);
+ goto cleanup;
+ }
+
+ if (esxVI_String_DeepCopyValue(&fileName,
+ directoryAndFileName + length + 1) < 0) {
+ goto cleanup;
+ }
}
/* Lookup HostDatastoreBrowser */
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
+ VIR_FREE(directoryAndFileName);
VIR_FREE(fileName);
VIR_FREE(datastorePathWithoutFileName);
esxVI_String_Free(&propertyNameList);
int result;
const char *datastoreName;
const char *directoryName;
- const char *fileName;
+ const char *directoryAndFileName;
};
static struct testPath paths[] = {
- { "[datastore] directory/file", 0, "datastore", "directory", "file" },
- { "[datastore] file", 0, "datastore", NULL, "file" },
+ { "[datastore] directory/file", 0, "datastore", "directory",
+ "directory/file" },
+ { "[datastore] directory1/directory2/file", 0, "datastore",
+ "directory1/directory2", "directory1/directory2/file" },
+ { "[datastore] file", 0, "datastore", "file", "file" },
+ { "[datastore] directory/", 0, "datastore", "directory", "directory/" },
+ { "[datastore]", 0, "datastore", "", "" },
{ "[] directory/file", -1, NULL, NULL, NULL },
- { "[datastore] directory/", -1, NULL, NULL, NULL },
{ "directory/file", -1, NULL, NULL, NULL },
};
int i, result = 0;
char *datastoreName = NULL;
char *directoryName = NULL;
- char *fileName = NULL;
+ char *directoryAndFileName = NULL;
for (i = 0; i < ARRAY_CARDINALITY(paths); ++i) {
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
- VIR_FREE(fileName);
+ VIR_FREE(directoryAndFileName);
- if (esxUtil_ParseDatastorePath(paths[i].datastorePath,
- &datastoreName, &directoryName,
- &fileName) != paths[i].result) {
+ if (esxUtil_ParseDatastorePath
+ (paths[i].datastorePath, &datastoreName, &directoryName,
+ &directoryAndFileName) != paths[i].result) {
goto failure;
}
goto failure;
}
- if (paths[i].directoryName != NULL &&
- STRNEQ(paths[i].directoryName, directoryName)) {
+ if (STRNEQ(paths[i].directoryName, directoryName)) {
virtTestDifference(stderr, paths[i].directoryName, directoryName);
goto failure;
}
- if (STRNEQ(paths[i].fileName, fileName)) {
- virtTestDifference(stderr, paths[i].fileName, fileName);
+ if (STRNEQ(paths[i].directoryAndFileName, directoryAndFileName)) {
+ virtTestDifference(stderr, paths[i].directoryAndFileName,
+ directoryAndFileName);
goto failure;
}
}
cleanup:
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
- VIR_FREE(fileName);
+ VIR_FREE(directoryAndFileName);
return result;
{
bool success = false;
char *datastoreName = NULL;
- char *directoryName = NULL;
- char *fileName = NULL;
+ char *directoryAndFileName = NULL;
char *absolutePath = NULL;
if (STRPREFIX(src, "[")) {
/* Found potential datastore path */
- if (esxUtil_ParseDatastorePath(src, &datastoreName, &directoryName,
- &fileName) < 0) {
+ if (esxUtil_ParseDatastorePath(src, &datastoreName, NULL,
+ &directoryAndFileName) < 0) {
goto cleanup;
}
- if (directoryName == NULL) {
- virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s", datastoreName,
- fileName);
- } else {
- virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s", datastoreName,
- directoryName, fileName);
- }
+ virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s", datastoreName,
+ directoryAndFileName);
} else if (STRPREFIX(src, "/")) {
/* Found absolute path */
absolutePath = strdup(src);
}
VIR_FREE(datastoreName);
- VIR_FREE(directoryName);
- VIR_FREE(fileName);
+ VIR_FREE(directoryAndFileName);
return absolutePath;
}