esx: Improve error reporting for failed tasks

Instead of just reporting that a task failed get the
localized message from the TaskInfo error and include
it in the reported error message.

Implement minimal deserialization support for the
MethodFault type in order to obtain the actual fault
type.

For example, this changes the reported error message
when trying to create a volume with zero size from

  Could not create volume

to

  Could not create volume: InvalidArgument - A specified parameter was not correct.

Not perfect yet, but better than before.
This commit is contained in:
Matthias Bolte 2010-12-06 13:53:36 +01:00
parent f12d416927
commit 2a151699f1
8 changed files with 227 additions and 41 deletions

View File

@ -1706,6 +1706,7 @@ esxDomainSuspend(virDomainPtr domain)
esxVI_VirtualMachinePowerState powerState;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
@ -1729,12 +1730,14 @@ esxDomainSuspend(virDomainPtr domain)
if (esxVI_SuspendVM_Task(priv->primary, virtualMachine->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not suspend domain"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not suspend domain: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -1744,6 +1747,7 @@ esxDomainSuspend(virDomainPtr domain)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -1760,6 +1764,7 @@ esxDomainResume(virDomainPtr domain)
esxVI_VirtualMachinePowerState powerState;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
@ -1783,12 +1788,14 @@ esxDomainResume(virDomainPtr domain)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not resume domain"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not resume domain: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -1798,6 +1805,7 @@ esxDomainResume(virDomainPtr domain)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -1901,6 +1909,7 @@ esxDomainDestroy(virDomainPtr domain)
esxVI_VirtualMachinePowerState powerState;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (priv->vCenter != NULL) {
ctx = priv->vCenter;
@ -1930,12 +1939,14 @@ esxDomainDestroy(virDomainPtr domain)
if (esxVI_PowerOffVM_Task(ctx, virtualMachine->obj, &task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not destroy domain"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not destroy domain: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -1946,6 +1957,7 @@ esxDomainDestroy(virDomainPtr domain)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -2028,6 +2040,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
esxVI_VirtualMachineConfigSpec *spec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
@ -2048,13 +2061,15 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set max-memory to %lu kilobytes"), memory);
_("Could not set max-memory to %lu kilobytes: %s"), memory,
taskInfoErrorMessage);
goto cleanup;
}
@ -2064,6 +2079,7 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -2079,6 +2095,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
esxVI_VirtualMachineConfigSpec *spec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
@ -2100,13 +2117,15 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set memory to %lu kilobytes"), memory);
_("Could not set memory to %lu kilobytes: %s"), memory,
taskInfoErrorMessage);
goto cleanup;
}
@ -2116,6 +2135,7 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -2394,6 +2414,7 @@ esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
esxVI_VirtualMachineConfigSpec *spec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (flags != VIR_DOMAIN_VCPU_LIVE) {
ESX_ERROR(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
@ -2438,13 +2459,15 @@ esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not set number of virtual CPUs to %d"), nvcpus);
_("Could not set number of virtual CPUs to %d: %s"), nvcpus,
taskInfoErrorMessage);
goto cleanup;
}
@ -2454,6 +2477,7 @@ esxDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -2828,6 +2852,7 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
int id = -1;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
virCheckFlags(0, -1);
@ -2855,12 +2880,14 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not start domain"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not start domain: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -2871,6 +2898,7 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_String_Free(&propertyNameList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -2907,6 +2935,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml)
esxVI_ManagedObjectReference *resourcePool = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
virDomainPtr domain = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
@ -3066,12 +3095,14 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, def->uuid,
esxVI_Occurrence_OptionalItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not define domain"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not define domain: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -3100,6 +3131,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml)
esxVI_ObjectContent_Free(&hostSystem);
esxVI_ManagedObjectReference_Free(&resourcePool);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return domain;
}
@ -3340,6 +3372,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
esxVI_SharesInfo *sharesInfo = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
int i;
if (esxVI_EnsureSession(priv->primary) < 0) {
@ -3434,13 +3467,15 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not change scheduler parameters"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not change scheduler parameters: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -3450,6 +3485,7 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -3504,6 +3540,7 @@ esxDomainMigratePerform(virDomainPtr domain,
esxVI_Event *eventList = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
if (priv->vCenter == NULL) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
@ -3601,14 +3638,16 @@ esxDomainMigratePerform(virDomainPtr domain,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->vCenter, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not migrate domain, migration task finished with "
"an error"));
"an error: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -3619,6 +3658,7 @@ esxDomainMigratePerform(virDomainPtr domain,
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_Event_Free(&eventList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -3783,6 +3823,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
virDomainSnapshotPtr snapshot = NULL;
virCheckFlags(0, NULL);
@ -3820,12 +3861,14 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_Boolean_False, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create snapshot"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not create snapshot: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -3836,6 +3879,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return snapshot;
}
@ -4058,6 +4102,7 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
esxVI_VirtualMachineSnapshotTree *snapshotTreeParent = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
virCheckFlags(0, -1);
@ -4077,13 +4122,15 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not revert to snapshot '%s'"), snapshot->name);
_("Could not revert to snapshot '%s': %s"), snapshot->name,
taskInfoErrorMessage);
goto cleanup;
}
@ -4092,6 +4139,7 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -4109,6 +4157,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
esxVI_Boolean removeChildren = esxVI_Boolean_False;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
@ -4132,13 +4181,15 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
removeChildren, &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not delete snapshot '%s'"), snapshot->name);
_("Could not delete snapshot '%s': %s"), snapshot->name,
taskInfoErrorMessage);
goto cleanup;
}
@ -4147,6 +4198,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
cleanup:
esxVI_VirtualMachineSnapshotTree_Free(&rootSnapshotList);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}
@ -4163,6 +4215,7 @@ esxDomainSetMemoryParameters(virDomainPtr domain, virMemoryParameterPtr params,
esxVI_VirtualMachineConfigSpec *spec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
int i;
virCheckFlags(0, -1);
@ -4199,13 +4252,15 @@ esxDomainSetMemoryParameters(virDomainPtr domain, virMemoryParameterPtr params,
&task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
esxVI_Occurrence_RequiredItem,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not change memory parameters"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not change memory parameters: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -4215,6 +4270,7 @@ esxDomainSetMemoryParameters(virDomainPtr domain, virMemoryParameterPtr params,
esxVI_ObjectContent_Free(&virtualMachine);
esxVI_VirtualMachineConfigSpec_Free(&spec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
return result;
}

View File

@ -926,6 +926,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
char *uuid_string = NULL;
char *key = NULL;
@ -1092,12 +1093,14 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_VirtualDiskSpec_DynamicCast(virtualDiskSpec), &task) < 0 ||
esxVI_WaitForTaskCompletion(priv->primary, task, NULL,
esxVI_Occurrence_None,
priv->autoAnswer, &taskInfoState) < 0) {
priv->autoAnswer, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create volume"));
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not create volume: %s"),
taskInfoErrorMessage);
goto cleanup;
}
@ -1151,6 +1154,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_FileInfo_Free(&fileInfo);
esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
VIR_FREE(uuid_string);
VIR_FREE(key);

View File

@ -3009,6 +3009,7 @@ esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
esxVI_FloppyImageFileQuery *floppyImageFileQuery = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
esxVI_TaskInfo *taskInfo = NULL;
esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
@ -3128,13 +3129,15 @@ esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
datastorePathWithoutFileName, searchSpec,
&task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Occurrence_None,
esxVI_Boolean_False, &taskInfoState) < 0) {
esxVI_Boolean_False, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not serach in datastore '%s'"), datastoreName);
_("Could not search in datastore '%s': %s"),
datastoreName, taskInfoErrorMessage);
goto cleanup;
}
@ -3179,6 +3182,7 @@ esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
esxVI_ManagedObjectReference_Free(&hostDatastoreBrowser);
esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
esxVI_TaskInfo_Free(&taskInfo);
esxVI_HostDatastoreBrowserSearchResults_Free(&searchResults);
@ -3203,6 +3207,7 @@ esxVI_LookupDatastoreContentByDatastoreName
char *datastorePath = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *taskInfoErrorMessage = NULL;
esxVI_TaskInfo *taskInfo = NULL;
if (searchResultsList == NULL || *searchResultsList != NULL) {
@ -3269,13 +3274,15 @@ esxVI_LookupDatastoreContentByDatastoreName
datastorePath, searchSpec,
&task) < 0 ||
esxVI_WaitForTaskCompletion(ctx, task, NULL, esxVI_Occurrence_None,
esxVI_Boolean_False, &taskInfoState) < 0) {
esxVI_Boolean_False, &taskInfoState,
&taskInfoErrorMessage) < 0) {
goto cleanup;
}
if (taskInfoState != esxVI_TaskInfoState_Success) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not serach in datastore '%s'"), datastoreName);
_("Could not serach in datastore '%s': %s"),
datastoreName, taskInfoErrorMessage);
goto cleanup;
}
@ -3294,6 +3301,7 @@ esxVI_LookupDatastoreContentByDatastoreName
esxVI_HostDatastoreBrowserSearchSpec_Free(&searchSpec);
VIR_FREE(datastorePath);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(taskInfoErrorMessage);
esxVI_TaskInfo_Free(&taskInfo);
return result;
@ -3472,7 +3480,8 @@ esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
const unsigned char *virtualMachineUuid,
esxVI_Occurrence virtualMachineOccurrence,
esxVI_Boolean autoAnswer,
esxVI_TaskInfoState *finalState)
esxVI_TaskInfoState *finalState,
char **errorMessage)
{
int result = -1;
esxVI_ObjectSpec *objectSpec = NULL;
@ -3489,6 +3498,11 @@ esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
esxVI_Boolean blocked = esxVI_Boolean_Undefined;
esxVI_TaskInfo *taskInfo = NULL;
if (errorMessage == NULL || *errorMessage != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
version = strdup("");
if (version == NULL) {
@ -3609,6 +3623,35 @@ esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
goto cleanup;
}
if (*finalState != esxVI_TaskInfoState_Success) {
if (esxVI_LookupTaskInfoByTask(ctx, task, &taskInfo)) {
goto cleanup;
}
if (taskInfo->error == NULL) {
*errorMessage = strdup(_("Unknown error"));
if (*errorMessage == NULL) {
virReportOOMError();
goto cleanup;
}
} else if (taskInfo->error->localizedMessage == NULL) {
*errorMessage = strdup(taskInfo->error->fault->_actualType);
if (*errorMessage == NULL) {
virReportOOMError();
goto cleanup;
}
} else {
if (virAsprintf(errorMessage, "%s - %s",
taskInfo->error->fault->_actualType,
taskInfo->error->localizedMessage) < 0) {
virReportOOMError();
goto cleanup;
}
}
}
result = 0;
cleanup:

View File

@ -429,7 +429,8 @@ int esxVI_WaitForTaskCompletion(esxVI_Context *ctx,
const unsigned char *virtualMachineUuid,
esxVI_Occurrence virtualMachineOccurrence,
esxVI_Boolean autoAnswer,
esxVI_TaskInfoState *finalState);
esxVI_TaskInfoState *finalState,
char **errorMessage);
int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
esxVI_HostCpuIdInfo *hostCpuIdInfo);

View File

@ -311,6 +311,12 @@ object LocalDatastoreInfo extends DatastoreInfo
end
object LocalizedMethodFault
MethodFault fault r
String localizedMessage o
end
object NasDatastoreInfo extends DatastoreInfo
HostNasVolume nas o
end
@ -494,7 +500,7 @@ object TaskInfo
TaskInfoState state r
Boolean cancelled r
Boolean cancelable r
LocalizedMethodFault error i
LocalizedMethodFault error o
AnyType result o
Int progress o
TaskReason reason i

View File

@ -1139,6 +1139,7 @@ predefined_objects = ["AnyType",
"Long",
"String",
"DateTime",
"MethodFault",
"ManagedObjectReference"]
@ -1172,6 +1173,7 @@ additional_object_features = { "DatastoreHostMount" : Object.FEATURE__DE
removed_object_features = { "DynamicProperty" : Object.FEATURE__SERIALIZE,
"LocalizedMethodFault" : Object.FEATURE__SERIALIZE,
"ObjectContent" : Object.FEATURE__SERIALIZE,
"ObjectUpdate" : Object.FEATURE__SERIALIZE,
"PropertyChange" : Object.FEATURE__SERIALIZE,

View File

@ -701,6 +701,9 @@ esxVI_Type_ToString(esxVI_Type type)
case esxVI_Type_Fault:
return "Fault";
case esxVI_Type_MethodFault:
return "MethodFault";
case esxVI_Type_ManagedObjectReference:
return "ManagedObjectReference";
@ -741,6 +744,8 @@ esxVI_Type_FromString(const char *type)
return esxVI_Type_DateTime;
} else if (STREQ(type, "Fault")) {
return esxVI_Type_Fault;
} else if (STREQ(type, "MethodFault")) {
return esxVI_Type_MethodFault;
} else if (STREQ(type, "ManagedObjectReference")) {
return esxVI_Type_ManagedObjectReference;
} else if (STREQ(type, "Datacenter")) {
@ -751,7 +756,6 @@ esxVI_Type_FromString(const char *type)
return esxVI_Type_HostSystem;
}
#include "esx_vi_types.generated.typefromstring"
else {
@ -1446,6 +1450,51 @@ ESX_VI__TEMPLATE__DESERIALIZE(Fault,
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: MethodFault
*/
/* esxVI_MethodFault_Alloc */
ESX_VI__TEMPLATE__ALLOC(MethodFault);
/* esxVI_MethodFault_Free */
ESX_VI__TEMPLATE__FREE(MethodFault,
{
VIR_FREE(item->_actualType);
})
int
esxVI_MethodFault_Deserialize(xmlNodePtr node, esxVI_MethodFault **methodFault)
{
if (methodFault == NULL || *methodFault != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
return -1;
}
if (esxVI_MethodFault_Alloc(methodFault) < 0) {
return -1;
}
(*methodFault)->_actualType =
(char *)xmlGetNsProp(node, BAD_CAST "type",
BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
if ((*methodFault)->_actualType == NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("MethodFault is missing 'type' property"));
goto failure;
}
return 0;
failure:
esxVI_MethodFault_Free(methodFault);
return -1;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ManagedObjectReference
*/

View File

@ -48,6 +48,7 @@ typedef struct _esxVI_DateTime esxVI_DateTime;
*/
typedef struct _esxVI_Fault esxVI_Fault;
typedef struct _esxVI_MethodFault esxVI_MethodFault;
typedef struct _esxVI_ManagedObjectReference esxVI_ManagedObjectReference;
typedef struct _esxVI_Datacenter esxVI_Datacenter;
typedef struct _esxVI_ComputeResource esxVI_ComputeResource;
@ -71,6 +72,7 @@ enum _esxVI_Type {
esxVI_Type_Long,
esxVI_Type_DateTime,
esxVI_Type_Fault,
esxVI_Type_MethodFault,
esxVI_Type_ManagedObjectReference,
esxVI_Type_Datacenter,
esxVI_Type_ComputeResource,
@ -278,6 +280,29 @@ int esxVI_Fault_Deserialize(xmlNodePtr node, esxVI_Fault **fault);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: MethodFault
*/
/*
* FIXME: This is just a minimal implementation of the MethodFault type.
* A complete implementation would require to implement dozens of
* extending types too.
*/
struct _esxVI_MethodFault {
esxVI_MethodFault *_unused; /* optional */
esxVI_Type _type; /* required */
char *_actualType; /* required */
};
int esxVI_MethodFault_Alloc(esxVI_MethodFault **methodfault);
void esxVI_MethodFault_Free(esxVI_MethodFault **methodFault);
int esxVI_MethodFault_Deserialize(xmlNodePtr node,
esxVI_MethodFault **methodFault);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* VI Type: ManagedObjectReference
*/