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

Re: [Xen-devel] Error reporting capabilities for libxc



On Fri, 2006-09-22 at 21:31 +0100, Daniel P. Berrange wrote:
> 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

I agree; this is a serious problem that I suspect we've all run into at
least once.

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

Isn't the whole idea of "get_last_error" racy by design? I guess errno
has the same problem, but I'm not quite clear how it's solved there (a
magic array of errnos that is somehow sized to include all threads?)

> 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.

Thanks for sending this out! It's really helpful to see the design
early.

-- 
Hollis Blanchard
IBM Linux Technology Center


_______________________________________________
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®.