]> xenbits.xensource.com Git - libvirt.git/commitdiff
* include/virterror.h src/libvirt_sym.version: exported
authorDaniel Veillard <veillard@redhat.com>
Mon, 27 Feb 2006 21:34:28 +0000 (21:34 +0000)
committerDaniel Veillard <veillard@redhat.com>
Mon, 27 Feb 2006 21:34:28 +0000 (21:34 +0000)
  virDefaultErrorFunc()
* src/sexpr.c src/xen_internal.c src/virterror.c include/virterror.h:
  adding more error reporting though the code, nearly complete.
* src/sexpr.c: added specific error function to avoid an error report.
Daniel

ChangeLog
include/libvirt/virterror.h
include/virterror.h
src/libvirt_sym.version
src/sexpr.c
src/virsh.c
src/virterror.c
src/xen_internal.c

index e900a14a3f5db3ee8f185d44f480295dc1d84c07..e97ae328d139762bb0416546c405e72faca010f0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Feb 27 16:32:55 EST 2006 Daniel Veillard <veillard@redhat.com>
+
+       * include/virterror.h src/libvirt_sym.version: exported
+         virDefaultErrorFunc()
+       * src/sexpr.c src/xen_internal.c src/virterror.c include/virterror.h:
+         adding more error reporting though the code, nearly complete.
+       * src/sexpr.c: added specific error function to avoid an error report.
+
 Mon Feb 27 14:56:57 EST 2006 Daniel Veillard <veillard@redhat.com>
 
        * include/virterror.h src/virterror.c src/xend_internal.c: more work
index a81bb83a7f42fb84818992862e530dcd07596411..a5c90502333e0e06ded2292db798d1efc0813fd5 100644 (file)
@@ -86,6 +86,9 @@ typedef enum {
     VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
     VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
     VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */
+    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 */
 } virErrorNumber;
 
 /**
@@ -111,6 +114,7 @@ virErrorPtr         virConnGetLastError     (virConnectPtr conn);
 void                   virConnResetLastError   (virConnectPtr conn);
 int                    virCopyLastError        (virErrorPtr to);
 
+void                   virDefaultErrorFunc     (virErrorPtr err);
 void                   virSetErrorFunc         (void *userData,
                                                 virErrorFunc handler);
 void                   virConnSetErrorFunc     (virConnectPtr conn,
index a81bb83a7f42fb84818992862e530dcd07596411..a5c90502333e0e06ded2292db798d1efc0813fd5 100644 (file)
@@ -86,6 +86,9 @@ typedef enum {
     VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
     VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
     VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */
+    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 */
 } virErrorNumber;
 
 /**
@@ -111,6 +114,7 @@ virErrorPtr         virConnGetLastError     (virConnectPtr conn);
 void                   virConnResetLastError   (virConnectPtr conn);
 int                    virCopyLastError        (virErrorPtr to);
 
+void                   virDefaultErrorFunc     (virErrorPtr err);
 void                   virSetErrorFunc         (void *userData,
                                                 virErrorFunc handler);
 void                   virConnSetErrorFunc     (virConnectPtr conn,
index e8c507d9157c2ac1f5ff29967462889563d3f52d..85e2694b1150ebe3696854ed6f42cb994d318977 100644 (file)
@@ -37,5 +37,6 @@
        virSetErrorFunc;
        virConnCopyLastError;
        virConnResetLastError;
+       virDefaultErrorFunc;
     local: *;
 };
index e04639bd71a22ada2f0e4061393ac87c82223bbb..105ed3ec5cc46a85429ce303fde968605e3c5c6f 100644 (file)
@@ -13,6 +13,7 @@
 #define _GNU_SOURCE
 
 #include "sexpr.h"
+#include "internal.h"
 
 #include <malloc.h>
 #include <string.h>
 #include <ctype.h>
 #include <errno.h>
 
+/**
+ * virSexprError:
+ * @conn: the connection if available
+ * @error: the error noumber
+ * @info: extra information string
+ *
+ * Handle an error in the S-Expression code
+ */
+static void
+virSexprError(virErrorNumber error, const char *info) {
+    const char *errmsg;
+    
+    if (error == VIR_ERR_OK)
+        return;
+
+    errmsg = __virErrorMsg(error, info);
+    __virRaiseError(NULL, NULL, VIR_FROM_SEXPR, error, VIR_ERR_ERROR,
+                    errmsg, info, NULL, 0, 0, errmsg, info);
+}
+
 /**
  * sexpr_new:
  *
@@ -34,6 +55,7 @@ sexpr_new(void)
 
     ret = (struct sexpr *) malloc(sizeof(*ret));
     if (ret == NULL) {
+        virSexprError(VIR_ERR_NO_MEMORY, "failed to allocate a node");
         return(NULL);
     }
     ret->kind = SEXPR_NIL;
@@ -203,26 +225,26 @@ sexpr2string(struct sexpr * sexpr, char *buffer, size_t n_buffer)
         case SEXPR_CONS:
             tmp = snprintf(buffer + ret, n_buffer - ret, "(");
            if (tmp == 0)
-               return(0);
+               goto error;
            ret += tmp;
            tmp =  sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
            if (tmp == 0)
-               return(0);
+               goto error;
            ret += tmp;
             while (sexpr->cdr->kind != SEXPR_NIL) {
                 sexpr = sexpr->cdr;
                 tmp = snprintf(buffer + ret, n_buffer - ret, " ");
                if (tmp == 0)
-                   return(0);
+                   goto error;
                ret += tmp;
                 tmp = sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
                if (tmp == 0)
-                   return(0);
+                   goto error;
                ret += tmp;
             }
             tmp = snprintf(buffer + ret, n_buffer - ret, ")");
            if (tmp == 0)
-               return(0);
+               goto error;
            ret += tmp;
             break;
         case SEXPR_VALUE:
@@ -233,16 +255,20 @@ sexpr2string(struct sexpr * sexpr, char *buffer, size_t n_buffer)
                 tmp = snprintf(buffer + ret, n_buffer - ret, "%s",
                                sexpr->value);
            if (tmp == 0)
-               return(0);
+               goto error;
            ret += tmp;
             break;
         case SEXPR_NIL:
             break;
        default:
-           return(0);
+           goto error;
     }
 
     return(ret);
+error:
+    buffer[n_buffer - 1] = 0;
+    virSexprError(VIR_ERR_SEXPR_SERIAL, buffer);
+    return(0);
 }
 
 #define IS_SPACE(c) ((c == 0x20) || (c == 0x9) || (c == 0xD) || (c == 0xA))
@@ -319,6 +345,9 @@ _string2sexpr(const char *buffer, size_t * end)
             }
 
             ret->value = strndup(start, ptr - start);
+           if (ret->value == NULL) {
+               virSexprError(VIR_ERR_NO_MEMORY, "failed to copy a string");
+           }
 
             if (*ptr == '\'')
                 ptr++;
@@ -330,14 +359,23 @@ _string2sexpr(const char *buffer, size_t * end)
             }
 
             ret->value = strndup(start, ptr - start);
+           if (ret->value == NULL) {
+               virSexprError(VIR_ERR_NO_MEMORY, "failed to copy a string");
+           }
         }
 
         ret->kind = SEXPR_VALUE;
+       if (ret->value == NULL)
+           goto error;
     }
 
     *end = ptr - buffer;
 
     return ret;
+
+error:
+    sexpr_free(ret);
+    return(NULL);
 }
 
 /**
index 523126e51b74f89b84ce9ad6f716218f8bdbd526..faeb4d7e52227edc1145d16ed8b643cf5a010fde 100644 (file)
@@ -14,6 +14,7 @@
 #define _GNU_SOURCE    /* isblank() */
 
 #include "libvirt.h"
+#include "virterror.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -56,6 +57,21 @@ typedef enum {
     VSH_DEBUG5
 } vshOutType;
 
+/*
+ * The error handler for virtsh
+ */
+static void
+virshErrorHandler(void *unused, virErrorPtr error) {
+    if ((unused != NULL) || (error == NULL))
+        return;
+
+    /* Suppress the VIR_ERR_NO_XEN error which fails as non-root */
+    if ((error->code == VIR_ERR_NO_XEN) || (error->code == VIR_ERR_OK))
+        return;
+
+    virDefaultErrorFunc(error);
+}
+
 /*
  * virsh command line grammar:
  *
@@ -1485,6 +1501,9 @@ vshInit(vshControl *ctl) {
 
     ctl->uid = getuid();
     
+    /* set up the library error handler */
+    virSetErrorFunc(NULL, virshErrorHandler);
+    
     /* basic connection to hypervisor */
     if (ctl->uid == 0)
         ctl->conn = virConnectOpen(NULL);
index f385cc3368a3286479f802e13424d9f4a520d30f..5d24201aae1363c0a44e871066351562a2aa7ffc 100644 (file)
@@ -212,13 +212,13 @@ virConnSetErrorFunc(virConnectPtr conn, void *userData, virErrorFunc handler) {
 }
 
 /**
- * virReportError:
+ * virDefaultErrorFunc:
  * @err: pointer to the error.
  *
- * Internal routine reporting an error to stderr.
+ * Default routine reporting an error to stderr.
  */
-static void
-virReportError(virErrorPtr err) {
+void
+virDefaultErrorFunc(virErrorPtr err) {
     const char *lvl = "", *dom = "", *domain = "";
     int len;
 
@@ -337,7 +337,7 @@ __virRaiseError(virConnectPtr conn, virDomainPtr dom,
     if (handler != NULL) {
         handler(userData, to);
     } else {
-        virReportError(to);
+        virDefaultErrorFunc(to);
     }
 }
 
@@ -407,7 +407,22 @@ __virErrorMsg(virErrorNumber error, const char *info) {
            errmsg = "got unknown HTTP error code %d";
            break;
        case VIR_ERR_UNKNOWN_HOST:
-           errmsg = "Unknown host %s";
+           errmsg = "unknown host %s";
+           break;
+       case VIR_ERR_SEXPR_SERIAL:
+           if (info != NULL)
+               errmsg = "failed to serialize S-Expr: %s";
+           else
+               errmsg = "failed to serialize S-Expr";
+           break;
+       case VIR_ERR_NO_XEN:
+           if (info == NULL)
+               errmsg = "could not use Xen hypervisor entry";
+           else
+               errmsg = "could not use Xen hypervisor entry %s";
+           break;
+       case VIR_ERR_XEN_CALL:
+           errmsg = "failed Xen syscall %s %d";
            break;
     }
     return(errmsg);
index 67260b20540c09de6ba301923c261bd926fd3f1a..f04c3674a58ebbf732d347287ece2d2ea0518572 100644 (file)
@@ -36,6 +36,27 @@ typedef struct hypercall_struct
 
 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
 
+/**
+ * virXenError:
+ * @conn: the connection if available
+ * @error: the error number
+ * @info: extra information string
+ *
+ * Handle an error at the xend daemon interface
+ */
+static void
+virXenError(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_XEN, error, VIR_ERR_ERROR,
+                    errmsg, info, NULL, value, 0, errmsg, info,
+                   value);
+}
+
 /**
  * xenHypervisorOpen:
  *
@@ -47,8 +68,10 @@ int xenHypervisorOpen(void) {
     int ret;
 
     ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
-    if (ret < 0)
+    if (ret < 0) {
+        virXenError(VIR_ERR_NO_XEN, XEN_HYPERVISOR_SOCKET, 0);
         return(-1);
+    }
 
     return(ret);
 }
@@ -92,14 +115,21 @@ xenHypervisorDoOp(int handle, dom0_op_t *op) {
     hc.op = __HYPERVISOR_dom0_op;
     hc.arg[0] = (unsigned long)op; 
 
-    if (mlock(op, sizeof(dom0_op_t)) < 0)
+    if (mlock(op, sizeof(dom0_op_t)) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " locking", sizeof(dom0_op_t));
         return(-1);
+    }
 
     cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
     ret = ioctl(handle, cmd, (unsigned long) &hc);
+    if (ret < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " ioctl ", cmd);
+    }
 
-    if (munlock(op, sizeof(dom0_op_t)) < 0)
+    if (munlock(op, sizeof(dom0_op_t)) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " releasing", sizeof(dom0_op_t));
         ret = -1;
+    }
 
     if (ret < 0)
         return(-1);
@@ -128,8 +158,10 @@ xenHypervisorGetVersion(int handle) {
     cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
     ret = ioctl(handle, cmd, (unsigned long) &hc);
 
-    if (ret < 0)
+    if (ret < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " getting version ", XENVER_version);
         return(0);
+    }
     /*
      * use unsigned long in case the version grows behind expectations
      * allowed by int
@@ -157,8 +189,10 @@ xenHypervisorGetDomainInfo(int handle, int domain, dom0_getdomaininfo_t *info) {
 
     memset(info, 0, sizeof(dom0_getdomaininfo_t));
 
-    if (mlock(info, sizeof(dom0_getdomaininfo_t)) < 0)
+    if (mlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " locking", sizeof(dom0_getdomaininfo_t));
         return(-1);
+    }
 
     op.cmd = DOM0_GETDOMAININFOLIST;
     op.u.getdomaininfolist.first_domain = (domid_t) domain;
@@ -169,8 +203,10 @@ xenHypervisorGetDomainInfo(int handle, int domain, dom0_getdomaininfo_t *info) {
 
     ret = xenHypervisorDoOp(handle, &op);
 
-    if (munlock(info, sizeof(dom0_getdomaininfo_t)) < 0)
+    if (munlock(info, sizeof(dom0_getdomaininfo_t)) < 0) {
+        virXenError(VIR_ERR_XEN_CALL, " release", sizeof(dom0_getdomaininfo_t));
         ret = -1;
+    }
 
     if (ret < 0)
         return(-1);