]> xenbits.xensource.com Git - libvirt.git/commitdiff
esx: Improve error reporting for failed tasks
authorMatthias Bolte <matthias.bolte@googlemail.com>
Mon, 6 Dec 2010 12:53:36 +0000 (13:53 +0100)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Fri, 10 Dec 2010 19:31:57 +0000 (20:31 +0100)
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.

src/esx/esx_driver.c
src/esx/esx_storage_driver.c
src/esx/esx_vi.c
src/esx/esx_vi.h
src/esx/esx_vi_generator.input
src/esx/esx_vi_generator.py
src/esx/esx_vi_types.c
src/esx/esx_vi_types.h

index 8ea6219f86a6a975df3864181b1b38351f8e3348..03a7be30df88cd268aa6bacf99f864a1740a99a3 100644 (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;
 }
index 72e0d7a5cd772832e18fc9fc08f618c66c97c858..83b53fbbd25f0fdf9c394905510f6c0bc5d58a61 100644 (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);
 
index 9c966504b7ffafa3d57214759db182742cfbc79a..74a2a422ece478f0670f153e00685bbcc6a451a4 100644 (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:
index 26779ad07436e666cdef99b88da631f7d74ee646..20e6fb50f6d6243412de7e9969640de243689611 100644 (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);
index 2ee513a2f188bdcadbf321563e703e6fcf403104..991ce8a92f5e7a2c9cc0d0850c6c99b729c54e4e 100644 (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
index 459337975b13591db32fa6cc63cbae95ad6aee7f..4a8a9dc72ebdbfc76fcfcce073f8a5dc676245ac 100755 (executable)
@@ -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,
index ad45483b455fd89d6c3b8c590f5e687e98c14a87..a70e1e05a12b6fa35e03c7b49792a7d03962e81f 100644 (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
  */
index 901eda0357c8cd556674523bce4c6e8ca5a1fc18..64bf2dc27e6f61fcda42a32a96528dc8853badb8 100644 (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
  */