From: Daniel Veillard Date: Mon, 27 Feb 2006 22:32:54 +0000 (+0000) Subject: * TODO: updated, and added python hooks for error handling X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=8bc437e412580815db2b9451eabaed20ea91d71e;p=libvirt.git * 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 --- diff --git a/ChangeLog b/ChangeLog index 29dd83d4b4..16c80bab25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Feb 27 17:33:16 EST 2006 Daniel Veillard + + * 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 * src/libvirt.c src/xen_internal.[ch]: virConnectOpenReadOnly() diff --git a/TODO b/TODO index 82e47dc4fc..dc51e2dbda 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a5c9050233..eb28be0827 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -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; /** diff --git a/include/virterror.h b/include/virterror.h index a5c9050233..eb28be0827 100644 --- a/include/virterror.h +++ b/include/virterror.h @@ -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; /** diff --git a/src/virterror.c b/src/virterror.c index 5d24201aae..c3510bcc0d 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -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); } diff --git a/src/xml.c b/src/xml.c index fd97a9e9e0..2e7b2da1c4 100644 --- a/src/xml.c +++ b/src/xml.c @@ -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)