* 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.
Daniel
This commit is contained in:
Daniel Veillard 2006-02-27 21:34:28 +00:00
parent 739dfb531d
commit 87d338374a
8 changed files with 144 additions and 19 deletions

View File

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

View 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,

View 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,

View File

@ -37,5 +37,6 @@
virSetErrorFunc;
virConnCopyLastError;
virConnResetLastError;
virDefaultErrorFunc;
local: *;
};

View File

@ -13,6 +13,7 @@
#define _GNU_SOURCE
#include "sexpr.h"
#include "internal.h"
#include <malloc.h>
#include <string.h>
@ -20,6 +21,26 @@
#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);
}
/**

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

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

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