* TODO: updated, and added python hooks for error handling

* include/virterror.h src/virterror.c src/xml.c: error interception
  and reporting should be done.
Daniel
This commit is contained in:
Daniel Veillard 2006-02-27 22:32:54 +00:00
parent 5548938d62
commit 8bc437e412
6 changed files with 116 additions and 17 deletions

View File

@ -1,3 +1,9 @@
Mon Feb 27 17:33:16 EST 2006 Daniel Veillard <veillard@redhat.com>
* TODO: updated, and added python hooks for error handling
* include/virterror.h src/virterror.c src/xml.c: error interception
and reporting should be done.
Mon Feb 27 16:42:46 EST 2006 Daniel Veillard <veillard@redhat.com>
* src/libvirt.c src/xen_internal.[ch]: virConnectOpenReadOnly()

5
TODO
View File

@ -1,7 +1,5 @@
Absolute TODOs:
- thread protection, reentrancy, refcounting, etc ...
- Error API. probably similar to libxml2 structured API
- extract error messages from the Xend rpc
TODO:
- Create() API, how do we best keep flexibility and allow various
@ -13,6 +11,7 @@ TODO:
- in python bindings raise an exception if a lookup or connection fails
to return a non-None object
- Add uuid to XML format
- add error handling hooks at the python level
virsh TODO:
- decide where will be default directory for domains configurations (/etc/xen/domains/* ?)
@ -46,3 +45,5 @@ Done:
- the CreateLinux() API is a first step toward a final Create()
- documentation and examples on using the toolkit
- UUID based lookup and naming
- Error API similar to libxml2 structured API
- extract error messages from the Xend rpc

View File

@ -41,6 +41,7 @@ typedef enum {
VIR_FROM_XEN, /* Error at Xen hypervisor layer */
VIR_FROM_XEND, /* Error at connection with xend daemon */
VIR_FROM_SEXPR, /* Error in the S-Epression code */
VIR_FROM_XML, /* Error in the XML code */
VIR_FROM_DOM, /* Error when operating on a domain */
} virErrorDomain;
@ -89,6 +90,14 @@ typedef enum {
VIR_ERR_SEXPR_SERIAL,/* failure to serialize an S-Expr */
VIR_ERR_NO_XEN,/* could not open Xen hypervisor control */
VIR_ERR_XEN_CALL,/* failure doing an hypervisor call */
VIR_ERR_OS_TYPE, /* unknown OS type */
VIR_ERR_NO_KERNEL, /* missing kernel informations */
VIR_ERR_NO_ROOT, /* missing root device informations */
VIR_ERR_NO_SOURCE, /* missing source device informations */
VIR_ERR_NO_TARGET, /* missing target device informations */
VIR_ERR_NO_NAME, /* missing domain name informations */
VIR_ERR_NO_OS, /* missing domain OS informations */
VIR_ERR_NO_DEVICE, /* missing domain devices informations */
} virErrorNumber;
/**

View File

@ -41,6 +41,7 @@ typedef enum {
VIR_FROM_XEN, /* Error at Xen hypervisor layer */
VIR_FROM_XEND, /* Error at connection with xend daemon */
VIR_FROM_SEXPR, /* Error in the S-Epression code */
VIR_FROM_XML, /* Error in the XML code */
VIR_FROM_DOM, /* Error when operating on a domain */
} virErrorDomain;
@ -89,6 +90,14 @@ typedef enum {
VIR_ERR_SEXPR_SERIAL,/* failure to serialize an S-Expr */
VIR_ERR_NO_XEN,/* could not open Xen hypervisor control */
VIR_ERR_XEN_CALL,/* failure doing an hypervisor call */
VIR_ERR_OS_TYPE, /* unknown OS type */
VIR_ERR_NO_KERNEL, /* missing kernel informations */
VIR_ERR_NO_ROOT, /* missing root device informations */
VIR_ERR_NO_SOURCE, /* missing source device informations */
VIR_ERR_NO_TARGET, /* missing target device informations */
VIR_ERR_NO_NAME, /* missing domain name informations */
VIR_ERR_NO_OS, /* missing domain OS informations */
VIR_ERR_NO_DEVICE, /* missing domain devices informations */
} virErrorNumber;
/**

View File

@ -424,6 +424,51 @@ __virErrorMsg(virErrorNumber error, const char *info) {
case VIR_ERR_XEN_CALL:
errmsg = "failed Xen syscall %s %d";
break;
case VIR_ERR_OS_TYPE:
if (info == NULL)
errmsg = "unknown OS type";
else
errmsg = "unknown OS type %s";
break;
case VIR_ERR_NO_KERNEL:
errmsg = "missing kernel informations";
break;
case VIR_ERR_NO_ROOT:
if (info == NULL)
errmsg = "missing root device informations";
else
errmsg = "missing root device informations in %s";
break;
case VIR_ERR_NO_SOURCE:
if (info == NULL)
errmsg = "missing source informations for device";
else
errmsg = "missing source informations for device %s";
break;
case VIR_ERR_NO_TARGET:
if (info == NULL)
errmsg = "missing target informations for device";
else
errmsg = "missing target informations for device %s";
break;
case VIR_ERR_NO_NAME:
if (info == NULL)
errmsg = "missing domain name informations";
else
errmsg = "missing domain name informations in %s";
break;
case VIR_ERR_NO_OS:
if (info == NULL)
errmsg = "missing operating system informations";
else
errmsg = "missing operating system informations for %s";
break;
case VIR_ERR_NO_DEVICE:
if (info == NULL)
errmsg = "missing devices informations";
else
errmsg = "missing devices informations for %s";
break;
}
return(errmsg);
}

View File

@ -23,6 +23,27 @@
#include "sexpr.h"
#include "xml.h"
/**
* virXenError:
* @conn: the connection if available
* @error: the error number
* @info: extra information string
*
* Handle an error at the xend daemon interface
*/
static void
virXMLError(virErrorNumber error, const char *info, int value) {
const char *errmsg;
if (error == VIR_ERR_OK)
return;
errmsg = __virErrorMsg(error, info);
__virRaiseError(NULL, NULL, VIR_FROM_XML, error, VIR_ERR_ERROR,
errmsg, info, NULL, value, 0, errmsg, info,
value);
}
/**
* virBufferGrow:
* @buf: the buffer
@ -44,6 +65,7 @@ virBufferGrow(virBufferPtr buf, unsigned int len) {
newbuf = (char *) realloc(buf->content, size);
if (newbuf == NULL) {
virXMLError(VIR_ERR_NO_MEMORY, "growing buffer", size);
return(-1);
}
buf->content = newbuf;
@ -514,11 +536,12 @@ virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf) {
}
if ((type != NULL) && (!xmlStrEqual(type, BAD_CAST "linux"))) {
/* VIR_ERR_OS_TYPE */
virXMLError(VIR_ERR_OS_TYPE, (const char *) type, 0);
return(-1);
}
virBufferAdd(buf, "(linux ", 7);
if (kernel == NULL) {
/* VIR_ERR_NO_KERNEL */
virXMLError(VIR_ERR_NO_KERNEL, NULL, 0);
return(-1);
}
virBufferVSprintf(buf, "(kernel '%s')", (const char *) kernel);
@ -528,7 +551,7 @@ virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf) {
const xmlChar *base, *tmp;
/* need to extract root info from command line */
if (cmdline == NULL) {
/* VIR_ERR_NO_ROOT */
virXMLError(VIR_ERR_NO_ROOT, (const char *) cmdline, 0);
return(-1);
}
base = cmdline;
@ -548,7 +571,7 @@ virDomainParseXMLOSDesc(xmlNodePtr node, virBufferPtr buf) {
tmp = base;
while ((*tmp != 0) && (*tmp != ' ') && (*tmp != '\t')) tmp++;
if (tmp == base) {
/* VIR_ERR_NO_ROOT */
virXMLError(VIR_ERR_NO_ROOT, (const char *) cmdline, 0);
return(-1);
}
root = xmlStrndup(base, tmp - base);
@ -612,13 +635,14 @@ virDomainParseXMLDiskDesc(xmlNodePtr node, virBufferPtr buf) {
}
if (source == NULL) {
/* VIR_ERR_NO_SOURCE */
virXMLError(VIR_ERR_NO_SOURCE, (const char *) target, 0);
if (target != NULL)
xmlFree(target);
return(-1);
}
if (target == NULL) {
/* VIR_ERR_NO_TARGET */
virXMLError(VIR_ERR_NO_TARGET, (const char *) source, 0);
if (source != NULL)
xmlFree(source);
return(-1);
@ -733,7 +757,7 @@ char *
virDomainParseXMLDesc(const char *xmldesc, char **name) {
xmlDocPtr xml = NULL;
xmlNodePtr node;
char *ret = NULL;
char *ret = NULL, *nam = NULL;
virBuffer buf;
xmlChar *prop;
xmlXPathObjectPtr obj = NULL;
@ -778,12 +802,15 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
/* VIR_ERR_NO_NAME */
virXMLError(VIR_ERR_NO_NAME, xmldesc, 0);
goto error;
}
virBufferVSprintf(&buf, "(name '%s')", obj->stringval);
if (name != NULL)
*name = strdup((const char *) obj->stringval);
nam = strdup((const char *) obj->stringval);
if (nam == NULL) {
virXMLError(VIR_ERR_NO_MEMORY, "copying name", 0);
goto error;
}
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "number(/domain/memory[1])", ctxt);
@ -812,7 +839,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL) ||
(obj->nodesetval->nodeNr != 1)) {
/* VIR_ERR_NO_OS */
virXMLError(VIR_ERR_NO_OS, nam, 0);
goto error;
}
res = virDomainParseXMLOSDesc(obj->nodesetval->nodeTab[0], &buf);
@ -827,7 +854,7 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL) ||
(obj->nodesetval->nodeNr < 1)) {
/* VIR_ERR_NO_DEVICE */
virXMLError(VIR_ERR_NO_DEVICE, nam, 0);
goto error;
}
for (i = 0;i < obj->nodesetval->nodeNr;i++) {
@ -859,15 +886,17 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml);
if (name != NULL)
*name = nam;
return(ret);
error:
if (name != NULL) {
if (*name != NULL)
free(*name);
if (nam != NULL)
free(nam);
if (name != NULL)
*name = NULL;
}
if (obj != NULL)
xmlXPathFreeObject(obj);
if (ctxt != NULL)