+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()
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
- 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/* ?)
- 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
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;
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;
/**
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;
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;
/**
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);
}
#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
newbuf = (char *) realloc(buf->content, size);
if (newbuf == NULL) {
+ virXMLError(VIR_ERR_NO_MEMORY, "growing buffer", size);
return(-1);
}
buf->content = newbuf;
}
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);
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;
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);
}
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);
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;
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);
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);
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++) {
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)