File 767_error_base.patch of Package libvirt-cim

# HG changeset patch
# User Dan Smith <danms@us.ibm.com>
# Date 1227560778 28800
# Node ID 11147ca6980ce2d1999b600e316fd3c415f744b6
# Parent  db393eb037a0782d2e8328d2e2fd0582e185f08b
Add vir_set_status() to misc_util.h

This function allows you to set the message of a CMPIStatus object to something
like what perror() would do.  You give it an error message and (optionally)
a virConnectPtr object and it formats it as "YourError: VirtError".  It
attempts to extract the last error from the connection pointer if supplied,
otherwise it takes the last error in the global library pointer.

I tried to make this function as foolproof as possible, providing no real
error paths.  It attempts to get as much info as it can into the status
object, despite any failures along the way.  Since this is usually to be used
for error handling scenarios, this seems like the only sane approach.

Signed-off-by: Dan Smith <danms@us.ibm.com>

Index: libvirt-cim-0.5.2/libxkutil/misc_util.c
===================================================================
--- libvirt-cim-0.5.2.orig/libxkutil/misc_util.c
+++ libvirt-cim-0.5.2/libxkutil/misc_util.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <libvirt/libvirt.h>
 #include <libvirt/virterror.h>
@@ -580,6 +581,51 @@ int domain_vcpu_count(virDomainPtr dom)
         return actual;
 }
 
+int virt_set_status(const CMPIBroker *broker,
+                    CMPIStatus *s,
+                    CMPIrc rc,
+                    virConnectPtr conn,
+                    const char *fmt, ...)
+{
+        va_list ap;
+        char *formatted = NULL;
+        char *verrmsg = NULL;
+        int ret;
+        virErrorPtr virt_error;
+
+        if (conn == NULL)
+                virt_error = virGetLastError();
+        else
+                virt_error = virConnGetLastError(conn);
+
+        if (virt_error == NULL) {
+                if (asprintf(&verrmsg, "(none)") == -1)
+                        verrmsg = NULL;
+        } else if (virt_error->message != NULL) {
+                verrmsg = strdup(virt_error->message);
+        } else {
+                if (asprintf(&verrmsg, "Error %i", virt_error->code) == -1)
+                        verrmsg = NULL;
+        }
+
+        va_start(ap, fmt);
+        ret = vasprintf(&formatted, fmt, ap);
+        va_end(ap);
+
+        if (ret == -1) {
+                CU_DEBUG("Failed to format message for %s", fmt);
+                formatted = NULL;
+        }
+
+        ret = cu_statusf(broker, s, rc, "%s: %s", formatted, verrmsg);
+
+        free(formatted);
+        free(verrmsg);
+
+        return ret;
+}
+
+
 /*
  * Local Variables:
  * mode: C
Index: libvirt-cim-0.5.2/libxkutil/misc_util.h
===================================================================
--- libvirt-cim-0.5.2.orig/libxkutil/misc_util.h
+++ libvirt-cim-0.5.2/libxkutil/misc_util.h
@@ -126,6 +126,12 @@ bool check_refs_pfx_match(const CMPIObje
 
 int domain_vcpu_count(virDomainPtr dom);
 
+int virt_set_status(const CMPIBroker *broker,
+                    CMPIStatus *s,
+                    CMPIrc rc,
+                    virConnectPtr conn,
+                    const char *fmt, ...);
+
 #define LIBVIRT_CIM_DEFAULT_MAKEREF()                                   \
         static CMPIInstance* make_ref(const CMPIObjectPath *source_ref, \
                                       const CMPIInstance *target_inst,  \
openSUSE Build Service is sponsored by