[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Error reporting capabilities for libxc



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@xxxxxxxxxx>

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: xen-libxc-errors7.patch
Description: Text document

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.