All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: xen-devel@lists.xensource.com
Subject: Error reporting capabilities for libxc
Date: Fri, 22 Sep 2006 21:31:53 +0100	[thread overview]
Message-ID: <20060922203153.GA1805@redhat.com> (raw)

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

Currently APIs in the libxc library have a very limited means for reporting
errors. They basically return -1 / NULL on error and set errno. Unfortunately
since most of the errors which can occur in libxc are not related to system
calls failing, the information available via errno is essentially useless.
Indeed libxc simply sets errno to -EINVAL in most cases.

The irritating thing is that libxc *does* actually know exactly what went 
wrong in all these cases & if you compile with -DDEBUG will report this
information on STDERR. This is not much use for applications using libxc
since they can hardly trap & parse STDERR to find out what went wrong!

As an illustration of why better error handling is needed, consider the
frequently encountered problem of trying to create a non-PAE guest on a
PAE hypervisor:

  # xm create demo
  Using config file "demo".
  Error: (22, 'Invalid argument')

This makes it essentially impossible to debug any errors with domain 
creation, especially if -DDEBUG was not defined in your build of libxc

So, I've prototyped a simple error reporting mechanism for libxc. The idea
is we first define an enum for the broad classes of errors which can occur.
As proof of concept I've defined one generic error code, and a special one
for invalid kernels

 typedef enum {
    XC_ERROR_NONE = 0,
    XC_INTERNAL_ERROR = 1,
    XC_INVALID_KERNEL = 2,
 } xc_error_code;

Next, I created an internal function  for setting the error code, and
providing an associated descritive message

  void xc_set_error(int code, const char *fmt, ...);

And simply re-defined the existing ERROR & PERROR macros to use this 
function passing the generic XC_INTERNAL_ERROR

 #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))

In the various places which deal with validating the guest kernel I
changed calls to ERROR to call xc_set_error(XC_INVALID_KERNEL,...)
instead. We can define further error codes over time to reduce use
fo the genreic XC_INTERNAL_ERROR as desired.

In the public API defined a way to either fetch the last error, or
register a callback for receving errors:

  int xc_get_last_error_code(void);
  const char *xc_get_last_error_message(void);
  void xc_clear_last_error(void);
  const char *xc_error_code_to_desc(int code);

  typedef void (*xc_error_handler)(int code, const char *msg);
  void xc_default_error_handler(int code, const char *msg);
  xc_error_handler xc_set_error_handler(xc_error_handler handler);

In the python binding I replaced all use of PyErr_SetFromErrno with a helper
which fetches the info from xc_get_last_error_code/message.

Its important to note that in all this work I did not change the contract
of *any* public method in the C library for libxc. The return codes
are still the same, errno is still set in various places. If you compile
with -DDEBUG a error handler callback is set to print to STDERR. So any
existing users will continue to get exactly same behaviour as before. 
They do now have the ability to opt-in to getting full error details if
they so desire.

The python bindings are also unchanged with the exception that the error
thrown contains the xc_error_code & description instead of the errno
value. Since the latter was essentially useless I don't think that's a
huge problem, but we could probably figure out a way to maintain compat
at the python level if absolutely required.

Any way, the upshot of all this work:

 - Try running a 32-bit PV kernel on 64-bit host:

  # xm create error
  Using config file "error".
  Error: [2, 'Kernel ELF architecture 3 does not match Xen architecture 62']

 - Try running a non-PAE kernel on a PAE host:

  # xm create demo
  Using config file "demo".
  Error: [2, 'Non PAE-kernel on PAE host.']

 - Try using libgtk as your kernel:

  # xm create error
  Using config file "error".
  Error: [2, 'Kernel ELF type 3 does not match Xen type 2']

Any way there's some more cleanup to do & some error messages to improve,
and switch more errors to use an explicit error code rather than the 
generic  XC_INTERNAL_ERROR, but I thought I'd post the patch for review
before going too much further.


  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-libxc-errors7.patch --]
[-- Type: text/plain, Size: 23951 bytes --]

diff -ru xen-unstable-11405.orig/tools/libxc/xc_hvm_build.c xen-unstable-11405.new/tools/libxc/xc_hvm_build.c
--- xen-unstable-11405.orig/tools/libxc/xc_hvm_build.c	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xc_hvm_build.c	2006-09-22 15:14:14.000000000 -0400
@@ -460,7 +460,6 @@
                      ctxt, domctl.u.getdomaininfo.shared_info_frame,
                      vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0)
     {
-        ERROR("Error constructing guest OS");
         goto error_out;
     }
 
@@ -529,26 +528,30 @@
 
     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 +
@@ -570,7 +573,8 @@
          (ehdr->e_entry < kernstart) ||
          (ehdr->e_entry > kernend) )
     {
-        ERROR("Malformed ELF image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Malformed ELF image.");
         return -EINVAL;
     }
 
diff -ru xen-unstable-11405.orig/tools/libxc/xc_linux_build.c xen-unstable-11405.new/tools/libxc/xc_linux_build.c
--- xen-unstable-11405.orig/tools/libxc/xc_linux_build.c	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xc_linux_build.c	2006-09-22 15:15:04.000000000 -0400
@@ -121,7 +121,6 @@
     if ( probe_elf(image, image_size, load_funcs) &&
          probe_bin(image, image_size, load_funcs) )
     {
-        ERROR( "Unrecognized image format" );
         return -EINVAL;
     }
 
@@ -611,17 +610,20 @@
     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;
     }
 
@@ -1167,7 +1169,6 @@
                      console_evtchn, console_mfn,
                      features_bitmap) < 0 )
     {
-        ERROR("Error constructing guest OS");
         goto error_out;
     }
 
diff -ru xen-unstable-11405.orig/tools/libxc/xc_linux.c xen-unstable-11405.new/tools/libxc/xc_linux.c
--- xen-unstable-11405.orig/tools/libxc/xc_linux.c	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xc_linux.c	2006-09-18 16:49:42.000000000 -0400
@@ -15,6 +15,82 @@
 #include <xen/sys/evtchn.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <stdarg.h>
+
+
+static int last_error_code = XC_ERROR_NONE;
+static char *last_error_message = NULL;
+#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(int code, const char *msg) {
+    const char *desc = xc_error_code_to_desc(code);
+    fprintf(stderr, "ERROR %s: %s\n", desc, msg);
+}
+
+int xc_get_last_error_code(void) {
+    return last_error_code;
+}
+
+const char *xc_get_last_error_message(void) {
+    return last_error_message;
+}
+
+void xc_clear_last_error(void) {
+    last_error_code = XC_ERROR_NONE;
+    if (last_error_message) {
+        free(last_error_message);
+        last_error_message = NULL;
+    }
+}
+
+const char *xc_error_code_to_desc(int code) {
+    switch (code) {
+    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) {
+    xc_clear_last_error();
+    last_error_code = code;
+    /* NB, we delibrately ignore the OOM condition when
+       strdup()'ing here - there's not really anything
+       we can - particularly if the error we're reporting
+       was an OOM in the first place. The caller can always
+       find the latter via errno */
+    last_error_message = strdup(msg);
+}
+
+#define XC_MAX_ERROR_MSG 4096
+void xc_set_error(int code, const char *fmt, ...) {
+    int saved_errno = errno;
+    char msg[XC_MAX_ERROR_MSG];
+    va_list args;
+
+    va_start(args, fmt);
+    vsnprintf(msg, XC_MAX_ERROR_MSG-1, fmt, args);
+    msg[XC_MAX_ERROR_MSG-1] = '\0';
+    va_end(args);
+
+    _xc_set_error(code, msg);
+
+    errno = saved_errno;
+
+    if (error_handler)
+        error_handler(code, msg);
+}
+
 
 int xc_interface_open(void)
 {
diff -ru xen-unstable-11405.orig/tools/libxc/xc_load_elf.c xen-unstable-11405.new/tools/libxc/xc_load_elf.c
--- xen-unstable-11405.orig/tools/libxc/xc_load_elf.c	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xc_load_elf.c	2006-09-22 15:27:23.000000000 -0400
@@ -231,7 +231,8 @@
         *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 +251,59 @@
 
     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_ident[EI_CLASS] != ELFCLASS) ||
-         (ehdr->e_machine != ELFMACHINE) ||
-         (ehdr->e_ident[EI_DATA] != ELFDATA) ||
-         (ehdr->e_type != ET_EXEC) )
+    if (ehdr->e_machine != ELFMACHINE)
     {
-        ERROR("Kernel not a Xen-compatible Elf image.");
+        xc_set_error(XC_INVALID_KERNEL,
+                     "Kernel ELF architecture '%d' does not match Xen architecture '%d'",
+                     ehdr->e_machine, ELFMACHINE);
+        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'",
+                     ehdr->e_ident[EI_CLASS], ELFCLASS);
+        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'",
+                     ehdr->e_ident[EI_DATA], ELFDATA);
+        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 +350,25 @@
         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 +424,9 @@
 
     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 +438,8 @@
         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 +461,8 @@
          (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 -ru xen-unstable-11405.orig/tools/libxc/xc_private.h xen-unstable-11405.new/tools/libxc/xc_private.h
--- xen-unstable-11405.orig/tools/libxc/xc_private.h	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xc_private.h	2006-09-18 15:20:36.000000000 -0400
@@ -56,25 +56,13 @@
 #define PPRINTF(_f, _a...)
 #endif
 
-#define ERR(_f, _a...) do {                     \
-    DPRINTF(_f ": %d\n" , ## _a, errno);        \
-    fflush(stderr); }                           \
-while (0)
-
-#define ERROR(_m, _a...)                        \
-do {                                            \
-    int __saved_errno = errno;                  \
-    DPRINTF("ERROR: " _m "\n" , ## _a );        \
-    errno = __saved_errno;                      \
-} while (0)
-
-#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)
+void xc_set_error(int code, const char *fmt, ...);
+
+#define ERR(_f, _a...) ERROR(_f, ## _a)
+
+#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))
 
 static inline void safe_munlock(const void *addr, size_t len)
 {
diff -ru xen-unstable-11405.orig/tools/libxc/xenctrl.h xen-unstable-11405.new/tools/libxc/xenctrl.h
--- xen-unstable-11405.orig/tools/libxc/xenctrl.h	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/libxc/xenctrl.h	2006-09-18 15:20:36.000000000 -0400
@@ -646,4 +646,43 @@
  */
 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
 
+
+typedef enum {
+  XC_ERROR_NONE = 0,
+  XC_INTERNAL_ERROR = 1,
+  XC_INVALID_KERNEL = 2,
+} xc_error_code;
+
+/*
+ * Return the code of the last error to occurr
+ */
+int xc_get_last_error_code(void);
+
+/*
+ * Return the message associated with the last error to occur
+ */
+const char *xc_get_last_error_message(void);
+
+/*
+ * Clear the last error
+ */
+void xc_clear_last_error(void);
+
+typedef void (*xc_error_handler)(int code, const char *msg);
+
+/*
+ * The default error handler which prints to stderr
+ */
+void xc_default_error_handler(int code, const char *msg);
+
+/*
+ * 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 -ru xen-unstable-11405.orig/tools/python/xen/lowlevel/xc/xc.c xen-unstable-11405.new/tools/python/xen/lowlevel/xc/xc.c
--- xen-unstable-11405.orig/tools/python/xen/lowlevel/xc/xc.c	2006-08-31 20:07:45.000000000 -0400
+++ xen-unstable-11405.new/tools/python/xen/lowlevel/xc/xc.c	2006-09-22 14:49:49.000000000 -0400
@@ -37,6 +37,23 @@
 static PyObject *dom_op(XcObject *self, PyObject *args,
                         int (*fn)(int, uint32_t));
 
+static PyObject *pyxc_error_to_exception(void)
+{
+    PyObject *err;
+    int code = xc_get_last_error_code();
+    const char *msg = xc_get_last_error_message();
+
+    if (msg)
+	err = Py_BuildValue("[is]", code, msg);
+    else
+	err = Py_BuildValue("[i]", code);
+
+    xc_clear_last_error();
+
+    PyErr_SetObject(xc_error, err);
+
+    return NULL;
+}
 
 static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
 {
@@ -50,7 +67,7 @@
         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;
@@ -95,12 +112,11 @@
     }
 
     if ( (ret = xc_domain_create(self->xc_handle, ssidref, handle, &dom)) < 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return PyInt_FromLong(dom);
 
 out_exception:
-    errno = EINVAL;
     PyErr_SetFromErrno(xc_error);
     return NULL;
 }
@@ -113,7 +129,7 @@
       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;
@@ -158,7 +174,7 @@
     }
   
     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;
@@ -178,7 +194,7 @@
         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;
@@ -209,13 +225,12 @@
     }
 
     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);
     return NULL;
 }
@@ -245,7 +260,7 @@
     if (nr_doms < 0)
     {
         free(info);
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
     }
 
     list = PyList_New(nr_doms);
@@ -299,10 +314,10 @@
 
     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,
@@ -352,9 +367,7 @@
                         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,
@@ -385,7 +398,7 @@
 
     if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
                       vcpus, pae, acpi, apic, store_evtchn, &store_mfn) != 0 )
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
 }
@@ -404,7 +417,7 @@
         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);
 }
@@ -425,7 +438,7 @@
     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;
@@ -447,7 +460,7 @@
 
     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);
 }
@@ -477,7 +490,7 @@
     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++)
@@ -515,25 +528,25 @@
     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,
@@ -566,7 +579,7 @@
         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;
@@ -583,7 +596,7 @@
     
     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}",
                          "domain",    domid,
@@ -611,7 +624,7 @@
     
     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;
@@ -641,7 +654,7 @@
         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);
@@ -668,7 +681,7 @@
     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;
@@ -683,7 +696,7 @@
         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,
@@ -699,7 +712,7 @@
         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;
@@ -726,7 +739,7 @@
     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;
@@ -748,7 +761,7 @@
     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;
@@ -771,7 +784,7 @@
     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;
@@ -794,7 +807,7 @@
     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;
@@ -834,7 +847,7 @@
         return NULL;
 
     if (fn(self->xc_handle, dom) != 0)
-        return PyErr_SetFromErrno(xc_error);
+        return pyxc_error_to_exception();
 
     Py_INCREF(zero);
     return zero;
@@ -1157,7 +1170,7 @@
 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;
     }
 

[-- 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-09-22 20:31 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-22 20:31 Daniel P. Berrange [this message]
2006-09-26 11:45 ` Error reporting capabilities for libxc Stephen C. Tweedie
2006-09-26 12:28   ` Keir Fraser
2006-09-26 13:18     ` Daniel P. Berrange
2006-09-26 18:40 ` Hollis Blanchard
2006-09-26 18:49   ` Daniel P. Berrange
2006-09-26 21:37   ` Muli Ben-Yehuda
  -- strict thread matches above, loose matches on Subject: below --
2006-09-26 12:58 Ian Pratt
2006-09-26 13:20 ` Daniel P. Berrange
2006-10-23 18:00 ` Daniel P. Berrange
2006-10-23 19:17   ` Anthony Liguori
2006-10-23 19:27     ` Daniel P. Berrange
2006-10-23 20:04       ` Anthony Liguori
2006-10-23 20:08         ` Daniel P. Berrange
2006-10-23 20:40   ` John Levon
2006-10-23 21:04   ` John Levon
2006-10-23 21:09     ` Daniel P. Berrange

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=20060922203153.GA1805@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.