提交 f66d5745 编写于 作者: M Matthias Bolte

esx: Add automatic question handling

Questions can block tasks, to handle them automatically the driver can answers
them with the default answer. The auto_answer query parameter allows to enable
this automatic question handling.

* src/esx/README: add a detailed explanation for automatic question handling
* src/esx/esx_driver.c: add automatic question handling for all task related
  driver functions
* src/esx/esx_util.[ch]: add handling for the auto_answer query parameter
* src/esx/esx_vi.[ch], src/esx/esx_vi_methods.[ch], src/esx/esx_vi_types.[ch]:
  add new VI API methods and types and additional helper functions for
  automatic question handling
上级 1c5c6333
Some links to relevant documentation
====================================
VI API reference: http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/
VMX config: http://www.sanbarrow.com/vmx.html
CPUID: http://www.sandpile.org/ia32/cpuid.htm
Memory model: http://www.vmware.com/pdf/esx3_memory.pdf
Automatic question handling
===========================
What is a question in the ESX context?
--------------------------------------
The VI API contains calls that start tasks, for example PowerOnVM_Task(). Such
tasks may be blocked by a question if the ESX host detects an issue with the
virtual machine that requires user interaction.
An example: If a virtual machine has a serial port that is realized via a file,
the ESX host will ask a question on power-on of this virtual machine whether
new content should be appended to this file or the file should be replaced.
Until this question is answered the power-on task is blocked and the virtual
machine won't get powered on.
The ESX driver cannot prompt the user to answer a question, libvirt doesn't
have an API for something like this. The VI API provides a AnswerVM() method to
programmatically answer such questions. A question comes together with a list
of possible answers. One of this answers is marked as the default one. For all
questions I've seen so far the default answer is always a non-destructive one.
There are two options how to handle a question that is blocking a task: either
answer it automatically or report it as error and try to cancel the blocked
task.
The auto_answer query parameter defines how the driver should handle questions.
Possible values are 0 for the report-error-and-try-to-cancel option and 1 for
the automatic-answer option.
How is automatic question handling implemented?
-----------------------------------------------
Before any new task is started the driver checks if there is a pending task
blocked by a question. If automatic question handling is disabled the driver
reports an error that includes the question and returns from the driver
function. If automatic question handling is enabled the driver answers the
question with the default answer and returns from the driver function.
In both cases the actual desired task is not started. If the question was not
answered the blocked task is still blocked and because task can't be executed
in parallel in general it's of no use to start yet another task. If the
question was answered the blocked task may already perform the desired action
and one must wait for its completion, so it's of no use to start yet another
task.
If there is no question blocking a task or another pending task that had not
finished yet the driver starts the desired task and waits for its completion.
While polling for status updates of the task it also checks for question that
may have been triggered by the current task and handles them according to the
value of the auto_answer query parameter. If automatic question handling is
enabled the driver answers the question with the default answer and continues
polling for status updates. If automatic question handling is disabled the
driver reports an error that includes the question, tries to cancel the blocked
task and returns from the driver function.
It tries to cancel the blocked task, but this may not be possible, because
there are task like the power-on task that is marked as non-cancelable. So the
driver may leave blocked tasks behind if automatic question handling is
disabled.
...@@ -21,15 +21,6 @@ ...@@ -21,15 +21,6 @@
* *
*/ */
/*
* Some links to relevant documentation:
*
* - Memory model: http://www.vmware.com/pdf/esx3_memory.pdf
* - VI API reference: http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/
* - VMX-file parameters: http://www.sanbarrow.com/vmx.html
* - CPUID: http://www.sandpile.org/ia32/cpuid.htm
*/
#include <config.h> #include <config.h>
#include <netdb.h> #include <netdb.h>
...@@ -63,6 +54,7 @@ typedef struct _esxPrivate { ...@@ -63,6 +54,7 @@ typedef struct _esxPrivate {
int32_t maxVcpus; int32_t maxVcpus;
esxVI_Boolean supportsVMotion; esxVI_Boolean supportsVMotion;
esxVI_Boolean supportsLongMode; /* aka x86_64 */ esxVI_Boolean supportsLongMode; /* aka x86_64 */
esxVI_Boolean autoAnswer;
int32_t usedCpuTimeCounterId; int32_t usedCpuTimeCounterId;
} esxPrivate; } esxPrivate;
...@@ -242,7 +234,7 @@ esxCapsInit(virConnectPtr conn) ...@@ -242,7 +234,7 @@ esxCapsInit(virConnectPtr conn)
/* /*
* URI format: {esx|gsx}://[<user>@]<server>[:<port>][?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}] * URI format: {esx|gsx}://[<user>@]<server>[:<port>][?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}][&auto_answer={0|1}]
* *
* If no port is specified the default port is set dependent on the scheme and * If no port is specified the default port is set dependent on the scheme and
* transport parameter: * transport parameter:
...@@ -258,6 +250,10 @@ esxCapsInit(virConnectPtr conn) ...@@ -258,6 +250,10 @@ esxCapsInit(virConnectPtr conn)
* *
* If the no_verify parameter is set to 1, this disables libcurl client checks * If the no_verify parameter is set to 1, this disables libcurl client checks
* of the server's certificate. The default value it 0. * of the server's certificate. The default value it 0.
*
* If the auto_answer parameter is set to 1, the driver will respond to all
* virtual machine questions with the default answer, otherwise virtual machine
* questions will be reported as errors. The default value it 0.
*/ */
static virDrvOpenStatus static virDrvOpenStatus
esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
...@@ -268,6 +264,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) ...@@ -268,6 +264,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
char *url = NULL; char *url = NULL;
char *vCenter = NULL; char *vCenter = NULL;
int noVerify = 0; // boolean int noVerify = 0; // boolean
int autoAnswer = 0; // boolean
char *username = NULL; char *username = NULL;
char *password = NULL; char *password = NULL;
...@@ -296,13 +293,19 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) ...@@ -296,13 +293,19 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
priv->maxVcpus = -1; priv->maxVcpus = -1;
priv->supportsVMotion = esxVI_Boolean_Undefined; priv->supportsVMotion = esxVI_Boolean_Undefined;
priv->supportsLongMode = esxVI_Boolean_Undefined; priv->supportsLongMode = esxVI_Boolean_Undefined;
priv->autoAnswer = esxVI_Boolean_False;
priv->usedCpuTimeCounterId = -1; priv->usedCpuTimeCounterId = -1;
/* Request credentials and login to host/vCenter */ if (esxUtil_ParseQuery(conn, &priv->transport, &vCenter, &noVerify,
if (esxUtil_ParseQuery(conn, &priv->transport, &vCenter, &noVerify) < 0) { &autoAnswer) < 0) {
goto failure; goto failure;
} }
if (autoAnswer) {
priv->autoAnswer = esxVI_Boolean_True;
}
/* Request credentials and login to host/vCenter */
if (esxUtil_ResolveHostname(conn, conn->uri->server, hostIpAddress, if (esxUtil_ResolveHostname(conn, conn->uri->server, hostIpAddress,
NI_MAXHOST) < 0) { NI_MAXHOST) < 0) {
goto failure; goto failure;
...@@ -1360,10 +1363,9 @@ esxDomainSuspend(virDomainPtr domain) ...@@ -1360,10 +1363,9 @@ esxDomainSuspend(virDomainPtr domain)
if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
"runtime.powerState") < 0 || "runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, propertyNameList, (domain->conn, priv->host, domain->uuid, propertyNameList,
&virtualMachine, &virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine, esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine,
&powerState) < 0) { &powerState) < 0) {
goto failure; goto failure;
...@@ -1378,6 +1380,7 @@ esxDomainSuspend(virDomainPtr domain) ...@@ -1378,6 +1380,7 @@ esxDomainSuspend(virDomainPtr domain)
if (esxVI_SuspendVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_SuspendVM_Task(domain->conn, priv->host, virtualMachine->obj,
&task) < 0 || &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -1420,10 +1423,9 @@ esxDomainResume(virDomainPtr domain) ...@@ -1420,10 +1423,9 @@ esxDomainResume(virDomainPtr domain)
if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
"runtime.powerState") < 0 || "runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, propertyNameList, (domain->conn, priv->host, domain->uuid, propertyNameList,
&virtualMachine, &virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine, esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine,
&powerState) < 0) { &powerState) < 0) {
goto failure; goto failure;
...@@ -1438,6 +1440,7 @@ esxDomainResume(virDomainPtr domain) ...@@ -1438,6 +1440,7 @@ esxDomainResume(virDomainPtr domain)
if (esxVI_PowerOnVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_PowerOnVM_Task(domain->conn, priv->host, virtualMachine->obj,
&task) < 0 || &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -1577,10 +1580,9 @@ esxDomainDestroy(virDomainPtr domain) ...@@ -1577,10 +1580,9 @@ esxDomainDestroy(virDomainPtr domain)
if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
"runtime.powerState") < 0 || "runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, propertyNameList, (domain->conn, priv->host, domain->uuid, propertyNameList,
&virtualMachine, &virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine, esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine,
&powerState) < 0) { &powerState) < 0) {
goto failure; goto failure;
...@@ -1595,6 +1597,7 @@ esxDomainDestroy(virDomainPtr domain) ...@@ -1595,6 +1597,7 @@ esxDomainDestroy(virDomainPtr domain)
if (esxVI_PowerOffVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_PowerOffVM_Task(domain->conn, priv->host, virtualMachine->obj,
&task) < 0 || &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -1707,10 +1710,9 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) ...@@ -1707,10 +1710,9 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
goto failure; goto failure;
} }
if (esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, NULL, (domain->conn, priv->host, domain->uuid, NULL, &virtualMachine,
&virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 ||
esxVI_Long_Alloc(domain->conn, &spec->memoryMB) < 0) { esxVI_Long_Alloc(domain->conn, &spec->memoryMB) < 0) {
goto failure; goto failure;
...@@ -1722,6 +1724,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) ...@@ -1722,6 +1724,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj,
spec, &task) < 0 || spec, &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -1761,10 +1764,9 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory) ...@@ -1761,10 +1764,9 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
goto failure; goto failure;
} }
if (esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, NULL, (domain->conn, priv->host, domain->uuid, NULL, &virtualMachine,
&virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(domain->conn, esxVI_ResourceAllocationInfo_Alloc(domain->conn,
&spec->memoryAllocation) < 0 || &spec->memoryAllocation) < 0 ||
...@@ -1778,6 +1780,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory) ...@@ -1778,6 +1780,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj,
spec, &task) < 0 || spec, &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -2100,10 +2103,9 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) ...@@ -2100,10 +2103,9 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
goto failure; goto failure;
} }
if (esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, NULL, (domain->conn, priv->host, domain->uuid, NULL, &virtualMachine,
&virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 ||
esxVI_Int_Alloc(domain->conn, &spec->numCPUs) < 0) { esxVI_Int_Alloc(domain->conn, &spec->numCPUs) < 0) {
goto failure; goto failure;
...@@ -2114,6 +2116,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) ...@@ -2114,6 +2116,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj,
spec, &task) < 0 || spec, &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -2483,10 +2486,9 @@ esxDomainCreate(virDomainPtr domain) ...@@ -2483,10 +2486,9 @@ esxDomainCreate(virDomainPtr domain)
if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList, if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
"runtime.powerState") < 0 || "runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, propertyNameList, (domain->conn, priv->host, domain->uuid, propertyNameList,
&virtualMachine, &virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine, esxVI_GetVirtualMachinePowerState(domain->conn, virtualMachine,
&powerState) < 0) { &powerState) < 0) {
goto failure; goto failure;
...@@ -2501,6 +2503,7 @@ esxDomainCreate(virDomainPtr domain) ...@@ -2501,6 +2503,7 @@ esxDomainCreate(virDomainPtr domain)
if (esxVI_PowerOnVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_PowerOnVM_Task(domain->conn, priv->host, virtualMachine->obj,
&task) < 0 || &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -2690,6 +2693,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) ...@@ -2690,6 +2693,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
datastoreRelatedPath, NULL, esxVI_Boolean_False, datastoreRelatedPath, NULL, esxVI_Boolean_False,
resourcePool, hostSystem->obj, &task) < 0 || resourcePool, hostSystem->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(conn, priv->host, task, esxVI_WaitForTaskCompletion(conn, priv->host, task,
def->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -2977,10 +2981,9 @@ esxDomainSetSchedulerParameters(virDomainPtr domain, ...@@ -2977,10 +2981,9 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
goto failure; goto failure;
} }
if (esxVI_LookupVirtualMachineByUuid(domain->conn, priv->host, if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, NULL, (domain->conn, priv->host, domain->uuid, NULL, &virtualMachine,
&virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(domain->conn, &spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(domain->conn, esxVI_ResourceAllocationInfo_Alloc(domain->conn,
&spec->cpuAllocation) < 0) { &spec->cpuAllocation) < 0) {
...@@ -3068,6 +3071,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain, ...@@ -3068,6 +3071,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj, if (esxVI_ReconfigVM_Task(domain->conn, priv->host, virtualMachine->obj,
spec, &task) < 0 || spec, &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->host, task, esxVI_WaitForTaskCompletion(domain->conn, priv->host, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
...@@ -3106,7 +3110,7 @@ esxDomainMigratePrepare(virConnectPtr dconn, ...@@ -3106,7 +3110,7 @@ esxDomainMigratePrepare(virConnectPtr dconn,
char *transport = NULL; char *transport = NULL;
if (uri_in == NULL) { if (uri_in == NULL) {
if (esxUtil_ParseQuery(dconn, &transport, NULL, NULL) < 0) { if (esxUtil_ParseQuery(dconn, &transport, NULL, NULL, NULL) < 0) {
return -1; return -1;
} }
...@@ -3181,14 +3185,10 @@ esxDomainMigratePerform(virDomainPtr domain, ...@@ -3181,14 +3185,10 @@ esxDomainMigratePerform(virDomainPtr domain,
} }
/* Lookup VirtualMachine, HostSystem and ResourcePool */ /* Lookup VirtualMachine, HostSystem and ResourcePool */
if (esxVI_LookupVirtualMachineByUuid(domain->conn, priv->vCenter, if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
domain->uuid, NULL, (domain->conn, priv->vCenter, domain->uuid, NULL, &virtualMachine,
&virtualMachine, priv->autoAnswer) < 0 ||
esxVI_Occurence_RequiredItem) < 0) { esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
goto failure;
}
if (esxVI_String_AppendValueToList(domain->conn, &propertyNameList,
"parent") < 0 || "parent") < 0 ||
esxVI_LookupHostSystemByIp(domain->conn, priv->vCenter, hostIpAddress, esxVI_LookupHostSystemByIp(domain->conn, priv->vCenter, hostIpAddress,
propertyNameList, &hostSystem) < 0) { propertyNameList, &hostSystem) < 0) {
...@@ -3231,6 +3231,7 @@ esxDomainMigratePerform(virDomainPtr domain, ...@@ -3231,6 +3231,7 @@ esxDomainMigratePerform(virDomainPtr domain,
if (esxVI_MigrateVM_Task(domain->conn, priv->vCenter, virtualMachine->obj, if (esxVI_MigrateVM_Task(domain->conn, priv->vCenter, virtualMachine->obj,
resourcePool, hostSystem->obj, &task) < 0 || resourcePool, hostSystem->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(domain->conn, priv->vCenter, task, esxVI_WaitForTaskCompletion(domain->conn, priv->vCenter, task,
domain->uuid, priv->autoAnswer,
&taskInfoState) < 0) { &taskInfoState) < 0) {
goto failure; goto failure;
} }
......
...@@ -133,7 +133,7 @@ esxUtil_RequestPassword(virConnectAuthPtr auth, const char *username, ...@@ -133,7 +133,7 @@ esxUtil_RequestPassword(virConnectAuthPtr auth, const char *username,
int int
esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter, esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
int *noVerify) int *noVerify, int *autoAnswer)
{ {
int result = 0; int result = 0;
int i; int i;
...@@ -148,6 +148,14 @@ esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter, ...@@ -148,6 +148,14 @@ esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
*vCenter = NULL; *vCenter = NULL;
} }
if (noVerify != NULL) {
*noVerify = 0;
}
if (autoAnswer != NULL) {
*autoAnswer = 0;
}
#ifdef HAVE_XMLURI_QUERY_RAW #ifdef HAVE_XMLURI_QUERY_RAW
queryParamSet = qparam_query_parse(conn->uri->query_raw); queryParamSet = qparam_query_parse(conn->uri->query_raw);
#else #else
...@@ -202,6 +210,18 @@ esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter, ...@@ -202,6 +210,18 @@ esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
"'%s' (should be 0 or 1)", queryParam->value); "'%s' (should be 0 or 1)", queryParam->value);
goto failure; goto failure;
} }
} else if (STRCASEEQ(queryParam->name, "auto_answer")) {
if (autoAnswer == NULL) {
continue;
}
if (virStrToLong_i(queryParam->value, NULL, 10, autoAnswer) < 0 ||
(*autoAnswer != 0 && *autoAnswer != 1)) {
ESX_ERROR(conn, VIR_ERR_INVALID_ARG,
"Query parameter 'auto_answer' has unexpected value "
"'%s' (should be 0 or 1)", queryParam->value);
goto failure;
}
} else { } else {
VIR_WARN("Ignoring unexpected query parameter '%s'", VIR_WARN("Ignoring unexpected query parameter '%s'",
queryParam->name); queryParam->name);
......
...@@ -36,7 +36,7 @@ char *esxUtil_RequestPassword(virConnectAuthPtr auth, const char *username, ...@@ -36,7 +36,7 @@ char *esxUtil_RequestPassword(virConnectAuthPtr auth, const char *username,
const char *hostname); const char *hostname);
int esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter, int esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
int *noVerify); int *noVerify, int *autoAnswer);
int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id); int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
......
...@@ -982,7 +982,6 @@ esxVI_List_CastFromAnyType(virConnectPtr conn, esxVI_AnyType *anyType, ...@@ -982,7 +982,6 @@ esxVI_List_CastFromAnyType(virConnectPtr conn, esxVI_AnyType *anyType,
goto cleanup; goto cleanup;
} }
int int
esxVI_List_Serialize(virConnectPtr conn, esxVI_List *list, const char *element, esxVI_List_Serialize(virConnectPtr conn, esxVI_List *list, const char *element,
virBufferPtr output, esxVI_Boolean required, virBufferPtr output, esxVI_Boolean required,
...@@ -1076,6 +1075,8 @@ esxVI_Alloc(virConnectPtr conn, void **ptrptr, size_t size) ...@@ -1076,6 +1075,8 @@ esxVI_Alloc(virConnectPtr conn, void **ptrptr, size_t size)
return 0; return 0;
} }
int int
esxVI_CheckSerializationNecessity(virConnectPtr conn, const char *element, esxVI_CheckSerializationNecessity(virConnectPtr conn, const char *element,
esxVI_Boolean required) esxVI_Boolean required)
...@@ -1478,6 +1479,33 @@ esxVI_GetVirtualMachinePowerState(virConnectPtr conn, ...@@ -1478,6 +1479,33 @@ esxVI_GetVirtualMachinePowerState(virConnectPtr conn,
int
esxVI_GetVirtualMachineQuestionInfo
(virConnectPtr conn, esxVI_ObjectContent *virtualMachine,
esxVI_VirtualMachineQuestionInfo **questionInfo)
{
esxVI_DynamicProperty *dynamicProperty;
if (questionInfo == NULL || *questionInfo != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
return -1;
}
for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "runtime.question")) {
if (esxVI_VirtualMachineQuestionInfo_CastFromAnyType
(conn, dynamicProperty->val, questionInfo) < 0) {
return -1;
}
}
}
return 0;
}
int int
esxVI_LookupNumberOfDomainsByPowerState(virConnectPtr conn, esxVI_Context *ctx, esxVI_LookupNumberOfDomainsByPowerState(virConnectPtr conn, esxVI_Context *ctx,
esxVI_VirtualMachinePowerState powerState, esxVI_VirtualMachinePowerState powerState,
...@@ -1826,6 +1854,60 @@ esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx, ...@@ -1826,6 +1854,60 @@ esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
int
esxVI_LookupVirtualMachineByUuidAndPrepareForTask
(virConnectPtr conn, esxVI_Context *ctx, const unsigned char *uuid,
esxVI_String *propertyNameList, esxVI_ObjectContent **virtualMachine,
esxVI_Boolean autoAnswer)
{
int result = 0;
esxVI_String *completePropertyNameList = NULL;
esxVI_VirtualMachineQuestionInfo *questionInfo = NULL;
esxVI_TaskInfo *pendingTaskInfoList = NULL;
if (esxVI_String_DeepCopyList(conn, &completePropertyNameList,
propertyNameList) < 0 ||
esxVI_String_AppendValueListToList(conn, &completePropertyNameList,
"runtime.question\0"
"recentTask\0") < 0 ||
esxVI_LookupVirtualMachineByUuid(conn, ctx, uuid,
completePropertyNameList,
virtualMachine,
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachineQuestionInfo(conn, *virtualMachine,
&questionInfo) < 0 ||
esxVI_LookupPendingTaskInfoListByVirtualMachine
(conn, ctx, *virtualMachine, &pendingTaskInfoList) < 0) {
goto failure;
}
if (questionInfo != NULL &&
esxVI_HandleVirtualMachineQuestion(conn, ctx, (*virtualMachine)->obj,
questionInfo, autoAnswer) < 0) {
goto failure;
}
if (pendingTaskInfoList != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_OPERATION_INVALID,
"Other tasks are pending for this domain");
goto failure;
}
cleanup:
esxVI_String_Free(&completePropertyNameList);
esxVI_VirtualMachineQuestionInfo_Free(&questionInfo);
esxVI_TaskInfo_Free(&pendingTaskInfoList);
return result;
failure:
result = -1;
goto cleanup;
}
int int
esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx, esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
const char *name, esxVI_String *propertyNameList, const char *name, esxVI_String *propertyNameList,
...@@ -1986,6 +2068,164 @@ esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx, ...@@ -1986,6 +2068,164 @@ esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
int esxVI_LookupTaskInfoByTask(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task,
esxVI_TaskInfo **taskInfo)
{
int result = 0;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *objectContent = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
if (taskInfo == NULL || *taskInfo != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
return -1;
}
if (esxVI_String_AppendValueToList(conn, &propertyNameList, "info") < 0 ||
esxVI_LookupObjectContentByType(conn, ctx, task, "Task",
propertyNameList, esxVI_Boolean_False,
&objectContent) < 0) {
goto failure;
}
for (dynamicProperty = objectContent->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "info")) {
if (esxVI_TaskInfo_CastFromAnyType(conn, dynamicProperty->val,
taskInfo) < 0) {
goto failure;
}
break;
} else {
VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
}
}
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&objectContent);
return result;
failure:
result = -1;
goto cleanup;
}
int
esxVI_LookupPendingTaskInfoListByVirtualMachine
(virConnectPtr conn, esxVI_Context *ctx, esxVI_ObjectContent *virtualMachine,
esxVI_TaskInfo **pendingTaskInfoList)
{
int result = 0;
esxVI_String *propertyNameList = NULL;
esxVI_ManagedObjectReference *recentTaskList = NULL;
esxVI_ManagedObjectReference *recentTask = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_TaskInfo *taskInfo = NULL;
if (pendingTaskInfoList == NULL || *pendingTaskInfoList != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
return -1;
}
/* Get list of recent tasks */
for (dynamicProperty = virtualMachine->propSet; dynamicProperty != NULL;
dynamicProperty = dynamicProperty->_next) {
if (STREQ(dynamicProperty->name, "recentTask")) {
if (esxVI_ManagedObjectReference_CastListFromAnyType
(conn, dynamicProperty->val, &recentTaskList, "Task") < 0) {
goto failure;
}
break;
}
}
/* Lookup task info for each task */
for (recentTask = recentTaskList; recentTask != NULL;
recentTask = recentTask->_next) {
if (esxVI_LookupTaskInfoByTask(conn, ctx, recentTask, &taskInfo) < 0) {
goto failure;
}
if (taskInfo->state == esxVI_TaskInfoState_Queued ||
taskInfo->state == esxVI_TaskInfoState_Running) {
if (esxVI_TaskInfo_AppendToList(conn, pendingTaskInfoList,
taskInfo) < 0) {
goto failure;
}
taskInfo = NULL;
} else {
esxVI_TaskInfo_Free(&taskInfo);
}
}
cleanup:
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&recentTaskList);
esxVI_TaskInfo_Free(&taskInfo);
return result;
failure:
esxVI_TaskInfo_Free(pendingTaskInfoList);
result = -1;
goto cleanup;
}
int
esxVI_LookupAndHandleVirtualMachineQuestion(virConnectPtr conn,
esxVI_Context *ctx,
const unsigned char *uuid,
esxVI_Boolean autoAnswer)
{
int result = 0;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachineQuestionInfo *questionInfo = NULL;
if (esxVI_String_AppendValueToList(conn, &propertyNameList,
"runtime.question") < 0 ||
esxVI_LookupVirtualMachineByUuid(conn, ctx, uuid, propertyNameList,
&virtualMachine,
esxVI_Occurence_RequiredItem) < 0 ||
esxVI_GetVirtualMachineQuestionInfo(conn, virtualMachine,
&questionInfo) < 0) {
goto failure;
}
if (questionInfo != NULL &&
esxVI_HandleVirtualMachineQuestion(conn, ctx, virtualMachine->obj,
questionInfo, autoAnswer) < 0) {
goto failure;
}
cleanup:
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_VirtualMachineQuestionInfo_Free(&questionInfo);
return result;
failure:
result = -1;
goto cleanup;
}
int int
esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx, esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
const char *name, const char *request, const char *name, const char *request,
...@@ -2133,9 +2373,110 @@ esxVI_SimpleVirtualMachineMethod(virConnectPtr conn, esxVI_Context *ctx, ...@@ -2133,9 +2373,110 @@ esxVI_SimpleVirtualMachineMethod(virConnectPtr conn, esxVI_Context *ctx,
int
esxVI_HandleVirtualMachineQuestion
(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo,
esxVI_Boolean autoAnswer)
{
int result = 0;
esxVI_ElementDescription *elementDescription = NULL;
virBuffer buffer = VIR_BUFFER_INITIALIZER;
esxVI_ElementDescription *answerChoice = NULL;
int answerIndex = 0;
char *possibleAnswers = NULL;
if (questionInfo->choice->choiceInfo != NULL) {
for (elementDescription = questionInfo->choice->choiceInfo;
elementDescription != NULL;
elementDescription = elementDescription->_next) {
virBufferVSprintf(&buffer, "'%s'", elementDescription->label);
if (elementDescription->_next != NULL) {
virBufferAddLit(&buffer, ", ");
}
if (answerChoice == NULL &&
questionInfo->choice->defaultIndex != NULL &&
questionInfo->choice->defaultIndex->value == answerIndex) {
answerChoice = elementDescription;
}
++answerIndex;
}
if (virBufferError(&buffer)) {
virReportOOMError(conn);
goto failure;
}
possibleAnswers = virBufferContentAndReset(&buffer);
}
if (autoAnswer == esxVI_Boolean_True) {
if (possibleAnswers == NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Pending question blocks virtual machine execution, "
"question is '%s', no possible answers",
questionInfo->text);
goto failure;
} else if (answerChoice == NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Pending question blocks virtual machine execution, "
"question is '%s', possible answers are %s, but no "
"default answer is specified", questionInfo->text,
possibleAnswers);
goto failure;
}
VIR_INFO("Pending question blocks virtual machine execution, "
"question is '%s', possible answers are %s, responding "
"with default answer '%s'", questionInfo->text,
possibleAnswers, answerChoice->label);
if (esxVI_AnswerVM(conn, ctx, virtualMachine, questionInfo->id,
answerChoice->key) < 0) {
goto failure;
}
} else {
if (possibleAnswers != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Pending question blocks virtual machine execution, "
"question is '%s', possible answers are %s",
questionInfo->text, possibleAnswers);
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Pending question blocks virtual machine execution, "
"question is '%s', no possible answers",
questionInfo->text);
}
goto failure;
}
cleanup:
VIR_FREE(possibleAnswers);
return result;
failure:
if (possibleAnswers == NULL) {
possibleAnswers = virBufferContentAndReset(&buffer);
}
result = -1;
goto cleanup;
}
int int
esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx, esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task, esxVI_ManagedObjectReference *task,
const unsigned char *virtualMachineUuid,
esxVI_Boolean autoAnswer,
esxVI_TaskInfoState *finalState) esxVI_TaskInfoState *finalState)
{ {
int result = 0; int result = 0;
...@@ -2150,6 +2491,7 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx, ...@@ -2150,6 +2491,7 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx,
esxVI_PropertyChange *propertyChange = NULL; esxVI_PropertyChange *propertyChange = NULL;
esxVI_AnyType *propertyValue = NULL; esxVI_AnyType *propertyValue = NULL;
esxVI_TaskInfoState state = esxVI_TaskInfoState_Undefined; esxVI_TaskInfoState state = esxVI_TaskInfoState_Undefined;
esxVI_TaskInfo *taskInfo = NULL;
version = strdup(""); version = strdup("");
...@@ -2187,6 +2529,35 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx, ...@@ -2187,6 +2529,35 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx,
state != esxVI_TaskInfoState_Error) { state != esxVI_TaskInfoState_Error) {
esxVI_UpdateSet_Free(&updateSet); esxVI_UpdateSet_Free(&updateSet);
if (virtualMachineUuid != NULL) {
if (esxVI_LookupAndHandleVirtualMachineQuestion
(conn, ctx, virtualMachineUuid, autoAnswer) < 0) {
/*
* FIXME: Disable error reporting here, so possible errors from
* esxVI_LookupTaskInfoByTask() and esxVI_CancelTask()
* don't overwrite the actual error
*/
if (esxVI_LookupTaskInfoByTask(conn, ctx, task, &taskInfo)) {
goto failure;
}
if (taskInfo->cancelable == esxVI_Boolean_True) {
if (esxVI_CancelTask(conn, ctx, task) < 0) {
VIR_ERROR0("Cancelable task is blocked by an "
"unanswered question but cancelation "
"failed");
}
} else {
VIR_ERROR0("Non-cancelable task is blocked by an "
"unanswered question");
}
/* FIXME: Enable error reporting here again */
goto failure;
}
}
if (esxVI_WaitForUpdates(conn, ctx, version, &updateSet) < 0) { if (esxVI_WaitForUpdates(conn, ctx, version, &updateSet) < 0) {
goto failure; goto failure;
} }
...@@ -2259,6 +2630,7 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx, ...@@ -2259,6 +2630,7 @@ esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference_Free(&propertyFilter); esxVI_ManagedObjectReference_Free(&propertyFilter);
VIR_FREE(version); VIR_FREE(version);
esxVI_UpdateSet_Free(&updateSet); esxVI_UpdateSet_Free(&updateSet);
esxVI_TaskInfo_Free(&taskInfo);
return result; return result;
......
...@@ -229,6 +229,10 @@ int esxVI_GetVirtualMachinePowerState ...@@ -229,6 +229,10 @@ int esxVI_GetVirtualMachinePowerState
(virConnectPtr conn, esxVI_ObjectContent *virtualMachine, (virConnectPtr conn, esxVI_ObjectContent *virtualMachine,
esxVI_VirtualMachinePowerState *powerState); esxVI_VirtualMachinePowerState *powerState);
int esxVI_GetVirtualMachineQuestionInfo
(virConnectPtr conn, esxVI_ObjectContent *virtualMachine,
esxVI_VirtualMachineQuestionInfo **questionInfo);
int esxVI_LookupNumberOfDomainsByPowerState int esxVI_LookupNumberOfDomainsByPowerState
(virConnectPtr conn, esxVI_Context *ctx, (virConnectPtr conn, esxVI_Context *ctx,
esxVI_VirtualMachinePowerState powerState, esxVI_Boolean inverse); esxVI_VirtualMachinePowerState powerState, esxVI_Boolean inverse);
...@@ -252,12 +256,31 @@ int esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx, ...@@ -252,12 +256,31 @@ int esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ObjectContent **virtualMachine, esxVI_ObjectContent **virtualMachine,
esxVI_Occurence occurence); esxVI_Occurence occurence);
int esxVI_LookupVirtualMachineByUuidAndPrepareForTask
(virConnectPtr conn, esxVI_Context *ctx, const unsigned char *uuid,
esxVI_String *propertyNameList, esxVI_ObjectContent **virtualMachine,
esxVI_Boolean autoAnswer);
int esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx, int esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
const char *name, const char *name,
esxVI_String *propertyNameList, esxVI_String *propertyNameList,
esxVI_ObjectContent **datastore, esxVI_ObjectContent **datastore,
esxVI_Occurence occurence); esxVI_Occurence occurence);
int esxVI_LookupTaskInfoByTask(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task,
esxVI_TaskInfo **taskInfo);
int esxVI_LookupPendingTaskInfoListByVirtualMachine
(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ObjectContent *virtualMachine,
esxVI_TaskInfo **pendingTaskInfoList);
int esxVI_LookupAndHandleVirtualMachineQuestion(virConnectPtr conn,
esxVI_Context *ctx,
const unsigned char *uuid,
esxVI_Boolean autoAnswer);
int esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx, int esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
const char *name, const char *request, const char *name, const char *request,
esxVI_ManagedObjectReference **task); esxVI_ManagedObjectReference **task);
...@@ -271,8 +294,16 @@ int esxVI_SimpleVirtualMachineMethod ...@@ -271,8 +294,16 @@ int esxVI_SimpleVirtualMachineMethod
(virConnectPtr conn, esxVI_Context *ctx, const char *name, (virConnectPtr conn, esxVI_Context *ctx, const char *name,
esxVI_ManagedObjectReference *virtualMachine); esxVI_ManagedObjectReference *virtualMachine);
int esxVI_HandleVirtualMachineQuestion
(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo,
esxVI_Boolean autoAnswer);
int esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx, int esxVI_WaitForTaskCompletion(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task, esxVI_ManagedObjectReference *task,
const unsigned char *virtualMachineUuid,
esxVI_Boolean autoAnswer,
esxVI_TaskInfoState *finalState); esxVI_TaskInfoState *finalState);
#endif /* __ESX_VI_H__ */ #endif /* __ESX_VI_H__ */
...@@ -576,6 +576,61 @@ esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx, ...@@ -576,6 +576,61 @@ esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
int
esxVI_CancelTask(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task)
{
int result = 0;
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *request = NULL;
esxVI_Response *response = NULL;
if (ctx->service == NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid call");
return -1;
}
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
virBufferAddLit(&buffer, "<CancelTask xmlns=\"urn:vim25\">");
if (esxVI_ManagedObjectReference_Serialize(conn, task, "_this", &buffer,
esxVI_Boolean_True) < 0) {
goto failure;
}
virBufferAddLit(&buffer, "</CancelTask>");
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);
if (virBufferError(&buffer)) {
virReportOOMError(conn);
goto failure;
}
request = virBufferContentAndReset(&buffer);
if (esxVI_Context_Execute(conn, ctx, request, NULL, &response,
esxVI_Boolean_False) < 0) {
goto failure;
}
cleanup:
VIR_FREE(request);
esxVI_Response_Free(&response);
return result;
failure:
if (request == NULL) {
request = virBufferContentAndReset(&buffer);
}
result = -1;
goto cleanup;
}
int int
esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx, esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine) esxVI_ManagedObjectReference *virtualMachine)
...@@ -625,6 +680,62 @@ esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx, ...@@ -625,6 +680,62 @@ esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
int
esxVI_AnswerVM(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
const char *questionId, const char *answerChoice)
{
int result = 0;
virBuffer buffer = VIR_BUFFER_INITIALIZER;
char *request = NULL;
esxVI_Response *response = NULL;
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
virBufferAddLit(&buffer, "<AnswerVM xmlns=\"urn:vim25\">");
if (esxVI_ManagedObjectReference_Serialize(conn, virtualMachine, "_this",
&buffer,
esxVI_Boolean_True) < 0 ||
esxVI_String_SerializeValue(conn, questionId, "questionId",
&buffer, esxVI_Boolean_True) < 0 ||
esxVI_String_SerializeValue(conn, answerChoice, "answerChoice",
&buffer, esxVI_Boolean_True) < 0) {
goto failure;
}
virBufferAddLit(&buffer, "</AnswerVM>");
virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);
if (virBufferError(&buffer)) {
virReportOOMError(conn);
goto failure;
}
request = virBufferContentAndReset(&buffer);
if (esxVI_Context_Execute(conn, ctx, request, NULL, &response,
esxVI_Boolean_False) < 0) {
goto failure;
}
cleanup:
VIR_FREE(request);
esxVI_Response_Free(&response);
return result;
failure:
if (request == NULL) {
request = virBufferContentAndReset(&buffer);
}
result = -1;
goto cleanup;
}
int int
esxVI_CreateFilter(virConnectPtr conn, esxVI_Context *ctx, esxVI_CreateFilter(virConnectPtr conn, esxVI_Context *ctx,
esxVI_PropertyFilterSpec *propertyFilterSpec, esxVI_PropertyFilterSpec *propertyFilterSpec,
......
...@@ -80,9 +80,16 @@ int esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx, ...@@ -80,9 +80,16 @@ int esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *hostSystem, esxVI_ManagedObjectReference *hostSystem,
esxVI_ManagedObjectReference **task); esxVI_ManagedObjectReference **task);
int esxVI_CancelTask(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *task);
int esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx, int esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine); esxVI_ManagedObjectReference *virtualMachine);
int esxVI_AnswerVM(virConnectPtr conn, esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
const char *questionId, const char *answerChoice);
int esxVI_CreateFilter(virConnectPtr conn, esxVI_Context *ctx, int esxVI_CreateFilter(virConnectPtr conn, esxVI_Context *ctx,
esxVI_PropertyFilterSpec *propertyFilterSpec, esxVI_PropertyFilterSpec *propertyFilterSpec,
esxVI_Boolean partialUpdates, esxVI_Boolean partialUpdates,
......
...@@ -1202,6 +1202,9 @@ static const esxVI_Enumeration _esxVI_TaskInfoState_Enumeration = { ...@@ -1202,6 +1202,9 @@ static const esxVI_Enumeration _esxVI_TaskInfoState_Enumeration = {
/* esxVI_TaskInfoState_CastFromAnyType */ /* esxVI_TaskInfoState_CastFromAnyType */
ESX_VI__TEMPLATE__ENUMERATION__CAST_FROM_ANY_TYPE(TaskInfoState); ESX_VI__TEMPLATE__ENUMERATION__CAST_FROM_ANY_TYPE(TaskInfoState);
/* esxVI_TaskInfoState_Deserialize */
ESX_VI__TEMPLATE__ENUMERATION__DESERIALIZE(TaskInfoState);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
...@@ -1315,6 +1318,9 @@ esxVI_ManagedObjectReference_DeepCopy(virConnectPtr conn, ...@@ -1315,6 +1318,9 @@ esxVI_ManagedObjectReference_DeepCopy(virConnectPtr conn,
return -1; return -1;
} }
/* esxVI_ManagedObjectReference_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(ManagedObjectReference);
int int
esxVI_ManagedObjectReference_CastFromAnyType esxVI_ManagedObjectReference_CastFromAnyType
(virConnectPtr conn, esxVI_AnyType *anyType, (virConnectPtr conn, esxVI_AnyType *anyType,
...@@ -1339,6 +1345,76 @@ esxVI_ManagedObjectReference_CastFromAnyType ...@@ -1339,6 +1345,76 @@ esxVI_ManagedObjectReference_CastFromAnyType
expectedType); expectedType);
} }
int
esxVI_ManagedObjectReference_CastListFromAnyType
(virConnectPtr conn, esxVI_AnyType *anyType,
esxVI_ManagedObjectReference **managedObjectReferenceList,
const char *expectedType)
{
int result = 0;
xmlNodePtr childNode = NULL;
esxVI_AnyType *childAnyType = NULL;
esxVI_ManagedObjectReference *managedObjectReference = NULL;
if (managedObjectReferenceList == NULL ||
*managedObjectReferenceList != NULL) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
goto failure;
}
if (anyType == NULL) {
return 0;
}
if (STRNEQ(anyType->other, "ArrayOfManagedObjectReference")) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting type to be 'ArrayOfManagedObjectReference' "
"but found '%s'", anyType->other);
goto failure;
}
for (childNode = anyType->_node->children; childNode != NULL;
childNode = childNode->next) {
if (childNode->type != XML_ELEMENT_NODE) {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Wrong XML element type %d", childNode->type);
goto failure;
}
esxVI_AnyType_Free(&childAnyType);
if (esxVI_AnyType_Deserialize(conn, childNode, &childAnyType) < 0) {
goto failure;
}
managedObjectReference = NULL;
if (esxVI_ManagedObjectReference_CastFromAnyType
(conn, childAnyType, &managedObjectReference,
expectedType) < 0) {
goto failure;
}
if (esxVI_ManagedObjectReference_AppendToList
(conn, managedObjectReferenceList, managedObjectReference) < 0) {
goto failure;
}
}
cleanup:
esxVI_AnyType_Free(&childAnyType);
return result;
failure:
esxVI_ManagedObjectReference_Free(managedObjectReferenceList);
result = -1;
goto cleanup;
}
int int
esxVI_ManagedObjectReference_Serialize esxVI_ManagedObjectReference_Serialize
(virConnectPtr conn, esxVI_ManagedObjectReference *managedObjectReference, (virConnectPtr conn, esxVI_ManagedObjectReference *managedObjectReference,
...@@ -2426,6 +2502,41 @@ ESX_VI__TEMPLATE__DESERIALIZE(UserSession, ...@@ -2426,6 +2502,41 @@ ESX_VI__TEMPLATE__DESERIALIZE(UserSession,
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: VirtualMachineQuestionInfo
*/
/* esxVI_VirtualMachineQuestionInfo_Alloc */
ESX_VI__TEMPLATE__ALLOC(VirtualMachineQuestionInfo);
/* esxVI_VirtualMachineQuestionInfo_Free */
ESX_VI__TEMPLATE__FREE(VirtualMachineQuestionInfo,
{
VIR_FREE(item->id);
VIR_FREE(item->text);
esxVI_ChoiceOption_Free(&item->choice);
/*esxVI_VirtualMachineMessage_Free(&item->message);*//* FIXME */
});
/* esxVI_VirtualMachineQuestionInfo_CastFromAnyType */
ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(VirtualMachineQuestionInfo);
/* esxVI_VirtualMachineQuestionInfo_Deserialize */
ESX_VI__TEMPLATE__DESERIALIZE(VirtualMachineQuestionInfo,
{
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, id);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, text);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(ChoiceOption, choice);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_NOOP(message); /* FIXME */
},
{
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(id);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(text);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(choice);
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ElementDescription extends Description * VI Type: ElementDescription extends Description
* *
...@@ -2447,6 +2558,9 @@ ESX_VI__TEMPLATE__FREE(ElementDescription, ...@@ -2447,6 +2558,9 @@ ESX_VI__TEMPLATE__FREE(ElementDescription,
VIR_FREE(item->key); VIR_FREE(item->key);
}); });
/* esxVI_ElementDescription_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(ElementDescription);
/* esxVI_ElementDescription_Deserialize */ /* esxVI_ElementDescription_Deserialize */
ESX_VI__TEMPLATE__DESERIALIZE(ElementDescription, ESX_VI__TEMPLATE__DESERIALIZE(ElementDescription,
{ {
...@@ -2462,6 +2576,37 @@ ESX_VI__TEMPLATE__DESERIALIZE(ElementDescription, ...@@ -2462,6 +2576,37 @@ ESX_VI__TEMPLATE__DESERIALIZE(ElementDescription,
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ChoiceOption extends OptionType
*
* In contrast to SelectionSpec and TraversalSpec just merge
* OptionType into ChoiceOption for simplicity, because
* only ChoiceOption is used.
*/
/* esxVI_ChoiceOption_Alloc */
ESX_VI__TEMPLATE__ALLOC(ChoiceOption);
/* esxVI_ChoiceOption_Free */
ESX_VI__TEMPLATE__FREE(ChoiceOption,
{
esxVI_ElementDescription_Free(&item->choiceInfo);
esxVI_Int_Free(&item->defaultIndex);
});
/* esxVI_ChoiceOption_Deserialize */
ESX_VI__TEMPLATE__DESERIALIZE(ChoiceOption,
{
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Boolean, valueIsReadonly);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(ElementDescription, choiceInfo);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Int, defaultIndex);
},
{
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(choiceInfo);
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: PerfMetricId * VI Type: PerfMetricId
*/ */
...@@ -2699,3 +2844,76 @@ ESX_VI__TEMPLATE__DESERIALIZE(PerfEntityMetric, ...@@ -2699,3 +2844,76 @@ ESX_VI__TEMPLATE__DESERIALIZE(PerfEntityMetric,
/* esxVI_PerfEntityMetric_DeserializeList */ /* esxVI_PerfEntityMetric_DeserializeList */
ESX_VI__TEMPLATE__LIST__DESERIALIZE(PerfEntityMetric); ESX_VI__TEMPLATE__LIST__DESERIALIZE(PerfEntityMetric);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: TaskInfo
*/
/* esxVI_TaskInfo_Alloc */
ESX_VI__TEMPLATE__ALLOC(TaskInfo);
/* esxVI_TaskInfo_Free */
ESX_VI__TEMPLATE__FREE(TaskInfo,
{
esxVI_TaskInfo_Free(&item->_next);
VIR_FREE(item->key);
esxVI_ManagedObjectReference_Free(&item->task);
VIR_FREE(item->name);
VIR_FREE(item->descriptionId);
esxVI_ManagedObjectReference_Free(&item->entity);
VIR_FREE(item->entityName);
/*esxVI_ManagedObjectReference_Free(&item->locked);*//* FIXME */
/*esxVI_MethodFault_Free(&item->error);*//* FIXME */
esxVI_AnyType_Free(&item->result);
esxVI_Int_Free(&item->progress);
/*esxVI_TaskReason_Free(&item->reason);*//* FIXME */
esxVI_DateTime_Free(&item->queueTime);
esxVI_DateTime_Free(&item->startTime);
esxVI_DateTime_Free(&item->completeTime);
esxVI_Int_Free(&item->eventChainId);
});
/* esxVI_TaskInfo_CastFromAnyType */
ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(TaskInfo);
/* esxVI_TaskInfo_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(TaskInfo);
/* esxVI_TaskInfo_Deserialize */
ESX_VI__TEMPLATE__DESERIALIZE(TaskInfo,
{
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, key);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_EXPECTED(ManagedObjectReference,
"Task", task);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, name);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, descriptionId);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_EXPECTED(ManagedObjectReference,
NULL, entity);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, entityName);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_NOOP(locked); /* FIXME */
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(TaskInfoState, state);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Boolean, cancelled);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Boolean, cancelable);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_NOOP(error); /* FIXME */
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(AnyType, result);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Int, progress);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_NOOP(reason); /* FIXME */
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(DateTime, queueTime);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(DateTime, startTime);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(DateTime, completeTime);
ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Int, eventChainId);
},
{
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(key);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(task);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(descriptionId);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(state);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(cancelled);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(cancelable);
/*ESX_VI__TEMPLATE__PROPERTY__REQUIRED(reason);*//* FIXME */
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(queueTime);
ESX_VI__TEMPLATE__PROPERTY__REQUIRED(eventChainId);
});
...@@ -90,13 +90,16 @@ typedef struct _esxVI_ResourcePoolResourceUsage esxVI_ResourcePoolResourceUsage; ...@@ -90,13 +90,16 @@ typedef struct _esxVI_ResourcePoolResourceUsage esxVI_ResourcePoolResourceUsage;
typedef struct _esxVI_VirtualMachineConfigSpec esxVI_VirtualMachineConfigSpec; typedef struct _esxVI_VirtualMachineConfigSpec esxVI_VirtualMachineConfigSpec;
typedef struct _esxVI_Event esxVI_Event; typedef struct _esxVI_Event esxVI_Event;
typedef struct _esxVI_UserSession esxVI_UserSession; typedef struct _esxVI_UserSession esxVI_UserSession;
typedef struct _esxVI_VirtualMachineQuestionInfo esxVI_VirtualMachineQuestionInfo;
typedef struct _esxVI_ElementDescription esxVI_ElementDescription; typedef struct _esxVI_ElementDescription esxVI_ElementDescription;
typedef struct _esxVI_ChoiceOption esxVI_ChoiceOption;
typedef struct _esxVI_PerfMetricId esxVI_PerfMetricId; typedef struct _esxVI_PerfMetricId esxVI_PerfMetricId;
typedef struct _esxVI_PerfCounterInfo esxVI_PerfCounterInfo; typedef struct _esxVI_PerfCounterInfo esxVI_PerfCounterInfo;
typedef struct _esxVI_PerfQuerySpec esxVI_PerfQuerySpec; typedef struct _esxVI_PerfQuerySpec esxVI_PerfQuerySpec;
typedef struct _esxVI_PerfSampleInfo esxVI_PerfSampleInfo; typedef struct _esxVI_PerfSampleInfo esxVI_PerfSampleInfo;
typedef struct _esxVI_PerfMetricIntSeries esxVI_PerfMetricIntSeries; typedef struct _esxVI_PerfMetricIntSeries esxVI_PerfMetricIntSeries;
typedef struct _esxVI_PerfEntityMetric esxVI_PerfEntityMetric; typedef struct _esxVI_PerfEntityMetric esxVI_PerfEntityMetric;
typedef struct _esxVI_TaskInfo esxVI_TaskInfo;
...@@ -403,6 +406,8 @@ enum _esxVI_TaskInfoState { ...@@ -403,6 +406,8 @@ enum _esxVI_TaskInfoState {
int esxVI_TaskInfoState_CastFromAnyType(virConnectPtr conn, int esxVI_TaskInfoState_CastFromAnyType(virConnectPtr conn,
esxVI_AnyType *anyType, esxVI_AnyType *anyType,
esxVI_TaskInfoState *taskInfoState); esxVI_TaskInfoState *taskInfoState);
int esxVI_TaskInfoState_Deserialize(virConnectPtr conn, xmlNodePtr node,
esxVI_TaskInfoState *taskInfoState);
...@@ -480,11 +485,19 @@ void esxVI_ManagedObjectReference_Free ...@@ -480,11 +485,19 @@ void esxVI_ManagedObjectReference_Free
int esxVI_ManagedObjectReference_DeepCopy(virConnectPtr conn, int esxVI_ManagedObjectReference_DeepCopy(virConnectPtr conn,
esxVI_ManagedObjectReference **dest, esxVI_ManagedObjectReference **dest,
esxVI_ManagedObjectReference *src); esxVI_ManagedObjectReference *src);
int esxVI_ManagedObjectReference_AppendToList
(virConnectPtr conn,
esxVI_ManagedObjectReference **managedObjectReferenceList,
esxVI_ManagedObjectReference *managedObjectReference);
int esxVI_ManagedObjectReference_CastFromAnyType(virConnectPtr conn, int esxVI_ManagedObjectReference_CastFromAnyType(virConnectPtr conn,
esxVI_AnyType *anyType, esxVI_AnyType *anyType,
esxVI_ManagedObjectReference esxVI_ManagedObjectReference
**managedObjectReference, **managedObjectReference,
const char *expectedType); const char *expectedType);
int esxVI_ManagedObjectReference_CastListFromAnyType
(virConnectPtr conn, esxVI_AnyType *anyType,
esxVI_ManagedObjectReference **managedObjectReferenceList,
const char *expectedType);
int esxVI_ManagedObjectReference_Serialize int esxVI_ManagedObjectReference_Serialize
(virConnectPtr conn, (virConnectPtr conn,
esxVI_ManagedObjectReference *managedObjectReference, esxVI_ManagedObjectReference *managedObjectReference,
...@@ -1064,6 +1077,32 @@ int esxVI_UserSession_Deserialize(virConnectPtr conn, xmlNodePtr node, ...@@ -1064,6 +1077,32 @@ int esxVI_UserSession_Deserialize(virConnectPtr conn, xmlNodePtr node,
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: VirtualMachineQuestionInfo
*/
/* FIXME: implement the rest */
struct _esxVI_VirtualMachineQuestionInfo {
char *id; /* required */
char *text; /* required */
esxVI_ChoiceOption *choice; /* required */
/*esxVI_VirtualMachineMessage *message;*/ /* optional, list */
};
int esxVI_VirtualMachineQuestionInfo_Alloc
(virConnectPtr conn,
esxVI_VirtualMachineQuestionInfo **virtualMachineQuestionInfo);
void esxVI_VirtualMachineQuestionInfo_Free
(esxVI_VirtualMachineQuestionInfo **virtualMachineQuestionInfo);
int esxVI_VirtualMachineQuestionInfo_CastFromAnyType
(virConnectPtr conn, esxVI_AnyType *anyType,
esxVI_VirtualMachineQuestionInfo **virtualMachineQuestionInfo);
int esxVI_VirtualMachineQuestionInfo_Deserialize
(virConnectPtr conn, xmlNodePtr node,
esxVI_VirtualMachineQuestionInfo **virtualMachineQuestionInfo);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ElementDescription extends Description * VI Type: ElementDescription extends Description
* *
...@@ -1087,12 +1126,40 @@ int esxVI_ElementDescription_Alloc ...@@ -1087,12 +1126,40 @@ int esxVI_ElementDescription_Alloc
(virConnectPtr conn, esxVI_ElementDescription **elementDescription); (virConnectPtr conn, esxVI_ElementDescription **elementDescription);
void esxVI_ElementDescription_Free void esxVI_ElementDescription_Free
(esxVI_ElementDescription **elementDescription); (esxVI_ElementDescription **elementDescription);
int esxVI_ElementDescription_AppendToList
(virConnectPtr conn, esxVI_ElementDescription **elementDescriptionList,
esxVI_ElementDescription *elementDescription);
int esxVI_ElementDescription_Deserialize int esxVI_ElementDescription_Deserialize
(virConnectPtr conn, xmlNodePtr node, (virConnectPtr conn, xmlNodePtr node,
esxVI_ElementDescription **elementDescription); esxVI_ElementDescription **elementDescription);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ChoiceOption extends OptionType
*
* In contrast to SelectionSpec and TraversalSpec just merge
* OptionType into ChoiceOption for simplicity, because
* only ChoiceOption is used.
*/
struct _esxVI_ChoiceOption {
/* OptionType */
esxVI_Boolean valueIsReadonly; /* optional */
/* ChoiceOption */
esxVI_ElementDescription *choiceInfo; /* required, list */
esxVI_Int *defaultIndex; /* optional */
};
int esxVI_ChoiceOption_Alloc(virConnectPtr conn,
esxVI_ChoiceOption **choiceOption);
void esxVI_ChoiceOption_Free(esxVI_ChoiceOption **choiceOption);
int esxVI_ChoiceOption_Deserialize(virConnectPtr conn, xmlNodePtr node,
esxVI_ChoiceOption **choiceOption);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: PerfMetricId * VI Type: PerfMetricId
*/ */
...@@ -1272,4 +1339,43 @@ int esxVI_PerfEntityMetric_DeserializeList ...@@ -1272,4 +1339,43 @@ int esxVI_PerfEntityMetric_DeserializeList
(virConnectPtr conn, xmlNodePtr node, (virConnectPtr conn, xmlNodePtr node,
esxVI_PerfEntityMetric **perfEntityMetricList); esxVI_PerfEntityMetric **perfEntityMetricList);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: TaskInfo
*/
struct _esxVI_TaskInfo {
esxVI_TaskInfo *_next; /* optional */
char *key; /* required */
esxVI_ManagedObjectReference *task; /* required */
char *name; /* optional */
char *descriptionId; /* required */
esxVI_ManagedObjectReference *entity; /* optional */
char *entityName; /* optional */
/*esxVI_ManagedObjectReference *locked;*/ /* optional, list *//* FIXME */
esxVI_TaskInfoState state; /* required */
esxVI_Boolean cancelled; /* required */
esxVI_Boolean cancelable; /* required */
/*esxVI_MethodFault *error;*/ /* optional *//* FIXME */
esxVI_AnyType *result; /* optional */
esxVI_Int *progress; /* optional */
/*esxVI_TaskReason *reason;*/ /* required *//* FIXME */
esxVI_DateTime *queueTime; /* required */
esxVI_DateTime *startTime; /* optional */
esxVI_DateTime *completeTime; /* optional */
esxVI_Int *eventChainId; /* required */
};
int esxVI_TaskInfo_Alloc(virConnectPtr conn, esxVI_TaskInfo **taskInfo);
void esxVI_TaskInfo_Free(esxVI_TaskInfo **taskInfoList);
int esxVI_TaskInfo_CastFromAnyType(virConnectPtr conn, esxVI_AnyType *anyType,
esxVI_TaskInfo **taskInfo);
int esxVI_TaskInfo_AppendToList(virConnectPtr conn,
esxVI_TaskInfo **taskInfoList,
esxVI_TaskInfo *taskInfo);
int esxVI_TaskInfo_Deserialize(virConnectPtr conn, xmlNodePtr node,
esxVI_TaskInfo **taskInfo);
#endif /* __ESX_VI_TYPES_H__ */ #endif /* __ESX_VI_TYPES_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册