mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00:00
ESX add esxDomainDefineXML()
A given domain XML gets converted to a VMX config, uploaded to the host and registered as new virtual machine. * src/esx/esx_driver.c: refactor datastore related path parsing into esxUtil_ParseDatastoreRelatedPath() * src/esx/esx_util.[ch]: add esxUtil_ParseDatastoreRelatedPath() * src/esx/esx_vi.[ch]: add esxVI_Context_UploadFile(), add datastores to the traversal in esxVI_BuildFullTraversalSpecList(), add esxVI_LookupDatastoreByName() * src/esx/esx_vi_methods.[ch]: add esxVI_RegisterVM_Task() * src/esx/esx_vi_types.c: make some error message more verbose * src/esx/esx_vmx.[ch]: add esxVMX_AbsolutePathToDatastoreRelatedPath() to convert a path into a datastore related path, add esxVMX_ParseFileName() to convert from VMX path format to domain XML path format, extend the other parsing function to be datastore aware, add esxVMX_FormatFileName() to convert from domain XML path format to VMX path format, fix VMX ethernet entry formating * tests/esxutilstest.c: add test for esxUtil_ParseDatastoreRelatedPath() * tests/vmx2xmldata/*: update domain XML files to use datastore related paths * tests/xml2vmxdata/*: update domain XML files to use datastore related paths, update VMX files to use absolute paths
This commit is contained in:
parent
c3aa1f8bdb
commit
49faa15e4f
@ -2267,7 +2267,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
const char *vmPathName = NULL;
|
||||
char *datastoreName = NULL;
|
||||
char *vmxPath = NULL;
|
||||
char *directoryName = NULL;
|
||||
char *fileName = NULL;
|
||||
virBuffer buffer = VIR_BUFFER_INITIALIZER;
|
||||
char *url = NULL;
|
||||
char *vmx = NULL;
|
||||
@ -2306,17 +2307,21 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* expected format: "[<datastoreName>] <vmxPath>" */
|
||||
if (sscanf(vmPathName, "[%a[^]%]] %a[^\n]", &datastoreName, &vmxPath) != 2) {
|
||||
ESX_ERROR(domain->conn, VIR_ERR_OPERATION_INVALID,
|
||||
"'config.files.vmPathName' property '%s' doesn't have "
|
||||
"expected format '[<datastore>] <vmx>'", vmPathName);
|
||||
if (esxUtil_ParseDatastoreRelatedPath(domain->conn, vmPathName,
|
||||
&datastoreName, &directoryName,
|
||||
&fileName) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
|
||||
domain->conn->uri->server, domain->conn->uri->port);
|
||||
virBufferURIEncodeString(&buffer, vmxPath);
|
||||
|
||||
if (directoryName != NULL) {
|
||||
virBufferURIEncodeString(&buffer, directoryName);
|
||||
virBufferAddChar(&buffer, '/');
|
||||
}
|
||||
|
||||
virBufferURIEncodeString(&buffer, fileName);
|
||||
virBufferAddLit(&buffer, "?dcPath=");
|
||||
virBufferURIEncodeString(&buffer, priv->host->datacenter->value);
|
||||
virBufferAddLit(&buffer, "&dsName=");
|
||||
@ -2329,11 +2334,12 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
||||
|
||||
url = virBufferContentAndReset(&buffer);
|
||||
|
||||
if (esxVI_Context_Download(domain->conn, priv->host, url, &vmx) < 0) {
|
||||
if (esxVI_Context_DownloadFile(domain->conn, priv->host, url, &vmx) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->apiVersion);
|
||||
def = esxVMX_ParseConfig(domain->conn, priv->host, vmx, datastoreName,
|
||||
directoryName, priv->host->apiVersion);
|
||||
|
||||
if (def != NULL) {
|
||||
xml = virDomainDefFormat(domain->conn, def, flags);
|
||||
@ -2343,7 +2349,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
|
||||
esxVI_String_Free(&propertyNameList);
|
||||
esxVI_ObjectContent_Free(&virtualMachine);
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(vmxPath);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(fileName);
|
||||
VIR_FREE(url);
|
||||
VIR_FREE(vmx);
|
||||
virDomainDefFree(def);
|
||||
@ -2364,6 +2371,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
|
||||
unsigned int flags ATTRIBUTE_UNUSED)
|
||||
{
|
||||
esxPrivate *priv = (esxPrivate *)conn->privateData;
|
||||
esxVI_Context *ctx = NULL;
|
||||
esxVI_APIVersion apiVersion = esxVI_APIVersion_Unknown;
|
||||
virDomainDefPtr def = NULL;
|
||||
char *xml = NULL;
|
||||
@ -2375,10 +2383,11 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
|
||||
}
|
||||
|
||||
if (! priv->phantom) {
|
||||
ctx = priv->host;
|
||||
apiVersion = priv->host->apiVersion;
|
||||
}
|
||||
|
||||
def = esxVMX_ParseConfig(conn, nativeConfig, apiVersion);
|
||||
def = esxVMX_ParseConfig(conn, ctx, nativeConfig, "?", "?", apiVersion);
|
||||
|
||||
if (def != NULL) {
|
||||
xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_INACTIVE);
|
||||
@ -2418,7 +2427,7 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vmx = esxVMX_FormatConfig(conn, def, priv->host->apiVersion);
|
||||
vmx = esxVMX_FormatConfig(conn, priv->host, def, priv->host->apiVersion);
|
||||
|
||||
virDomainDefFree(def);
|
||||
|
||||
@ -2605,6 +2614,195 @@ esxDomainCreate(virDomainPtr domain)
|
||||
|
||||
|
||||
|
||||
static virDomainPtr
|
||||
esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
|
||||
{
|
||||
esxPrivate *priv = (esxPrivate *)conn->privateData;
|
||||
virDomainDefPtr def = NULL;
|
||||
char *vmx = NULL;
|
||||
esxVI_ObjectContent *virtualMachine = NULL;
|
||||
char *datastoreName = NULL;
|
||||
char *directoryName = NULL;
|
||||
char *fileName = NULL;
|
||||
virBuffer buffer = VIR_BUFFER_INITIALIZER;
|
||||
char *url = NULL;
|
||||
char *datastoreRelatedPath = NULL;
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_ObjectContent *hostSystem = NULL;
|
||||
esxVI_ManagedObjectReference *resourcePool = NULL;
|
||||
esxVI_ManagedObjectReference *task = NULL;
|
||||
esxVI_TaskInfoState taskInfoState;
|
||||
virDomainPtr domain = NULL;
|
||||
|
||||
if (priv->phantom) {
|
||||
ESX_ERROR(conn, VIR_ERR_OPERATION_INVALID,
|
||||
"Not possible with a phantom connection");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (esxVI_EnsureSession(conn, priv->host) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Parse domain XML */
|
||||
def = virDomainDefParseString(conn, priv->caps, xml,
|
||||
VIR_DOMAIN_XML_INACTIVE);
|
||||
|
||||
if (def == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Check if an existing domain should be edited */
|
||||
if (esxVI_LookupVirtualMachineByUuid(conn, priv->host, def->uuid, NULL,
|
||||
&virtualMachine,
|
||||
esxVI_Occurence_OptionalItem) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (virtualMachine != NULL) {
|
||||
/* FIXME */
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Domain already exists, editing existing domains is not "
|
||||
"supported yet");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Build VMX from domain XML */
|
||||
vmx = esxVMX_FormatConfig(conn, priv->host, def, priv->host->apiVersion);
|
||||
|
||||
if (vmx == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Build VMX datastore URL */
|
||||
if (def->ndisks < 1) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Domain XML doesn't contain a disk, cannot deduce datastore "
|
||||
"and path for VMX file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (def->disks[0]->src == NULL) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"First disk has no source, cannot deduce datastore and path "
|
||||
"for VMX file");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (esxUtil_ParseDatastoreRelatedPath(conn, def->disks[0]->src,
|
||||
&datastoreName, &directoryName,
|
||||
&fileName) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (! esxUtil_EqualSuffix(fileName, ".vmdk")) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Expecting source of first disk '%s' to be a VMDK image",
|
||||
def->disks[0]->src);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
|
||||
conn->uri->server, conn->uri->port);
|
||||
|
||||
if (directoryName != NULL) {
|
||||
virBufferURIEncodeString(&buffer, directoryName);
|
||||
virBufferAddChar(&buffer, '/');
|
||||
}
|
||||
|
||||
virBufferURIEncodeString(&buffer, def->name);
|
||||
virBufferAddLit(&buffer, ".vmx?dcPath=");
|
||||
virBufferURIEncodeString(&buffer, priv->host->datacenter->value);
|
||||
virBufferAddLit(&buffer, "&dsName=");
|
||||
virBufferURIEncodeString(&buffer, datastoreName);
|
||||
|
||||
if (virBufferError(&buffer)) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
url = virBufferContentAndReset(&buffer);
|
||||
|
||||
if (directoryName != NULL) {
|
||||
if (virAsprintf(&datastoreRelatedPath, "[%s] %s/%s.vmx", datastoreName,
|
||||
directoryName, def->name) < 0) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
if (virAsprintf(&datastoreRelatedPath, "[%s] %s.vmx", datastoreName,
|
||||
def->name) < 0) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get resource pool */
|
||||
if (esxVI_String_AppendValueToList(conn, &propertyNameList, "parent") < 0 ||
|
||||
esxVI_LookupHostSystemByIp(conn, priv->host, priv->host->ipAddress,
|
||||
propertyNameList, &hostSystem) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (esxVI_GetResourcePool(conn, priv->host, hostSystem,
|
||||
&resourcePool) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Check, if VMX file already exists */
|
||||
/* FIXME */
|
||||
|
||||
/* Upload VMX file */
|
||||
if (esxVI_Context_UploadFile(conn, priv->host, url, vmx) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Register the domain */
|
||||
if (esxVI_RegisterVM_Task(conn, priv->host, priv->host->vmFolder,
|
||||
datastoreRelatedPath, NULL, esxVI_Boolean_False,
|
||||
resourcePool, hostSystem->obj, &task) < 0 ||
|
||||
esxVI_WaitForTaskCompletion(conn, priv->host, task,
|
||||
&taskInfoState) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (taskInfoState != esxVI_TaskInfoState_Success) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Could not define domain");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
domain = virGetDomain(conn, def->name, def->uuid);
|
||||
|
||||
if (domain != NULL) {
|
||||
domain->id = -1;
|
||||
}
|
||||
|
||||
/* FIXME: Add proper rollback in case of an error */
|
||||
|
||||
cleanup:
|
||||
virDomainDefFree(def);
|
||||
VIR_FREE(vmx);
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(fileName);
|
||||
VIR_FREE(url);
|
||||
VIR_FREE(datastoreRelatedPath);
|
||||
esxVI_ObjectContent_Free(&virtualMachine);
|
||||
esxVI_String_Free(&propertyNameList);
|
||||
esxVI_ObjectContent_Free(&hostSystem);
|
||||
esxVI_ManagedObjectReference_Free(&resourcePool);
|
||||
esxVI_ManagedObjectReference_Free(&task);
|
||||
|
||||
return domain;
|
||||
|
||||
failure:
|
||||
domain = NULL;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
esxDomainUndefine(virDomainPtr domain)
|
||||
{
|
||||
@ -3297,7 +3495,7 @@ static virDriver esxDriver = {
|
||||
esxListDefinedDomains, /* listDefinedDomains */
|
||||
esxNumberOfDefinedDomains, /* numOfDefinedDomains */
|
||||
esxDomainCreate, /* domainCreate */
|
||||
NULL, /* domainDefineXML */
|
||||
esxDomainDefineXML, /* domainDefineXML */
|
||||
esxDomainUndefine, /* domainUndefine */
|
||||
NULL, /* domainAttachDevice */
|
||||
NULL, /* domainDetachDevice */
|
||||
|
@ -263,6 +263,89 @@ esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id)
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxUtil_ParseDatastoreRelatedPath(virConnectPtr conn,
|
||||
const char *datastoreRelatedPath,
|
||||
char **datastoreName,
|
||||
char **directoryName, char **fileName)
|
||||
{
|
||||
int result = 0;
|
||||
char *directoryAndFileName = NULL;
|
||||
char *separator = NULL;
|
||||
|
||||
if (datastoreName == NULL || *datastoreName != NULL ||
|
||||
directoryName == NULL || *directoryName != NULL ||
|
||||
fileName == NULL || *fileName != NULL) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse string as '[<datastore>] <path>'. '%as' is similar to '%s', but
|
||||
* sscanf() will allocate the memory for the string, so the caller doesn't
|
||||
* need to preallocate a buffer that's large enough.
|
||||
*
|
||||
* The s in '%as' can be replaced with a character set, e.g. [a-z].
|
||||
*
|
||||
* '%a[^]%]' matches <datastore>. '[^]%]' excludes ']' from the accepted
|
||||
* characters, otherwise sscanf() wont match what it should.
|
||||
*
|
||||
* '%a[^\n]' matches <path>. '[^\n]' excludes '\n' from the accepted
|
||||
* characters, otherwise sscanf() would only match up to the first space,
|
||||
* but spaces are valid in <path>.
|
||||
*/
|
||||
if (sscanf(datastoreRelatedPath, "[%a[^]%]] %a[^\n]", datastoreName,
|
||||
&directoryAndFileName) != 2) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Datastore related path '%s' doesn't have expected format "
|
||||
"'[<datastore>] <path>'", datastoreRelatedPath);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Split <path> into <directory>/<file>, where <directory> is optional */
|
||||
separator = strrchr(directoryAndFileName, '/');
|
||||
|
||||
if (separator != NULL) {
|
||||
*separator++ = '\0';
|
||||
|
||||
*directoryName = directoryAndFileName;
|
||||
directoryAndFileName = NULL;
|
||||
|
||||
if (*separator == '\0') {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Datastore related path '%s' doesn't reference a file",
|
||||
datastoreRelatedPath);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
*fileName = strdup(separator);
|
||||
|
||||
if (*fileName == NULL) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
*fileName = directoryAndFileName;
|
||||
directoryAndFileName = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(directoryAndFileName);
|
||||
|
||||
return result;
|
||||
|
||||
failure:
|
||||
VIR_FREE(*datastoreName);
|
||||
VIR_FREE(*directoryName);
|
||||
VIR_FREE(*fileName);
|
||||
|
||||
result = -1;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxUtil_ResolveHostname(virConnectPtr conn, const char *hostname,
|
||||
char *ipAddress, size_t ipAddress_length)
|
||||
|
@ -40,6 +40,11 @@ int esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
|
||||
|
||||
int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
|
||||
|
||||
int esxUtil_ParseDatastoreRelatedPath(virConnectPtr conn,
|
||||
const char *datastoreRelatedPath,
|
||||
char **datastoreName,
|
||||
char **directoryName, char **fileName);
|
||||
|
||||
int esxUtil_ResolveHostname(virConnectPtr conn, const char *hostname,
|
||||
char *ipAddress, size_t ipAddress_length);
|
||||
|
||||
|
228
src/esx/esx_vi.c
228
src/esx/esx_vi.c
@ -138,7 +138,35 @@ ESX_VI__TEMPLATE__FREE(Context,
|
||||
});
|
||||
|
||||
static size_t
|
||||
_esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
|
||||
esxVI_CURL_ReadString(char *data, size_t size, size_t nmemb, void *ptrptr)
|
||||
{
|
||||
const char *content = *(const char **)ptrptr;
|
||||
size_t available = 0;
|
||||
size_t requested = size * nmemb;
|
||||
|
||||
if (content == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
available = strlen(content);
|
||||
|
||||
if (available == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (requested > available) {
|
||||
requested = available;
|
||||
}
|
||||
|
||||
memcpy(data, content, requested);
|
||||
|
||||
*(const char **)ptrptr = content + requested;
|
||||
|
||||
return requested;
|
||||
}
|
||||
|
||||
static size_t
|
||||
esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
virBufferAdd((virBufferPtr) buffer, data, size * nmemb);
|
||||
@ -153,7 +181,7 @@ _esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
|
||||
|
||||
#if ESX_VI__CURL__ENABLE_DEBUG_OUTPUT
|
||||
static int
|
||||
_esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type,
|
||||
esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type,
|
||||
char *info, size_t size, void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
switch (type) {
|
||||
@ -246,11 +274,13 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, noVerify ? 0 : 2);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_COOKIEFILE, "");
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPHEADER, ctx->curl_headers);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_READFUNCTION,
|
||||
esxVI_CURL_ReadString);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEFUNCTION,
|
||||
_esxVI_CURL_WriteBuffer);
|
||||
esxVI_CURL_WriteBuffer);
|
||||
#if ESX_VI__CURL__ENABLE_DEBUG_OUTPUT
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_DEBUGFUNCTION,
|
||||
_esxVI_CURL_Debug);
|
||||
esxVI_CURL_Debug);
|
||||
#endif
|
||||
|
||||
if (virMutexInit(&ctx->curl_lock) < 0) {
|
||||
@ -398,8 +428,8 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
||||
}
|
||||
|
||||
int
|
||||
esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
||||
char **content)
|
||||
esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *url, char **content)
|
||||
{
|
||||
virBuffer buffer = VIR_BUFFER_INITIALIZER;
|
||||
CURLcode errorCode;
|
||||
@ -414,6 +444,7 @@ esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
||||
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, url);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEDATA, &buffer);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 0);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPGET, 1);
|
||||
|
||||
errorCode = curl_easy_perform(ctx->curl_handle);
|
||||
@ -464,6 +495,61 @@ esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
|
||||
goto failure;
|
||||
}
|
||||
|
||||
int
|
||||
esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *url, const char *content)
|
||||
{
|
||||
CURLcode errorCode;
|
||||
long responseCode;
|
||||
|
||||
if (content == NULL) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
virMutexLock(&ctx->curl_lock);
|
||||
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, url);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_READDATA, &content);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 1);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_INFILESIZE, strlen(content));
|
||||
|
||||
errorCode = curl_easy_perform(ctx->curl_handle);
|
||||
|
||||
if (errorCode != CURLE_OK) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"curl_easy_perform() returned an error: %s (%d)",
|
||||
curl_easy_strerror(errorCode), errorCode);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
|
||||
&responseCode);
|
||||
|
||||
if (errorCode != CURLE_OK) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"curl_easy_getinfo() returned an error: %s (%d)",
|
||||
curl_easy_strerror(errorCode), errorCode);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
virMutexUnlock(&ctx->curl_lock);
|
||||
|
||||
if (responseCode != 200 && responseCode != 201) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"HTTP response code %d while trying to upload to '%s'",
|
||||
(int)responseCode, url);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
unlock:
|
||||
virMutexUnlock(&ctx->curl_lock);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *request, const char *xpathExpression,
|
||||
@ -486,6 +572,7 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
|
||||
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, ctx->url);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEDATA, &buffer);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 0);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDS, request);
|
||||
curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDSIZE, strlen(request));
|
||||
|
||||
@ -1085,15 +1172,24 @@ esxVI_BuildFullTraversalSpecList(virConnectPtr conn,
|
||||
"visitFolders",
|
||||
"Folder", "childEntity",
|
||||
"visitFolders\0"
|
||||
"datacenterToDatastore\0"
|
||||
"datacenterToVmFolder\0"
|
||||
"datacenterToHostFolder\0"
|
||||
"computeResourceToHost\0"
|
||||
"computeResourceToResourcePool\0"
|
||||
"HostSystemToVm\0"
|
||||
"hostSystemToVm\0"
|
||||
"resourcePoolToVm\0") < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Traversal through datastore branch */
|
||||
if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
|
||||
"datacenterToDatastore",
|
||||
"Datacenter", "datastore",
|
||||
NULL) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Traversal through vmFolder branch */
|
||||
if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
|
||||
"datacenterToVmFolder",
|
||||
@ -1138,7 +1234,7 @@ esxVI_BuildFullTraversalSpecList(virConnectPtr conn,
|
||||
|
||||
/* Recurse through all hosts */
|
||||
if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
|
||||
"HostSystemToVm",
|
||||
"hostSystemToVm",
|
||||
"HostSystem", "vm",
|
||||
"visitFolders\0") < 0) {
|
||||
goto failure;
|
||||
@ -1351,7 +1447,8 @@ esxVI_GetManagedEntityStatus(virConnectPtr conn,
|
||||
}
|
||||
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Missing '%s' property", propertyName);
|
||||
"Missing '%s' property while looking for ManagedEntityStatus",
|
||||
propertyName);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1725,6 +1822,119 @@ esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *name, esxVI_String *propertyNameList,
|
||||
esxVI_ObjectContent **datastore,
|
||||
esxVI_Occurence occurence)
|
||||
{
|
||||
int result = 0;
|
||||
esxVI_String *completePropertyNameList = NULL;
|
||||
esxVI_ObjectContent *datastoreList = NULL;
|
||||
esxVI_ObjectContent *candidate = NULL;
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
size_t offset = strlen("/vmfs/volumes/");
|
||||
|
||||
if (datastore == NULL || *datastore != NULL) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get all datastores */
|
||||
if (esxVI_String_DeepCopyList(conn, &completePropertyNameList,
|
||||
propertyNameList) < 0 ||
|
||||
esxVI_String_AppendValueListToList(conn, &completePropertyNameList,
|
||||
"info.name\0"
|
||||
"info.url\0") < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (esxVI_GetObjectContent(conn, ctx, ctx->datacenter,
|
||||
"Datastore", completePropertyNameList,
|
||||
esxVI_Boolean_True, &datastoreList) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (datastoreList == NULL) {
|
||||
if (occurence == esxVI_Occurence_OptionalItem) {
|
||||
goto cleanup;
|
||||
} else {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"No datastores available");
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for a matching datastore */
|
||||
for (candidate = datastoreList; candidate != NULL;
|
||||
candidate = candidate->_next) {
|
||||
for (dynamicProperty = candidate->propSet; dynamicProperty != NULL;
|
||||
dynamicProperty = dynamicProperty->_next) {
|
||||
if (STREQ(dynamicProperty->name, "info.name")) {
|
||||
if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
|
||||
esxVI_Type_String) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (STREQ(dynamicProperty->val->string, name)) {
|
||||
if (esxVI_ObjectContent_DeepCopy(conn, datastore,
|
||||
candidate) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Found datastore with matching name */
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (STREQ(dynamicProperty->name, "info.url")) {
|
||||
if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
|
||||
esxVI_Type_String) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (! STRPREFIX(dynamicProperty->val->string,
|
||||
"/vmfs/volumes/")) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Datastore URL '%s' has unexpected prefix, "
|
||||
"expecting '/vmfs/volumes/' prefix",
|
||||
dynamicProperty->val->string);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (STREQ(dynamicProperty->val->string + offset, name)) {
|
||||
if (esxVI_ObjectContent_DeepCopy(conn, datastore,
|
||||
candidate) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* Found datastore with matching URL suffix */
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (occurence != esxVI_Occurence_OptionalItem) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Could not find datastore with name '%s'", name);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
esxVI_String_Free(&completePropertyNameList);
|
||||
esxVI_ObjectContent_Free(&datastoreList);
|
||||
|
||||
return result;
|
||||
|
||||
failure:
|
||||
result = -1;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *name, const char *request,
|
||||
|
@ -95,8 +95,10 @@ int esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *ipAddress, const char *url,
|
||||
const char *username, const char *password,
|
||||
int noVerify);
|
||||
int esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx,
|
||||
int esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *url, char **content);
|
||||
int esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *url, const char *content);
|
||||
int esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *request, const char *xpathExpression,
|
||||
esxVI_Response **response, esxVI_Boolean expectList);
|
||||
@ -246,6 +248,12 @@ int esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_ObjectContent **virtualMachine,
|
||||
esxVI_Occurence occurence);
|
||||
|
||||
int esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *name,
|
||||
esxVI_String *propertyNameList,
|
||||
esxVI_ObjectContent **datastore,
|
||||
esxVI_Occurence occurence);
|
||||
|
||||
int esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *name, const char *request,
|
||||
esxVI_ManagedObjectReference **task);
|
||||
|
@ -520,6 +520,76 @@ esxVI_ReconfigVM_Task(virConnectPtr conn, esxVI_Context *ctx,
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_ManagedObjectReference *folder,
|
||||
const char *path, const char *name,
|
||||
esxVI_Boolean asTemplate,
|
||||
esxVI_ManagedObjectReference *resourcePool,
|
||||
esxVI_ManagedObjectReference *hostSystem,
|
||||
esxVI_ManagedObjectReference **task)
|
||||
{
|
||||
int result = 0;
|
||||
virBuffer buffer = VIR_BUFFER_INITIALIZER;
|
||||
char *request = NULL;
|
||||
|
||||
if (task == NULL || *task != NULL) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
|
||||
virBufferAddLit(&buffer, "<RegisterVM_Task xmlns=\"urn:vim25\">");
|
||||
|
||||
if (esxVI_ManagedObjectReference_Serialize(conn, folder, "_this", &buffer,
|
||||
esxVI_Boolean_True) < 0 ||
|
||||
esxVI_String_SerializeValue(conn, path, "path", &buffer,
|
||||
esxVI_Boolean_True) < 0 ||
|
||||
esxVI_String_SerializeValue(conn, name, "name", &buffer,
|
||||
esxVI_Boolean_False) < 0 ||
|
||||
esxVI_Boolean_Serialize(conn, asTemplate, "asTemplate", &buffer,
|
||||
esxVI_Boolean_False) < 0 ||
|
||||
esxVI_ManagedObjectReference_Serialize(conn, resourcePool, "pool",
|
||||
&buffer,
|
||||
esxVI_Boolean_False) < 0 ||
|
||||
esxVI_ManagedObjectReference_Serialize(conn, hostSystem, "host",
|
||||
&buffer,
|
||||
esxVI_Boolean_False) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
virBufferAddLit(&buffer, "</RegisterVM_Task>");
|
||||
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);
|
||||
|
||||
if (virBufferError(&buffer)) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
request = virBufferContentAndReset(&buffer);
|
||||
|
||||
if (esxVI_StartVirtualMachineTask(conn, ctx, "RegisterVM", request,
|
||||
task) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(request);
|
||||
|
||||
return result;
|
||||
|
||||
failure:
|
||||
if (request == NULL) {
|
||||
request = virBufferContentAndReset(&buffer);
|
||||
}
|
||||
|
||||
result = -1;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_ManagedObjectReference *virtualMachine)
|
||||
|
@ -72,6 +72,14 @@ int esxVI_ReconfigVM_Task(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_VirtualMachineConfigSpec *spec,
|
||||
esxVI_ManagedObjectReference **task);
|
||||
|
||||
int esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_ManagedObjectReference *folder,
|
||||
const char *path, const char *name,
|
||||
esxVI_Boolean asTemplate,
|
||||
esxVI_ManagedObjectReference *resourcePool,
|
||||
esxVI_ManagedObjectReference *hostSystem,
|
||||
esxVI_ManagedObjectReference **task);
|
||||
|
||||
int esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
|
||||
esxVI_ManagedObjectReference *virtualMachine);
|
||||
|
||||
|
@ -633,7 +633,8 @@ esxVI_AnyType_Deserialize(virConnectPtr conn, xmlNodePtr node,
|
||||
BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
|
||||
|
||||
if ((*anyType)->other == NULL) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Missing 'type' property");
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"AnyType is missing 'type' property");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -1388,7 +1389,8 @@ esxVI_ManagedObjectReference_Deserialize
|
||||
(char *)xmlGetNoNsProp(node, BAD_CAST "type");
|
||||
|
||||
if ((*managedObjectReference)->type == NULL) {
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Missing 'type' property");
|
||||
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"ManagedObjectReference is missing 'type' property");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ def->parallels[0]...
|
||||
#define VIR_FROM_THIS VIR_FROM_ESX
|
||||
|
||||
#define ESX_ERROR(conn, code, fmt...) \
|
||||
virReportErrorHelper (conn, VIR_FROM_ESX, code, __FILE__, __FUNCTION__, \
|
||||
virReportErrorHelper(conn, VIR_FROM_ESX, code, __FILE__, __FUNCTION__, \
|
||||
__LINE__, fmt)
|
||||
|
||||
|
||||
@ -583,12 +583,134 @@ esxVMX_GatherSCSIControllers(virConnectPtr conn, virDomainDefPtr def,
|
||||
|
||||
|
||||
|
||||
char *
|
||||
esxVMX_AbsolutePathToDatastoreRelatedPath(virConnectPtr conn,
|
||||
esxVI_Context *ctx,
|
||||
const char *absolutePath)
|
||||
{
|
||||
char *datastoreRelatedPath = NULL;
|
||||
char *preliminaryDatastoreName = NULL;
|
||||
char *directoryAndFileName = NULL;
|
||||
esxVI_DynamicProperty *dynamicProperty = NULL;
|
||||
esxVI_ObjectContent *datastore = NULL;
|
||||
const char *datastoreName = NULL;
|
||||
|
||||
if (sscanf(absolutePath, "/vmfs/volumes/%a[^/]/%a[^\n]",
|
||||
&preliminaryDatastoreName, &directoryAndFileName) != 2) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Absolute path '%s' doesn't have expected format "
|
||||
"'/vmfs/volumes/<datastore>/<path>'", absolutePath);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (ctx != NULL) {
|
||||
if (esxVI_LookupDatastoreByName(conn, ctx, preliminaryDatastoreName,
|
||||
NULL, &datastore,
|
||||
esxVI_Occurence_RequiredItem) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
|
||||
dynamicProperty = dynamicProperty->_next) {
|
||||
if (STREQ(dynamicProperty->name, "info.name")) {
|
||||
if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
|
||||
esxVI_Type_String) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
datastoreName = dynamicProperty->val->string;
|
||||
break;
|
||||
} else if (STREQ(dynamicProperty->name, "info.url")) {
|
||||
/* Ignore it */
|
||||
} else {
|
||||
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (datastoreName == NULL) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Could not retrieve datastore name for absolute path '%s'",
|
||||
absolutePath);
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
datastoreName = preliminaryDatastoreName;
|
||||
}
|
||||
|
||||
if (virAsprintf(&datastoreRelatedPath, "[%s] %s", datastoreName,
|
||||
directoryAndFileName) < 0) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* FIXME: Check if referenced path/file really exists */
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(preliminaryDatastoreName);
|
||||
VIR_FREE(directoryAndFileName);
|
||||
esxVI_ObjectContent_Free(&datastore);
|
||||
|
||||
return datastoreRelatedPath;
|
||||
|
||||
failure:
|
||||
VIR_FREE(datastoreRelatedPath);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* VMX -> Domain XML
|
||||
*/
|
||||
|
||||
char *
|
||||
esxVMX_ParseFileName(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *fileName, const char *datastoreName,
|
||||
const char *directoryName)
|
||||
{
|
||||
char *src = NULL;
|
||||
|
||||
if (STRPREFIX(fileName, "/vmfs/volumes/")) {
|
||||
/* Found absolute path referencing a file inside a datastore */
|
||||
return esxVMX_AbsolutePathToDatastoreRelatedPath(conn, ctx, fileName);
|
||||
} else if (STRPREFIX(fileName, "/")) {
|
||||
/* Found absolute path referencing a file outside a datastore */
|
||||
src = strdup(fileName);
|
||||
|
||||
if (src == NULL) {
|
||||
virReportOOMError(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: Check if referenced path/file really exists */
|
||||
|
||||
return src;
|
||||
} else if (strchr(fileName, '/') != NULL) {
|
||||
/* Found relative path, this is not supported */
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Found relative path '%s' in VMX file, this is not "
|
||||
"supported", fileName);
|
||||
return NULL;
|
||||
} else {
|
||||
/* Found single file name referencing a file inside a datastore */
|
||||
if (virAsprintf(&src, "[%s] %s/%s", datastoreName, directoryName,
|
||||
fileName) < 0) {
|
||||
virReportOOMError(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: Check if referenced path/file really exists */
|
||||
|
||||
return src;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
virDomainDefPtr
|
||||
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
|
||||
const char *datastoreName, const char *directoryName,
|
||||
esxVI_APIVersion apiVersion)
|
||||
{
|
||||
virConfPtr conf = NULL;
|
||||
@ -872,9 +994,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
|
||||
if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
|
||||
VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
|
||||
scsi_virtualDev,
|
||||
scsi_virtualDev, datastoreName, directoryName,
|
||||
&def->disks[def->ndisks]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
@ -884,9 +1006,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
|
||||
if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
|
||||
VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
|
||||
scsi_virtualDev,
|
||||
scsi_virtualDev, datastoreName, directoryName,
|
||||
&def->disks[def->ndisks]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
@ -900,9 +1022,10 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
/* def:disks (ide) */
|
||||
for (controller = 0; controller < 2; ++controller) {
|
||||
for (id = 0; id < 2; ++id) {
|
||||
if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
|
||||
if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
|
||||
VIR_DOMAIN_DISK_BUS_IDE, controller, id,
|
||||
NULL, &def->disks[def->ndisks]) < 0) {
|
||||
NULL, datastoreName, directoryName,
|
||||
&def->disks[def->ndisks]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -911,9 +1034,10 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
|
||||
if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
|
||||
VIR_DOMAIN_DISK_BUS_IDE, controller, id,
|
||||
NULL, &def->disks[def->ndisks]) < 0) {
|
||||
NULL, datastoreName, directoryName,
|
||||
&def->disks[def->ndisks]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -925,8 +1049,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
|
||||
/* def:disks (floppy) */
|
||||
for (controller = 0; controller < 2; ++controller) {
|
||||
if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
|
||||
if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
|
||||
VIR_DOMAIN_DISK_BUS_FDC, controller, -1, NULL,
|
||||
datastoreName, directoryName,
|
||||
&def->disks[def->ndisks]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
@ -976,7 +1101,8 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
def->nserials = 0;
|
||||
|
||||
for (port = 0; port < 4; ++port) {
|
||||
if (esxVMX_ParseSerial(conn, conf, port,
|
||||
if (esxVMX_ParseSerial(conn, ctx, conf, port,
|
||||
datastoreName, directoryName,
|
||||
&def->serials[def->nserials]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
@ -995,7 +1121,8 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
def->nparallels = 0;
|
||||
|
||||
for (port = 0; port < 3; ++port) {
|
||||
if (esxVMX_ParseParallel(conn, conf, port,
|
||||
if (esxVMX_ParseParallel(conn, ctx, conf, port,
|
||||
datastoreName, directoryName,
|
||||
&def->parallels[def->nparallels]) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
@ -1118,9 +1245,10 @@ struct _virDomainDiskDef {
|
||||
};*/
|
||||
|
||||
int
|
||||
esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
int controller, int id, const char *virtualDev,
|
||||
virDomainDiskDefPtr *def)
|
||||
esxVMX_ParseDisk(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int device, int bus, int controller, int id,
|
||||
const char *virtualDev, const char *datastoreName,
|
||||
const char *directoryName, virDomainDiskDefPtr *def)
|
||||
{
|
||||
/*
|
||||
* device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
|
||||
@ -1345,7 +1473,6 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
}
|
||||
|
||||
/* Setup virDomainDiskDef */
|
||||
/* FIXME: Need the datastore name for fileName */
|
||||
if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
|
||||
if (esxUtil_EqualSuffix(fileName, ".vmdk")) {
|
||||
if (deviceType != NULL) {
|
||||
@ -1375,11 +1502,14 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
}
|
||||
|
||||
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
||||
(*def)->src = fileName;
|
||||
(*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
|
||||
datastoreName, directoryName);
|
||||
(*def)->cachemode = writeThrough ? VIR_DOMAIN_DISK_CACHE_WRITETHRU
|
||||
: VIR_DOMAIN_DISK_CACHE_DEFAULT;
|
||||
|
||||
fileName = NULL;
|
||||
if ((*def)->src == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
} else if (esxUtil_EqualSuffix(fileName, ".iso") ||
|
||||
STREQ(deviceType, "atapi-cdrom")) {
|
||||
/*
|
||||
@ -1407,9 +1537,12 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
}
|
||||
|
||||
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
||||
(*def)->src = fileName;
|
||||
(*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
|
||||
datastoreName, directoryName);
|
||||
|
||||
fileName = NULL;
|
||||
if ((*def)->src == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
} else if (esxUtil_EqualSuffix(fileName, ".vmdk")) {
|
||||
/*
|
||||
* This function was called in order to parse a CDROM device, but
|
||||
@ -1441,9 +1574,12 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
}
|
||||
|
||||
(*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
|
||||
(*def)->src = fileName;
|
||||
(*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
|
||||
datastoreName, directoryName);
|
||||
|
||||
fileName = NULL;
|
||||
if ((*def)->src == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
} else if (fileType != NULL && STREQ(fileType, "device")) {
|
||||
(*def)->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
|
||||
(*def)->src = fileName;
|
||||
@ -1695,8 +1831,9 @@ esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
|
||||
virDomainChrDefPtr *def)
|
||||
esxVMX_ParseSerial(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int port, const char *datastoreName,
|
||||
const char *directoryName, virDomainChrDefPtr *def)
|
||||
{
|
||||
int result = 0;
|
||||
char prefix[48] = "";
|
||||
@ -1773,9 +1910,13 @@ esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
|
||||
} else if (STRCASEEQ(fileType, "file")) {
|
||||
(*def)->dstPort = port;
|
||||
(*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
|
||||
(*def)->data.file.path = fileName;
|
||||
(*def)->data.file.path = esxVMX_ParseFileName(conn, ctx, fileName,
|
||||
datastoreName,
|
||||
directoryName);
|
||||
|
||||
fileName = NULL;
|
||||
if ((*def)->data.file.path == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
} else if (STRCASEEQ(fileType, "pipe")) {
|
||||
/*
|
||||
* FIXME: Differences between client/server and VM/application pipes
|
||||
@ -1812,8 +1953,9 @@ esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
|
||||
virDomainChrDefPtr *def)
|
||||
esxVMX_ParseParallel(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int port, const char *datastoreName,
|
||||
const char *directoryName, virDomainChrDefPtr *def)
|
||||
{
|
||||
int result = 0;
|
||||
char prefix[48] = "";
|
||||
@ -1890,9 +2032,13 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
|
||||
} else if (STRCASEEQ(fileType, "file")) {
|
||||
(*def)->dstPort = port;
|
||||
(*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
|
||||
(*def)->data.file.path = fileName;
|
||||
(*def)->data.file.path = esxVMX_ParseFileName(conn, ctx, fileName,
|
||||
datastoreName,
|
||||
directoryName);
|
||||
|
||||
fileName = NULL;
|
||||
if ((*def)->data.file.path == NULL) {
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Expecting VMX entry '%s' to be 'device' or 'file' but "
|
||||
@ -1923,8 +2069,70 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
|
||||
*/
|
||||
|
||||
char *
|
||||
esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
|
||||
esxVI_APIVersion apiVersion)
|
||||
esxVMX_FormatFileName(virConnectPtr conn, esxVI_Context *ctx ATTRIBUTE_UNUSED,
|
||||
const char *src)
|
||||
{
|
||||
char *datastoreName = NULL;
|
||||
char *directoryName = NULL;
|
||||
char *fileName = NULL;
|
||||
char *absolutePath = NULL;
|
||||
|
||||
if (STRPREFIX(src, "[")) {
|
||||
/* Found potential datastore related path */
|
||||
if (esxUtil_ParseDatastoreRelatedPath(conn, src, &datastoreName,
|
||||
&directoryName, &fileName) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (directoryName == NULL) {
|
||||
if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s",
|
||||
datastoreName, fileName) < 0) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s",
|
||||
datastoreName, directoryName, fileName) < 0) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
} else if (STRPREFIX(src, "/")) {
|
||||
/* Found absolute path */
|
||||
absolutePath = strdup(src);
|
||||
|
||||
if (absolutePath == NULL) {
|
||||
virReportOOMError(conn);
|
||||
goto failure;
|
||||
}
|
||||
} else {
|
||||
/* Found relative path, this is not supported */
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Found relative path '%s' in domain XML, this is not "
|
||||
"supported", src);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* FIXME: Check if referenced path/file really exists */
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(fileName);
|
||||
|
||||
return absolutePath;
|
||||
|
||||
failure:
|
||||
VIR_FREE(absolutePath);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDefPtr def, esxVI_APIVersion apiVersion)
|
||||
{
|
||||
int i;
|
||||
int sched_cpu_affinity_length;
|
||||
@ -2086,21 +2294,21 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
|
||||
for (i = 0; i < def->ndisks; ++i) {
|
||||
switch (def->disks[i]->device) {
|
||||
case VIR_DOMAIN_DISK_DEVICE_DISK:
|
||||
if (esxVMX_FormatHardDisk(conn, def->disks[i], &buffer) < 0) {
|
||||
if (esxVMX_FormatHardDisk(conn, ctx, def->disks[i], &buffer) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DISK_DEVICE_CDROM:
|
||||
if (esxVMX_FormatCDROM(conn, def->disks[i], &buffer) < 0) {
|
||||
if (esxVMX_FormatCDROM(conn, ctx, def->disks[i], &buffer) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
|
||||
if (esxVMX_FormatFloppy(conn, def->disks[i], &buffer) < 0) {
|
||||
if (esxVMX_FormatFloppy(conn, ctx, def->disks[i], &buffer) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -2135,14 +2343,14 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
|
||||
|
||||
/* def:serials */
|
||||
for (i = 0; i < def->nserials; ++i) {
|
||||
if (esxVMX_FormatSerial(conn, def->serials[i], &buffer) < 0) {
|
||||
if (esxVMX_FormatSerial(conn, ctx, def->serials[i], &buffer) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
/* def:parallels */
|
||||
for (i = 0; i < def->nparallels; ++i) {
|
||||
if (esxVMX_FormatParallel(conn, def->parallels[i], &buffer) < 0) {
|
||||
if (esxVMX_FormatParallel(conn, ctx, def->parallels[i], &buffer) < 0) {
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
@ -2170,13 +2378,14 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer)
|
||||
esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer)
|
||||
{
|
||||
int controller, id;
|
||||
const char *busName = NULL;
|
||||
const char *entryPrefix = NULL;
|
||||
const char *deviceTypePrefix = NULL;
|
||||
char *fileName = NULL;
|
||||
|
||||
if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
@ -2229,8 +2438,16 @@ esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = esxVMX_FormatFileName(conn, ctx, def->src);
|
||||
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
|
||||
entryPrefix, controller, id, def->src);
|
||||
entryPrefix, controller, id, fileName);
|
||||
|
||||
VIR_FREE(fileName);
|
||||
}
|
||||
|
||||
if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
|
||||
@ -2252,12 +2469,13 @@ esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer)
|
||||
esxVMX_FormatCDROM(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer)
|
||||
{
|
||||
int controller, id;
|
||||
const char *busName = NULL;
|
||||
const char *entryPrefix = NULL;
|
||||
char *fileName = NULL;
|
||||
|
||||
if (def->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
@ -2293,9 +2511,34 @@ esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
||||
virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"cdrom-image\"\n",
|
||||
entryPrefix, controller, id);
|
||||
|
||||
if (def->src != NULL) {
|
||||
if (! esxUtil_EqualSuffix(def->src, ".iso")) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Image file for %s cdrom '%s' has unsupported "
|
||||
"suffix, expecting '.iso'", busName, def->dst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = esxVMX_FormatFileName(conn, ctx, def->src);
|
||||
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
|
||||
entryPrefix, controller, id, fileName);
|
||||
|
||||
VIR_FREE(fileName);
|
||||
}
|
||||
} else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
||||
virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"atapi-cdrom\"\n",
|
||||
entryPrefix, controller, id);
|
||||
|
||||
if (def->src != NULL) {
|
||||
virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
|
||||
entryPrefix, controller, id, def->src);
|
||||
}
|
||||
} else {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"%s cdrom '%s' has unsupported type '%s', expecting '%s' "
|
||||
@ -2306,29 +2549,17 @@ esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (def->src != NULL) {
|
||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
||||
! esxUtil_EqualSuffix(def->src, ".iso")) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Image file for %s cdrom '%s' has unsupported suffix, "
|
||||
"expecting '.iso'", busName, def->dst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
|
||||
entryPrefix, controller, id, def->src);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer)
|
||||
esxVMX_FormatFloppy(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer)
|
||||
{
|
||||
int controller;
|
||||
char *fileName = NULL;
|
||||
|
||||
if (def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
|
||||
@ -2344,9 +2575,34 @@ esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
||||
virBufferVSprintf(buffer, "floppy%d.fileType = \"file\"\n",
|
||||
controller);
|
||||
|
||||
if (def->src != NULL) {
|
||||
if (! esxUtil_EqualSuffix(def->src, ".flp")) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Image file for floppy '%s' has unsupported suffix, "
|
||||
"expecting '.flp'", def->dst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = esxVMX_FormatFileName(conn, ctx, def->src);
|
||||
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
|
||||
controller, fileName);
|
||||
|
||||
VIR_FREE(fileName);
|
||||
}
|
||||
} else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
||||
virBufferVSprintf(buffer, "floppy%d.fileType = \"device\"\n",
|
||||
controller);
|
||||
|
||||
if (def->src != NULL) {
|
||||
virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
|
||||
controller, def->src);
|
||||
}
|
||||
} else {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Floppy '%s' has unsupported type '%s', expecting '%s' "
|
||||
@ -2357,19 +2613,6 @@ esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (def->src != NULL) {
|
||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE &&
|
||||
! esxUtil_EqualSuffix(def->src, ".flp")) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Image file for floppy '%s' has unsupported suffix, "
|
||||
"expecting '.flp'", def->dst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n", controller,
|
||||
def->src);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2433,17 +2676,12 @@ esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
|
||||
|
||||
virFormatMacAddr(def->mac, mac_string);
|
||||
|
||||
if (def->mac[0] == 0x00 && def->mac[1] == 0x0c && def->mac[2] == 0x29) {
|
||||
if ((def->mac[0] == 0x00 && def->mac[1] == 0x0c && def->mac[2] == 0x29) ||
|
||||
(def->mac[0] == 0x00 && def->mac[1] == 0x50 && def->mac[2] == 0x56)) {
|
||||
virBufferVSprintf(buffer, "ethernet%d.addressType = \"generated\"\n",
|
||||
controller);
|
||||
virBufferVSprintf(buffer, "ethernet%d.generatedAddress = \"%s\"\n",
|
||||
controller, mac_string);
|
||||
} else if (def->mac[0] == 0x00 && def->mac[1] == 0x50 &&
|
||||
def->mac[2] == 0x56) {
|
||||
virBufferVSprintf(buffer, "ethernet%d.addressType = \"static\"\n",
|
||||
controller);
|
||||
virBufferVSprintf(buffer, "ethernet%d.address = \"%s\"\n",
|
||||
controller, mac_string);
|
||||
} else {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Unsupported MAC address prefix '%02X:%02X:%02X', expecting "
|
||||
@ -2458,9 +2696,11 @@ esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
virBufferPtr buffer)
|
||||
esxVMX_FormatSerial(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainChrDefPtr def, virBufferPtr buffer)
|
||||
{
|
||||
char *fileName = NULL;
|
||||
|
||||
if (def->dstPort < 0 || def->dstPort > 3) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Serial port index %d out of [0..3] range", def->dstPort);
|
||||
@ -2476,16 +2716,29 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
|
||||
virBufferVSprintf(buffer, "serial%d.present = \"true\"\n", def->dstPort);
|
||||
|
||||
/* def:type -> vmx:fileType */
|
||||
/* def:type -> vmx:fileType and def:data.file.path -> vmx:fileName */
|
||||
switch (def->type) {
|
||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||
virBufferVSprintf(buffer, "serial%d.fileType = \"device\"\n",
|
||||
def->dstPort);
|
||||
virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
|
||||
def->dstPort, def->data.file.path);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||
virBufferVSprintf(buffer, "serial%d.fileType = \"file\"\n",
|
||||
def->dstPort);
|
||||
|
||||
fileName = esxVMX_FormatFileName(conn, ctx, def->data.file.path);
|
||||
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
|
||||
def->dstPort, fileName);
|
||||
|
||||
VIR_FREE(fileName);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TYPE_PIPE:
|
||||
@ -2497,6 +2750,8 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
/* FIXME: Based on VI Client GUI default */
|
||||
virBufferVSprintf(buffer, "serial%d.tryNoRxLoss = \"false\"\n",
|
||||
def->dstPort);
|
||||
virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
|
||||
def->dstPort, def->data.file.path);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2506,10 +2761,6 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* def:data.file.path -> vmx:fileName */
|
||||
virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
|
||||
def->dstPort, def->data.file.path);
|
||||
|
||||
/* vmx:yieldOnMsrRead */
|
||||
/* FIXME: Based on VI Client GUI default */
|
||||
virBufferVSprintf(buffer, "serial%d.yieldOnMsrRead = \"true\"\n",
|
||||
@ -2521,9 +2772,11 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
|
||||
|
||||
int
|
||||
esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
virBufferPtr buffer)
|
||||
esxVMX_FormatParallel(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainChrDefPtr def, virBufferPtr buffer)
|
||||
{
|
||||
char *fileName = NULL;
|
||||
|
||||
if (def->dstPort < 0 || def->dstPort > 2) {
|
||||
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"Parallel port index %d out of [0..2] range", def->dstPort);
|
||||
@ -2539,16 +2792,29 @@ esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
|
||||
virBufferVSprintf(buffer, "parallel%d.present = \"true\"\n", def->dstPort);
|
||||
|
||||
/* def:type -> vmx:fileType */
|
||||
/* def:type -> vmx:fileType and def:data.file.path -> vmx:fileName */
|
||||
switch (def->type) {
|
||||
case VIR_DOMAIN_CHR_TYPE_DEV:
|
||||
virBufferVSprintf(buffer, "parallel%d.fileType = \"device\"\n",
|
||||
def->dstPort);
|
||||
virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
|
||||
def->dstPort, def->data.file.path);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TYPE_FILE:
|
||||
virBufferVSprintf(buffer, "parallel%d.fileType = \"file\"\n",
|
||||
def->dstPort);
|
||||
|
||||
fileName = esxVMX_FormatFileName(conn, ctx, def->data.file.path);
|
||||
|
||||
if (fileName == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
|
||||
def->dstPort, fileName);
|
||||
|
||||
VIR_FREE(fileName);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2558,9 +2824,5 @@ esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* def:data.file.path -> vmx:fileName */
|
||||
virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
|
||||
def->dstPort, def->data.file.path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,9 +34,11 @@ esxVMX_IndexToDiskName(virConnectPtr conn, int idx, const char *prefix);
|
||||
int
|
||||
esxVMX_SCSIDiskNameToControllerAndID(virConnectPtr conn, const char *name,
|
||||
int *controller, int *id);
|
||||
|
||||
int
|
||||
esxVMX_IDEDiskNameToControllerAndID(virConnectPtr conn, const char *name,
|
||||
int *controller, int *id);
|
||||
|
||||
int
|
||||
esxVMX_FloppyDiskNameToController(virConnectPtr conn, const char *name,
|
||||
int *controller);
|
||||
@ -45,14 +47,24 @@ int
|
||||
esxVMX_GatherSCSIControllers(virConnectPtr conn, virDomainDefPtr conf,
|
||||
char *virtualDev[4], int present[4]);
|
||||
|
||||
char *
|
||||
esxVMX_AbsolutePathToDatastoreRelatedPath(virConnectPtr conn,
|
||||
esxVI_Context *ctx,
|
||||
const char *absolutePath);
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* VMX -> Domain XML
|
||||
*/
|
||||
|
||||
char *
|
||||
esxVMX_ParseFileName(virConnectPtr conn, esxVI_Context *ctx,
|
||||
const char *fileName, const char *datastoreName,
|
||||
const char *directoryName);
|
||||
|
||||
virDomainDefPtr
|
||||
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
|
||||
esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
|
||||
const char *datastoreName, const char *directoryName,
|
||||
esxVI_APIVersion apiVersion);
|
||||
|
||||
int
|
||||
@ -60,20 +72,23 @@ esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
|
||||
int controller, int *present, char **virtualDev);
|
||||
|
||||
int
|
||||
esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
|
||||
int controller, int id, const char *virtualDev,
|
||||
virDomainDiskDefPtr *def);
|
||||
esxVMX_ParseDisk(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int device, int bus, int controller, int id,
|
||||
const char *virtualDev, const char *datastoreName,
|
||||
const char *directoryName, virDomainDiskDefPtr *def);
|
||||
int
|
||||
esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
|
||||
virDomainNetDefPtr *def);
|
||||
|
||||
int
|
||||
esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
|
||||
virDomainChrDefPtr *def);
|
||||
esxVMX_ParseSerial(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int port, const char *datastoreName,
|
||||
const char *directoryName, virDomainChrDefPtr *def);
|
||||
|
||||
int
|
||||
esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
|
||||
virDomainChrDefPtr *def);
|
||||
esxVMX_ParseParallel(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
|
||||
int port, const char *datastoreName,
|
||||
const char *directoryName, virDomainChrDefPtr *def);
|
||||
|
||||
|
||||
|
||||
@ -82,31 +97,34 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
|
||||
*/
|
||||
|
||||
char *
|
||||
esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
|
||||
esxVI_APIVersion apiVersion);
|
||||
esxVMX_FormatFileName(virConnectPtr conn, esxVI_Context *ctx, const char *src);
|
||||
|
||||
char *
|
||||
esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDefPtr def, esxVI_APIVersion apiVersion);
|
||||
|
||||
int
|
||||
esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer);
|
||||
esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer);
|
||||
|
||||
int
|
||||
esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer);
|
||||
esxVMX_FormatCDROM(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer);
|
||||
|
||||
int
|
||||
esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
|
||||
virBufferPtr buffer);
|
||||
esxVMX_FormatFloppy(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainDiskDefPtr def, virBufferPtr buffer);
|
||||
|
||||
int
|
||||
esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
|
||||
int controller, virBufferPtr buffer);
|
||||
|
||||
int
|
||||
esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
virBufferPtr buffer);
|
||||
esxVMX_FormatSerial(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainChrDefPtr def, virBufferPtr buffer);
|
||||
|
||||
int
|
||||
esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
|
||||
virBufferPtr buffer);
|
||||
esxVMX_FormatParallel(virConnectPtr conn, esxVI_Context *ctx,
|
||||
virDomainChrDefPtr def, virBufferPtr buffer);
|
||||
|
||||
#endif /* __ESX_VMX_H__ */
|
||||
|
@ -9,15 +9,21 @@
|
||||
#include "internal.h"
|
||||
#include "memory.h"
|
||||
#include "testutils.h"
|
||||
#include "esx/esx_util.h"
|
||||
#include "esx/esx_vmx.h"
|
||||
|
||||
static char *progname;
|
||||
|
||||
struct testInfo {
|
||||
const char *input;
|
||||
const char *output;
|
||||
esxVI_APIVersion version;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
testQuietError(void *userData ATTRIBUTE_UNUSED,
|
||||
virErrorPtr error ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char* names[] = {
|
||||
"sda", "sdb", "sdc", "sdd", "sde", "sdf", "sdg", "sdh", "sdi", "sdj", "sdk", "sdl", "sdm", "sdn", "sdo", "sdp", "sdq", "sdr", "sds", "sdt", "sdu", "sdv", "sdw", "sdx", "sdy", "sdz",
|
||||
@ -62,6 +68,80 @@ testIndexToDiskName(const void *data ATTRIBUTE_UNUSED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct testPath {
|
||||
const char *datastoreRelatedPath;
|
||||
int result;
|
||||
const char *datastoreName;
|
||||
const char *directoryName;
|
||||
const char *fileName;
|
||||
};
|
||||
|
||||
static struct testPath paths[] = {
|
||||
{ "[datastore] directory/file", 0, "datastore", "directory", "file" },
|
||||
{ "[datastore] file", 0, "datastore", NULL, "file" },
|
||||
{ "[] directory/file", -1, NULL, NULL, NULL },
|
||||
{ "[datastore] directory/", -1, NULL, NULL, NULL },
|
||||
{ "directory/file", -1, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i, result = 0;
|
||||
char *datastoreName = NULL;
|
||||
char *directoryName = NULL;
|
||||
char *fileName = NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_CARDINALITY(paths); ++i) {
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(fileName);
|
||||
|
||||
if (esxUtil_ParseDatastoreRelatedPath(NULL,
|
||||
paths[i].datastoreRelatedPath,
|
||||
&datastoreName, &directoryName,
|
||||
&fileName) != paths[i].result) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (paths[i].result < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (STRNEQ(paths[i].datastoreName, datastoreName)) {
|
||||
virtTestDifference(stderr, paths[i].datastoreName, datastoreName);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (paths[i].directoryName != NULL &&
|
||||
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);
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(fileName);
|
||||
|
||||
return result;
|
||||
|
||||
failure:
|
||||
result = -1;
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
mymain(int argc, char **argv)
|
||||
{
|
||||
@ -79,10 +159,18 @@ mymain(int argc, char **argv)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (virtTestRun("VMware IndexToDiskName", 1, testIndexToDiskName,
|
||||
NULL) < 0) {
|
||||
result = -1;
|
||||
}
|
||||
virSetErrorFunc(NULL, testQuietError);
|
||||
|
||||
#define DO_TEST(_name) \
|
||||
do { \
|
||||
if (virtTestRun("VMware "#_name, 1, test##_name, \
|
||||
NULL) < 0) { \
|
||||
result = -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
DO_TEST(IndexToDiskName);
|
||||
DO_TEST(ParseDatastoreRelatedPath);
|
||||
|
||||
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='cdrom.iso'/>
|
||||
<source file='[datastore] directory/cdrom.iso'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='cdrom.iso'/>
|
||||
<source file='[datastore] directory/cdrom.iso'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='Fedora11.vmdk'/>
|
||||
<source file='[datastore] directory/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -14,12 +14,12 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic' cache='writethrough'/>
|
||||
<source file='Debian1.vmdk'/>
|
||||
<source file='[datastore] directory/Debian1.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='buslogic'/>
|
||||
<source file='Debian1-cdrom.iso'/>
|
||||
<source file='[datastore] directory/Debian1-cdrom.iso'/>
|
||||
<target dev='sdp' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
@ -31,7 +31,7 @@
|
||||
<target dev='hdb' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian1-IDE.vmdk'/>
|
||||
<source file='[datastore] directory/Debian1-IDE.vmdk'/>
|
||||
<target dev='hdd' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='block' device='floppy'>
|
||||
|
@ -14,15 +14,15 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='Debian2.vmdk'/>
|
||||
<source file='[datastore] directory/Debian2.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/dummy.flp'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/>
|
||||
<target dev='fdb' bus='fdc'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='virtMonServ1.vmdk'/>
|
||||
<source file='[datastore] directory/virtMonServ1.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
@ -26,15 +26,15 @@
|
||||
<source bridge='VM Switch 2'/>
|
||||
</interface>
|
||||
<serial type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<parallel type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/parallel1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/parallel1.file'/>
|
||||
<target port='0'/>
|
||||
</parallel>
|
||||
<console type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
</devices>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='floppy.flp'/>
|
||||
<source file='[datastore] directory/floppy.flp'/>
|
||||
<target dev='fda' bus='fdc'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl2.vmdk'/>
|
||||
<source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl3.vmdk'/>
|
||||
<source file='[datastore] directory/Debian-System1-0-cl3.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl1.vmdk'/>
|
||||
<source file='[datastore] directory/Debian-System1-0-cl1.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl2.vmdk'/>
|
||||
<source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<parallel type='file'>
|
||||
<source path='parallel0.file'/>
|
||||
<source path='[datastore] directory/parallel0.file'/>
|
||||
<target port='0'/>
|
||||
</parallel>
|
||||
</devices>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='buslogic'/>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='buslogic' cache='writethrough'/>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -12,11 +12,11 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<serial type='file'>
|
||||
<source path='serial0.file'/>
|
||||
<source path='[datastore] directory/serial0.file'/>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<console type='file'>
|
||||
<source path='serial0.file'/>
|
||||
<source path='[datastore] directory/serial0.file'/>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
</devices>
|
||||
|
@ -35,7 +35,8 @@ testCompareFiles(const char *vmx, const char *xml, esxVI_APIVersion apiVersion)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
def = esxVMX_ParseConfig(NULL, vmxData, apiVersion);
|
||||
def = esxVMX_ParseConfig(NULL, NULL, vmxData, "datastore", "directory",
|
||||
apiVersion);
|
||||
|
||||
if (def == NULL) {
|
||||
goto failure;
|
||||
|
@ -7,4 +7,4 @@ memsize = "4"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "cdrom-image"
|
||||
ide0:0.fileName = "cdrom.iso"
|
||||
ide0:0.fileName = "/vmfs/volumes/testing/isos/cdrom.iso"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='cdrom.iso'/>
|
||||
<source file='[testing] isos/cdrom.iso'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -8,4 +8,4 @@ numvcpus = "1"
|
||||
scsi0.present = "true"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "cdrom-image"
|
||||
scsi0:0.fileName = "cdrom.iso"
|
||||
scsi0:0.fileName = "/vmfs/volumes/testing/isos/cdrom.iso"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='cdrom.iso'/>
|
||||
<source file='[testing] isos/cdrom.iso'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -9,9 +9,9 @@ scsi0.present = "true"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "Fedora11.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Fedora11/Fedora11.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "bridged"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:91:48:C7"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.generatedAddress = "00:50:56:91:48:C7"
|
||||
|
@ -14,7 +14,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='Fedora11.vmdk'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Fedora11/Fedora11.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -13,11 +13,11 @@ scsi1.present = "true"
|
||||
scsi1.virtualDev = "buslogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "Debian1.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1.vmdk"
|
||||
scsi0:0.writeThrough = "true"
|
||||
scsi1:0.present = "true"
|
||||
scsi1:0.deviceType = "cdrom-image"
|
||||
scsi1:0.fileName = "Debian1-cdrom.iso"
|
||||
scsi1:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1-cdrom.iso"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "cdrom-image"
|
||||
ide0:0.fileName = "/vmimages/tools-isoimages/linux.iso"
|
||||
@ -26,7 +26,7 @@ ide0:1.deviceType = "atapi-cdrom"
|
||||
ide0:1.fileName = "/dev/scd0"
|
||||
ide1:1.present = "true"
|
||||
ide1:1.deviceType = "ata-hardDisk"
|
||||
ide1:1.fileName = "Debian1-IDE.vmdk"
|
||||
ide1:1.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1-IDE.vmdk"
|
||||
floppy0.present = "true"
|
||||
floppy0.fileType = "device"
|
||||
floppy0.fileName = "/dev/fd0"
|
||||
|
@ -14,12 +14,12 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic' cache='writethrough'/>
|
||||
<source file='Debian1.vmdk'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='buslogic'/>
|
||||
<source file='Debian1-cdrom.iso'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1-cdrom.iso'/>
|
||||
<target dev='sdp' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
@ -31,7 +31,7 @@
|
||||
<target dev='hdb' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian1-IDE.vmdk'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1-IDE.vmdk'/>
|
||||
<target dev='hdd' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='block' device='floppy'>
|
||||
|
@ -10,7 +10,7 @@ scsi0.present = "true"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "Debian2.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/Debian2.vmdk"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "cdrom-image"
|
||||
ide0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso"
|
||||
|
@ -14,15 +14,15 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='Debian2.vmdk'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/Debian2.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/dummy.flp'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/>
|
||||
<target dev='fdb' bus='fdc'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -9,17 +9,17 @@ scsi0.present = "true"
|
||||
scsi0.virtualDev = "lsilogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "virtMonServ1.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/virtMonServ1.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "bridged"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:91:66:D4"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.generatedAddress = "00:50:56:91:66:D4"
|
||||
ethernet1.present = "true"
|
||||
ethernet1.networkName = "VM Switch 2"
|
||||
ethernet1.connectionType = "bridged"
|
||||
ethernet1.addressType = "static"
|
||||
ethernet1.address = "00:50:56:91:0C:51"
|
||||
ethernet1.addressType = "generated"
|
||||
ethernet1.generatedAddress = "00:50:56:91:0C:51"
|
||||
serial0.present = "true"
|
||||
serial0.fileType = "file"
|
||||
serial0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file"
|
||||
|
@ -14,7 +14,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='lsilogic'/>
|
||||
<source file='virtMonServ1.vmdk'/>
|
||||
<source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/virtMonServ1.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
@ -26,15 +26,15 @@
|
||||
<source bridge='VM Switch 2'/>
|
||||
</interface>
|
||||
<serial type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
<parallel type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/parallel1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/parallel1.file'/>
|
||||
<target port='0'/>
|
||||
</parallel>
|
||||
<console type='file'>
|
||||
<source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
|
||||
<source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
|
||||
<target port='0'/>
|
||||
</console>
|
||||
</devices>
|
||||
|
@ -8,5 +8,5 @@ numvcpus = "1"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "bridged"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:11:22:33"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.generatedAddress = "00:50:56:11:22:33"
|
||||
|
@ -9,5 +9,5 @@ ethernet0.present = "true"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "custom"
|
||||
ethernet0.vnet = "vmnet7"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:11:22:33"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.generatedAddress = "00:50:56:11:22:33"
|
||||
|
@ -9,5 +9,5 @@ ethernet0.present = "true"
|
||||
ethernet0.virtualDev = "e1000"
|
||||
ethernet0.networkName = "VM Network"
|
||||
ethernet0.connectionType = "bridged"
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:50:56:11:22:33"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.generatedAddress = "00:50:56:11:22:33"
|
||||
|
@ -7,4 +7,4 @@ memsize = "4"
|
||||
numvcpus = "1"
|
||||
floppy0.present = "true"
|
||||
floppy0.fileType = "file"
|
||||
floppy0.fileName = "floppy.flp"
|
||||
floppy0.fileName = "/vmfs/volumes/testing/floppy.flp"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='floppy.flp'/>
|
||||
<source file='[testing] floppy.flp'/>
|
||||
<target dev='fda' bus='fdc'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -7,7 +7,7 @@ memsize = "32"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "ata-hardDisk"
|
||||
ide0:0.fileName = "Debian-System1-0-cl2.vmdk"
|
||||
ide0:0.fileName = "/vmfs/volumes/storage/Server1/Debian-System1-0-cl2.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "net1"
|
||||
ethernet0.connectionType = "custom"
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl2.vmdk'/>
|
||||
<source file='[storage] Server1/Debian-System1-0-cl2.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -7,7 +7,7 @@ memsize = "32"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "ata-hardDisk"
|
||||
ide0:0.fileName = "Debian-System1-0-cl3.vmdk"
|
||||
ide0:0.fileName = "/vmfs/volumes/storage/Server2/Debian-System1-0-cl3.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "net1"
|
||||
ethernet0.connectionType = "custom"
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl3.vmdk'/>
|
||||
<source file='[storage] Server2/Debian-System1-0-cl3.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -7,7 +7,7 @@ memsize = "32"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "ata-hardDisk"
|
||||
ide0:0.fileName = "Debian-System1-0-cl1.vmdk"
|
||||
ide0:0.fileName = "/vmfs/volumes/storage/Router/Debian-System1-0-cl1.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "net1"
|
||||
ethernet0.connectionType = "custom"
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl1.vmdk'/>
|
||||
<source file='[storage] Router/Debian-System1-0-cl1.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -7,7 +7,7 @@ memsize = "264"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "ata-hardDisk"
|
||||
ide0:0.fileName = "Debian-System1-0-cl2.vmdk"
|
||||
ide0:0.fileName = "/vmfs/volumes/storage/Client/Debian-System1-0-cl2.vmdk"
|
||||
ethernet0.present = "true"
|
||||
ethernet0.networkName = "net2"
|
||||
ethernet0.connectionType = "custom"
|
||||
|
@ -13,7 +13,7 @@
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='Debian-System1-0-cl2.vmdk'/>
|
||||
<source file='[storage] Client/Debian-System1-0-cl2.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
|
@ -7,4 +7,4 @@ memsize = "4"
|
||||
numvcpus = "1"
|
||||
ide0:0.present = "true"
|
||||
ide0:0.deviceType = "ata-hardDisk"
|
||||
ide0:0.fileName = "harddisk.vmdk"
|
||||
ide0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='hda' bus='ide'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -8,4 +8,4 @@ numvcpus = "1"
|
||||
scsi0.present = "true"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "harddisk.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -7,4 +7,4 @@ memsize = "4"
|
||||
numvcpus = "1"
|
||||
parallel0.present = "true"
|
||||
parallel0.fileType = "file"
|
||||
parallel0.fileName = "parallel0.file"
|
||||
parallel0.fileName = "/vmfs/volumes/datastore/directory/parallel0.file"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<parallel type='file'>
|
||||
<source path='parallel0.file'/>
|
||||
<source path='[datastore] directory/parallel0.file'/>
|
||||
<target port='0'/>
|
||||
</parallel>
|
||||
</devices>
|
||||
|
@ -9,4 +9,4 @@ scsi0.present = "true"
|
||||
scsi0.virtualDev = "buslogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "harddisk.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
|
||||
|
@ -8,7 +8,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='buslogic'/>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -9,5 +9,5 @@ scsi0.present = "true"
|
||||
scsi0.virtualDev = "buslogic"
|
||||
scsi0:0.present = "true"
|
||||
scsi0:0.deviceType = "scsi-hardDisk"
|
||||
scsi0:0.fileName = "harddisk.vmdk"
|
||||
scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
|
||||
scsi0:0.writeThrough = "true"
|
||||
|
@ -8,7 +8,7 @@
|
||||
<devices>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='buslogic' cache='writethrough'/>
|
||||
<source file='harddisk.vmdk'/>
|
||||
<source file='[datastore] directory/harddisk.vmdk'/>
|
||||
<target dev='sda' bus='scsi'/>
|
||||
</disk>
|
||||
</devices>
|
||||
|
@ -7,5 +7,5 @@ memsize = "4"
|
||||
numvcpus = "1"
|
||||
serial0.present = "true"
|
||||
serial0.fileType = "file"
|
||||
serial0.fileName = "serial0.file"
|
||||
serial0.fileName = "/vmfs/volumes/datastore/directory/serial0.file"
|
||||
serial0.yieldOnMsrRead = "true"
|
||||
|
@ -7,7 +7,7 @@
|
||||
</os>
|
||||
<devices>
|
||||
<serial type='file'>
|
||||
<source path='serial0.file'/>
|
||||
<source path='[datastore] directory/serial0.file'/>
|
||||
<target port='0'/>
|
||||
</serial>
|
||||
</devices>
|
||||
|
@ -89,7 +89,7 @@ testCompareFiles(const char *xml, const char *vmx, esxVI_APIVersion apiVersion)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
formatted = esxVMX_FormatConfig(NULL, def, apiVersion);
|
||||
formatted = esxVMX_FormatConfig(NULL, NULL, def, apiVersion);
|
||||
|
||||
if (formatted == NULL) {
|
||||
goto failure;
|
||||
|
Loading…
Reference in New Issue
Block a user