All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] Add error reporting to libxc library
Date: Tue, 5 Dec 2006 02:25:24 +0000	[thread overview]
Message-ID: <20061205022524.GC16297@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 4113 bytes --]

Attached to this mail is an update of my previous patch to add an error
reporting API to the libxc library.  The patch is against xen-devel on
changeset 12722.

Previous discussions were:

 Original post:
  http://lists.xensource.com/archives/html/xen-devel/2006-09/msg00702.html

 2nd posting:
  http://lists.xensource.com/archives/html/xen-devel/2006-10/msg01041.html


This 3rd version of the patch has the following characteristics:

 - An 'xc_error' struct is used to pass around error details. Currently
   contains two members 'code' an enumeration of error types, and
   'message' a free text description of the specific problem. 

 - The xc_get_last_error() method returns a const pointer to the internal
   instance of this struct manged by libxc. By returning a const pointer we 
   can add extra members to the end of the struct at any time without 
   worrying about ABI of callers. This will let us provide more fine grained
   info if needed in the future.

 - The xc_error instance is statically defined inside libxc and marked
   __thread. This ensures that errors are recorded per-thread, and that
   when dealing with errors we never need to call malloc - all storage
   needed is statically allocated.

 - The xc_clear_last_error() method resets any currently recorded error
   details

 - The xc_error_code_to_desc() method converts the integer error code
   into a generic user facing messsage. eg "Invalid kernel". Together
   with the 'message' field from xc_error, this provides the user 
   visible feedback. eg "Invalid kernel: Non PAE-kernel on PAE host."

 - A callback can be registered with xc_set_error_handler to receive
   notification whenever an error is recorded, rather than querying
   for error details after the fact with xc_get_last_error

 - If built with -DDEBUG set, a default error handler will be registered
   which calls fprintf(stderr), thus maintaining current behaviour of
   logging errors to stderr during developer builds.

 - The python binding for libxc is updated to use xc_get_last_error
   to pull out error details whenever appropriate, instead of returning
   info based on 'errno'

 - The xc_set_error method is private to libxc internals, and is used
   for setting error details

 - The ERROR and PERROR macros have been updated to call xc_set_error
   automatically specifying XC_INTERNAL_ERROR as the error code. This
   gives a generic error report for all current failure points

 - Some uses of the ERROR macro have been replaced with explicit
   calls to xc_set_error to enable finer grained error reporting. In
   particular the code dealing with invalid kernel types uses this
   to report about PAE/architecture/wordsize mismatches

This should address the recommendations / suggestions from the previous
round of feedback on this patch.

The patch has been tested by calling xm create against a varietry of
config files defining invalid kernels of various kinds. It has also
been tested with libvirt talking to xend. In both cases the error
messages were propagated all the way back up the stack.

There is only one place where I need to do further work. The suspend
& restore APIs in Xend invoke external helper programs rather than
calling libxc directly. This means that error details are essentially
lost. Since there is already code in XenD which scans STDERR from these
programs I will investigate adapting this to extract actual error
mesages from these helpers.

Since I've not been keeping up with development on XenAPI I'm not clear
on what (if any) extra code is needed to get errors integrated with
this new control API. Hopefully it should be little-to-no work, but 
I could do with someone who knows XenAPI details validating this.

   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

[-- Attachment #2: xen-3.0.4-libxc-errors.patch --]
[-- Type: text/plain, Size: 27635 bytes --]

diff -r fd28a1b139de tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xc_hvm_build.c	Mon Dec 04 12:42:25 2006 -0500
@@ -285,7 +285,6 @@ static int xc_hvm_build_internal(int xc_
 
     if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
     {
-        ERROR("Error constructing guest OS");
         goto error_out;
     }
 
@@ -329,26 +328,30 @@ static int parseelfimage(char *elfbase,
 
     if ( !IS_ELF(*ehdr) )
     {
-        ERROR("Kernel image does not have an ELF header.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel image does not have an ELF header.");
         return -EINVAL;
     }
 
     if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
     {
-        ERROR("ELF program headers extend beyond end of image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF program headers extend beyond end of image.");
         return -EINVAL;
     }
 
     if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
     {
-        ERROR("ELF section headers extend beyond end of image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF section headers extend beyond end of image.");
         return -EINVAL;
     }
 
     /* Find the section-header strings table. */
     if ( ehdr->e_shstrndx == SHN_UNDEF )
     {
-        ERROR("ELF image has no section-header strings table (shstrtab).");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF image has no section-header strings table (shstrtab).");
         return -EINVAL;
     }
     shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
@@ -370,7 +373,8 @@ static int parseelfimage(char *elfbase,
          (ehdr->e_entry < kernstart) ||
          (ehdr->e_entry > kernend) )
     {
-        ERROR("Malformed ELF image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Malformed ELF image.");
         return -EINVAL;
     }
 
diff -r fd28a1b139de tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xc_linux_build.c	Mon Dec 04 12:42:25 2006 -0500
@@ -120,7 +120,7 @@ static int probeimageformat(const char *
     if ( probe_elf(image, image_size, load_funcs) &&
          probe_bin(image, image_size, load_funcs) )
     {
-        ERROR( "Unrecognized image format" );
+        xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
         return -EINVAL;
     }
 
@@ -618,17 +618,20 @@ static int compat_check(int xc_handle, s
     xen_capabilities_info_t xen_caps = "";
 
     if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
-        ERROR("Cannot determine host capabilities.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Cannot determine host capabilities.");
         return 0;
     }
 
     if (strstr(xen_caps, "xen-3.0-x86_32p")) {
         if (dsi->pae_kernel == PAEKERN_no) {
-            ERROR("Non PAE-kernel on PAE host.");
+            xc_set_error(XC_INVALID_KERNEL,
+                         "Non PAE-kernel on PAE host.");
             return 0;
         }
     } else if (dsi->pae_kernel != PAEKERN_no) {
-        ERROR("PAE-kernel on non-PAE host.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "PAE-kernel on non-PAE host.");
         return 0;
     }
 
@@ -1141,7 +1144,6 @@ static int xc_linux_build_internal(int x
                      console_evtchn, console_mfn,
                      features_bitmap) < 0 )
     {
-        ERROR("Error constructing guest OS");
         goto error_out;
     }
 
diff -r fd28a1b139de tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xc_load_elf.c	Mon Dec 04 12:42:25 2006 -0500
@@ -29,20 +29,46 @@ loadelfsymtab(
  */
 #if defined(__ia64__)
 #define ELFCLASS   ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
 #define ELFDATA    ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
 #define ELFMACHINE EM_IA_64
+#define ELFMACHINE_DESC "ia64"
+
+
 #elif defined(__i386__)
 #define ELFCLASS   ELFCLASS32
+#define ELFCLASS_DESC "32-bit"
+
 #define ELFDATA    ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
 #define ELFMACHINE EM_386
+#define ELFMACHINE_DESC "i386"
+
+
 #elif defined(__x86_64__)
 #define ELFCLASS   ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
 #define ELFDATA    ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
 #define ELFMACHINE EM_X86_64
+#define ELFMACHINE_DESC "x86_64"
+
+
 #elif defined(__powerpc__)
 #define ELFCLASS   ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
 #define ELFDATA    ELFDATA2MSB
+#define ELFDATA_DESC "Big-Endian"
+
 #define ELFMACHINE EM_PPC64
+#define ELFMACHINE_DESC "ppc64"
 #endif
 
 int probe_elf(const char *image,
@@ -231,7 +257,8 @@ unsigned long long xen_elfnote_numeric(s
         *defined = 1;
         return *(uint64_t*)ELFNOTE_DESC(note);
     default:
-        ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n",
+        xc_set_error(XC_INVALID_KERNEL,
+                     "elfnotes: unknown data size %#x for numeric type note %#x\n",
               note->descsz, type);
         return 0;
     }
@@ -250,35 +277,59 @@ static int parseelfimage(const char *ima
 
     if ( !IS_ELF(*ehdr) )
     {
-        ERROR("Kernel image does not have an ELF header.");
-        return -EINVAL;
-    }
-
-    if ( (ehdr->e_ident[EI_CLASS] != ELFCLASS) ||
-         (ehdr->e_machine != ELFMACHINE) ||
-         (ehdr->e_ident[EI_DATA] != ELFDATA) ||
-         (ehdr->e_type != ET_EXEC) )
-    {
-        ERROR("Kernel not a Xen-compatible Elf image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel image does not have an ELF header.");
+        return -EINVAL;
+    }
+
+    if (ehdr->e_machine != ELFMACHINE)
+    {
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel ELF architecture '%d' does not match Xen architecture '%d' (%s)",
+                     ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
+        return -EINVAL;
+    }
+    if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
+    {
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel ELF wordsize '%d' does not match Xen wordsize '%d' (%s)",
+                     ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
+        return -EINVAL;
+    }
+    if (ehdr->e_ident[EI_DATA] != ELFDATA)
+    {
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel ELF endianness '%d' does not match Xen endianness '%d' (%s)",
+                     ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
+        return -EINVAL;
+    }
+    if (ehdr->e_type != ET_EXEC)
+    {
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel ELF type '%d' does not match Xen type '%d'",
+                     ehdr->e_type, ET_EXEC);
         return -EINVAL;
     }
 
     if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
     {
-        ERROR("ELF program headers extend beyond end of image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF program headers extend beyond end of image.");
         return -EINVAL;
     }
 
     if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
     {
-        ERROR("ELF section headers extend beyond end of image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF section headers extend beyond end of image.");
         return -EINVAL;
     }
 
     /* Find the section-header strings table. */
     if ( ehdr->e_shstrndx == SHN_UNDEF )
     {
-        ERROR("ELF image has no section-header strings table (shstrtab).");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF image has no section-header strings table (shstrtab).");
         return -EINVAL;
     }
     shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
@@ -325,22 +376,25 @@ static int parseelfimage(const char *ima
         if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
              ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
         {
-            ERROR("Will only load images built for the generic loader "
-                  "or Linux images");
+            xc_set_error(XC_INVALID_KERNEL,
+                         "Will only load images built for the generic loader "
+                         "or Linux images");
             return -EINVAL;
         }
 
         if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
         {
-            ERROR("Will only load images built for Xen v3.0");
+            xc_set_error(XC_INVALID_KERNEL,
+                         "Will only load images built for Xen v3.0");
             return -EINVAL;
         }
     }
     else
     {
 #if defined(__x86_64__) || defined(__i386__)
-        ERROR("Not a Xen-ELF image: "
-              "No ELF notes or '__xen_guest' section found.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Not a Xen-ELF image: "
+                     "No ELF notes or '__xen_guest' section found.");
         return -EINVAL;
 #endif
     }
@@ -396,8 +450,9 @@ static int parseelfimage(const char *ima
 
     if ( elf_pa_off_defined && !virt_base_defined )
     {
-        ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
-              " notes or __xen_guest section.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
+                     " notes or __xen_guest section.");
         return -EINVAL;
     }
 
@@ -409,7 +464,8 @@ static int parseelfimage(const char *ima
         vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
         if ( (vaddr + phdr->p_memsz) < vaddr )
         {
-            ERROR("ELF program header %d is too large.", h);
+            xc_set_error(XC_INVALID_KERNEL,
+                         "ELF program header %d is too large.", h);
             return -EINVAL;
         }
 
@@ -431,7 +487,8 @@ static int parseelfimage(const char *ima
          (dsi->v_kernentry > kernend) ||
          (dsi->v_start > kernstart) )
     {
-        ERROR("ELF start or entries are out of bounds.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "ELF start or entries are out of bounds.");
         return -EINVAL;
     }
 
diff -r fd28a1b139de tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xc_private.c	Mon Dec 04 19:08:11 2006 -0500
@@ -7,6 +7,71 @@
 #include <inttypes.h>
 #include "xc_private.h"
 #include "xg_private.h"
+
+#include <stdarg.h>
+
+static __thread xc_error last_error = { XC_ERROR_NONE, ""};
+#if DEBUG
+static xc_error_handler error_handler = xc_default_error_handler;
+#else
+static xc_error_handler error_handler = NULL;
+#endif
+
+void xc_default_error_handler(const xc_error const *err) {
+    const char *desc = xc_error_code_to_desc(err->code);
+    fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
+}
+
+const xc_error const *xc_get_last_error(void) {
+    return &last_error;
+}
+
+void xc_clear_last_error(void) {
+    last_error.code = XC_ERROR_NONE;
+    last_error.message[0] = '\0';
+}
+
+const char *xc_error_code_to_desc(int code) {
+    /* Sync to members of xc_error_code enumeration in xenctrl.h */
+    switch (code) {
+    case XC_ERROR_NONE: return "No error details";
+    case XC_INTERNAL_ERROR: return "Internal error";
+    case XC_INVALID_KERNEL: return "Invalid kernel";
+    default:
+        return "Unknown error code";
+    }
+}
+
+xc_error_handler xc_set_error_handler(xc_error_handler handler) {
+    xc_error_handler old = error_handler;
+    error_handler = handler;
+    return old;
+}
+
+
+static void _xc_set_error(int code, const char *msg) {
+    last_error.code = code;
+    strncpy(last_error.message, msg, XC_MAX_ERROR_MSG_LEN - 1);
+    last_error.message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+}
+
+void xc_set_error(int code, const char *fmt, ...) {
+    int saved_errno = errno;
+    char msg[XC_MAX_ERROR_MSG_LEN];
+    va_list args;
+
+    va_start(args, fmt);
+    vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
+    msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+    va_end(args);
+
+    _xc_set_error(code, msg);
+
+    errno = saved_errno;
+
+    if (error_handler)
+        error_handler(&last_error);
+}
 
 int lock_pages(void *addr, size_t len)
 {
diff -r fd28a1b139de tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xc_private.h	Mon Dec 04 14:06:30 2006 -0500
@@ -59,23 +59,14 @@
 #define PPRINTF(_f, _a...)
 #endif
 
-#define ERROR(_m, _a...)                        \
-do {                                            \
-    int __saved_errno = errno;                  \
-    DPRINTF("ERROR: " _m "\n" , ## _a );        \
-    errno = __saved_errno;                      \
-} while (0)
+void xc_set_error(int code, const char *fmt, ...);
+
+#define ERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m, ## _a)
+
+#define PERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, "%s (%d = %s)", _m, errno, strerror(errno))
 
 int lock_pages(void *addr, size_t len);
 void unlock_pages(void *addr, size_t len);
-
-#define PERROR(_m, _a...)                               \
-do {                                                    \
-    int __saved_errno = errno;                          \
-    DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a ,       \
-            __saved_errno, strerror(__saved_errno));    \
-    errno = __saved_errno;                              \
-} while (0)
 
 static inline void safe_munlock(const void *addr, size_t len)
 {
diff -r fd28a1b139de tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/libxc/xenctrl.h	Mon Dec 04 19:04:53 2006 -0500
@@ -682,4 +682,46 @@ int xc_hvm_set_pci_link_route(
 int xc_hvm_set_pci_link_route(
     int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
 
+
+typedef enum {
+  XC_ERROR_NONE = 0,
+  XC_INTERNAL_ERROR = 1,
+  XC_INVALID_KERNEL = 2,
+} xc_error_code;
+
+#define XC_MAX_ERROR_MSG_LEN 1024
+typedef struct {
+  int code;
+  char message[XC_MAX_ERROR_MSG_LEN];
+} xc_error;
+
+/*
+ * Return a pointer to the last error. This pointer and the
+ * data pointed to are only valid until the next call to
+ * libxc.
+ */
+const xc_error const *xc_get_last_error(void);
+
+/*
+ * Clear the last error
+ */
+void xc_clear_last_error(void);
+
+typedef void (*xc_error_handler)(const xc_error const* err);
+
+/*
+ * The default error handler which prints to stderr
+ */
+void xc_default_error_handler(const xc_error const* err);
+
+/*
+ * Convert an error code into a text description
+ */
+const char *xc_error_code_to_desc(int code);
+
+/*
+ * Registers a callback to handle errors
+ */
+xc_error_handler xc_set_error_handler(xc_error_handler handler);
+
 #endif
diff -r fd28a1b139de tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c	Mon Dec 04 09:29:26 2006 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Dec 04 19:11:22 2006 -0500
@@ -29,7 +29,7 @@
 #define PKG "xen.lowlevel.xc"
 #define CLS "xc"
 
-static PyObject *xc_error, *zero;
+static PyObject *xc_error_obj, *zero;
 
 typedef struct {
     PyObject_HEAD;
@@ -40,6 +40,23 @@ static PyObject *dom_op(XcObject *self, 
 static PyObject *dom_op(XcObject *self, PyObject *args,
                         int (*fn)(int, uint32_t));
 
+static PyObject *pyxc_error_to_exception(void)
+{
+    PyObject *pyerr;
+    const xc_error const *err = xc_get_last_error();
+    const char *desc = xc_error_code_to_desc(err->code);
+
+    if (err->message[1])
+	pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
+    else
+	pyerr = Py_BuildValue("(is)", err->code, desc);
+
+    xc_clear_last_error();
+
+    PyErr_SetObject(xc_error_obj, pyerr);
+
+    return NULL;
+}
 
 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
 {
@@ -53,7 +70,7 @@ static PyObject *pyxc_domain_dumpcore(Xc
         return NULL;
 
     if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -101,13 +118,13 @@ static PyObject *pyxc_domain_create(XcOb
 
     if ( (ret = xc_domain_create(self->xc_handle, ssidref,
                                  handle, flags, &dom)) < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return PyInt_FromLong(dom);
 
 out_exception:
     errno = EINVAL;
-    PyErr_SetFromErrno(xc_error);
+    PyErr_SetFromErrno(xc_error_obj);
     return NULL;
 }
 
@@ -119,7 +136,7 @@ static PyObject *pyxc_domain_max_vcpus(X
       return NULL;
 
     if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -164,7 +181,7 @@ static PyObject *pyxc_vcpu_setaffinity(X
     }
   
     if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -184,7 +201,7 @@ static PyObject *pyxc_domain_setcpuweigh
         return NULL;
 
     if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -215,14 +232,13 @@ static PyObject *pyxc_domain_sethandle(X
     }
 
     if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
 
 out_exception:
-    errno = EINVAL;
-    PyErr_SetFromErrno(xc_error);
+    PyErr_SetFromErrno(xc_error_obj);
     return NULL;
 }
 
@@ -251,7 +267,7 @@ static PyObject *pyxc_domain_getinfo(XcO
     if (nr_doms < 0)
     {
         free(info);
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     }
 
     list = PyList_New(nr_doms);
@@ -306,10 +322,10 @@ static PyObject *pyxc_vcpu_getinfo(XcObj
 
     rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
     if ( rc < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
     if ( rc < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
                               "online",   info.online,
@@ -360,9 +376,7 @@ static PyObject *pyxc_linux_build(XcObje
                         ramdisk, cmdline, features, flags,
                         store_evtchn, &store_mfn,
                         console_evtchn, &console_mfn) != 0 ) {
-        if (!errno)
-             errno = EINVAL;
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     }
     return Py_BuildValue("{s:i,s:i}", 
                          "store_mfn", store_mfn,
@@ -389,14 +403,14 @@ static PyObject *pyxc_hvm_build(XcObject
         return NULL;
 
     if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     /* Set up the HVM info table. */
     va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
                                   PROT_READ | PROT_WRITE,
                                   HVM_INFO_PFN);
     if ( va_map == NULL )
-        return PyErr_SetFromErrno(xc_error);
+        return PyErr_SetFromErrno(xc_error_obj);
     va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
     memset(va_hvm, 0, sizeof(*va_hvm));
     strncpy(va_hvm->signature, "HVM INFO", 8);
@@ -431,7 +445,7 @@ static PyObject *pyxc_evtchn_alloc_unbou
         return NULL;
 
     if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return PyInt_FromLong(port);
 }
@@ -452,7 +466,7 @@ static PyObject *pyxc_physdev_pci_access
     ret = xc_physdev_pci_access_modify(
         self->xc_handle, dom, bus, dev, func, enable);
     if ( ret != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -474,7 +488,7 @@ static PyObject *pyxc_readconsolering(Xc
 
     ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
     if ( ret < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return PyString_FromStringAndSize(str, count);
 }
@@ -504,7 +518,7 @@ static PyObject *pyxc_physinfo(XcObject 
     int i;
     
     if ( xc_physinfo(self->xc_handle, &info) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     *q=0;
     for(i=0;i<sizeof(info.hw_cap)/4;i++)
@@ -542,25 +556,25 @@ static PyObject *pyxc_xeninfo(XcObject *
     xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
 
     if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
 
     xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
     if (xen_pagesize < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
                          "xen_major", xen_version >> 16,
@@ -593,7 +607,7 @@ static PyObject *pyxc_sedf_domain_set(Xc
         return NULL;
    if ( xc_sedf_domain_set(self->xc_handle, domid, period,
                            slice, latency, extratime,weight) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -610,7 +624,7 @@ static PyObject *pyxc_sedf_domain_get(Xc
     
     if (xc_sedf_domain_get(self->xc_handle, domid, &period,
                            &slice,&latency,&extratime,&weight))
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
                          "domid",    domid,
@@ -638,7 +652,7 @@ static PyObject *pyxc_shadow_control(PyO
     
     if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL) 
          < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -668,7 +682,7 @@ static PyObject *pyxc_shadow_mem_control
         op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
     }
     if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     mbarg = mb;
     return Py_BuildValue("i", mbarg);
@@ -678,7 +692,7 @@ static PyObject *pyxc_sched_id_get(XcObj
     
     int sched_id;
     if (xc_sched_id(self->xc_handle, &sched_id) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return PyErr_SetFromErrno(xc_error_obj);
 
     return Py_BuildValue("i", sched_id);
 }
@@ -704,7 +718,7 @@ static PyObject *pyxc_sched_credit_domai
     sdom.cap = cap;
 
     if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -719,7 +733,7 @@ static PyObject *pyxc_sched_credit_domai
         return NULL;
     
     if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return Py_BuildValue("{s:H,s:H}",
                          "weight",  sdom.weight,
@@ -735,7 +749,7 @@ static PyObject *pyxc_domain_setmaxmem(X
         return NULL;
 
     if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -762,7 +776,7 @@ static PyObject *pyxc_domain_memory_incr
     if ( xc_domain_memory_increase_reservation(self->xc_handle, dom, 
                                                nr_extents, extent_order, 
                                                address_bits, NULL) )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     
     Py_INCREF(zero);
     return zero;
@@ -784,7 +798,7 @@ static PyObject *pyxc_domain_ioport_perm
     ret = xc_domain_ioport_permission(
         self->xc_handle, dom, first_port, nr_ports, allow_access);
     if ( ret != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -807,7 +821,7 @@ static PyObject *pyxc_domain_irq_permiss
     ret = xc_domain_irq_permission(
         xc->xc_handle, dom, pirq, allow_access);
     if ( ret != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -830,7 +844,7 @@ static PyObject *pyxc_domain_iomem_permi
     ret = xc_domain_iomem_permission(
         xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
     if ( ret != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -870,7 +884,7 @@ static PyObject *dom_op(XcObject *self, 
         return NULL;
 
     if (fn(self->xc_handle, dom) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -1199,7 +1213,7 @@ PyXc_init(XcObject *self, PyObject *args
 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
 {
     if ((self->xc_handle = xc_interface_open()) == -1) {
-        PyErr_SetFromErrno(xc_error);
+        pyxc_error_to_exception();
         return -1;
     }
 
@@ -1272,7 +1286,7 @@ PyMODINIT_FUNC initxc(void)
     if (m == NULL)
       return;
 
-    xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
+    xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
     zero = PyInt_FromLong(0);
 
     /* KAF: This ensures that we get debug output in a timely manner. */
@@ -1282,8 +1296,8 @@ PyMODINIT_FUNC initxc(void)
     Py_INCREF(&PyXcType);
     PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
 
-    Py_INCREF(xc_error);
-    PyModule_AddObject(m, "Error", xc_error);
+    Py_INCREF(xc_error_obj);
+    PyModule_AddObject(m, "Error", xc_error_obj);
 
     /* Expose some libxc constants to Python */
     PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

                 reply	other threads:[~2006-12-05  2:25 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20061205022524.GC16297@redhat.com \
    --to=berrange@redhat.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.