mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
* 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:
parent
739dfb531d
commit
87d338374a
@ -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>
|
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
|
* include/virterror.h src/virterror.c src/xend_internal.c: more work
|
||||||
|
@ -86,6 +86,9 @@ typedef enum {
|
|||||||
VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
|
VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
|
||||||
VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
|
VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
|
||||||
VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */
|
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;
|
} virErrorNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +114,7 @@ virErrorPtr virConnGetLastError (virConnectPtr conn);
|
|||||||
void virConnResetLastError (virConnectPtr conn);
|
void virConnResetLastError (virConnectPtr conn);
|
||||||
int virCopyLastError (virErrorPtr to);
|
int virCopyLastError (virErrorPtr to);
|
||||||
|
|
||||||
|
void virDefaultErrorFunc (virErrorPtr err);
|
||||||
void virSetErrorFunc (void *userData,
|
void virSetErrorFunc (void *userData,
|
||||||
virErrorFunc handler);
|
virErrorFunc handler);
|
||||||
void virConnSetErrorFunc (virConnectPtr conn,
|
void virConnSetErrorFunc (virConnectPtr conn,
|
||||||
|
@ -86,6 +86,9 @@ typedef enum {
|
|||||||
VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
|
VIR_ERR_GET_FAILED,/* a HTTP GET command to failed */
|
||||||
VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
|
VIR_ERR_POST_FAILED,/* a HTTP POST command to failed */
|
||||||
VIR_ERR_HTTP_ERROR,/* unexpected HTTP error code */
|
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;
|
} virErrorNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +114,7 @@ virErrorPtr virConnGetLastError (virConnectPtr conn);
|
|||||||
void virConnResetLastError (virConnectPtr conn);
|
void virConnResetLastError (virConnectPtr conn);
|
||||||
int virCopyLastError (virErrorPtr to);
|
int virCopyLastError (virErrorPtr to);
|
||||||
|
|
||||||
|
void virDefaultErrorFunc (virErrorPtr err);
|
||||||
void virSetErrorFunc (void *userData,
|
void virSetErrorFunc (void *userData,
|
||||||
virErrorFunc handler);
|
virErrorFunc handler);
|
||||||
void virConnSetErrorFunc (virConnectPtr conn,
|
void virConnSetErrorFunc (virConnectPtr conn,
|
||||||
|
@ -37,5 +37,6 @@
|
|||||||
virSetErrorFunc;
|
virSetErrorFunc;
|
||||||
virConnCopyLastError;
|
virConnCopyLastError;
|
||||||
virConnResetLastError;
|
virConnResetLastError;
|
||||||
|
virDefaultErrorFunc;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
52
src/sexpr.c
52
src/sexpr.c
@ -13,6 +13,7 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include "sexpr.h"
|
#include "sexpr.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -20,6 +21,26 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.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:
|
* sexpr_new:
|
||||||
*
|
*
|
||||||
@ -34,6 +55,7 @@ sexpr_new(void)
|
|||||||
|
|
||||||
ret = (struct sexpr *) malloc(sizeof(*ret));
|
ret = (struct sexpr *) malloc(sizeof(*ret));
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
|
virSexprError(VIR_ERR_NO_MEMORY, "failed to allocate a node");
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
ret->kind = SEXPR_NIL;
|
ret->kind = SEXPR_NIL;
|
||||||
@ -203,26 +225,26 @@ sexpr2string(struct sexpr * sexpr, char *buffer, size_t n_buffer)
|
|||||||
case SEXPR_CONS:
|
case SEXPR_CONS:
|
||||||
tmp = snprintf(buffer + ret, n_buffer - ret, "(");
|
tmp = snprintf(buffer + ret, n_buffer - ret, "(");
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
tmp = sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
|
tmp = sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
while (sexpr->cdr->kind != SEXPR_NIL) {
|
while (sexpr->cdr->kind != SEXPR_NIL) {
|
||||||
sexpr = sexpr->cdr;
|
sexpr = sexpr->cdr;
|
||||||
tmp = snprintf(buffer + ret, n_buffer - ret, " ");
|
tmp = snprintf(buffer + ret, n_buffer - ret, " ");
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
tmp = sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
|
tmp = sexpr2string(sexpr->car, buffer + ret, n_buffer - ret);
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
}
|
}
|
||||||
tmp = snprintf(buffer + ret, n_buffer - ret, ")");
|
tmp = snprintf(buffer + ret, n_buffer - ret, ")");
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
break;
|
break;
|
||||||
case SEXPR_VALUE:
|
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",
|
tmp = snprintf(buffer + ret, n_buffer - ret, "%s",
|
||||||
sexpr->value);
|
sexpr->value);
|
||||||
if (tmp == 0)
|
if (tmp == 0)
|
||||||
return(0);
|
goto error;
|
||||||
ret += tmp;
|
ret += tmp;
|
||||||
break;
|
break;
|
||||||
case SEXPR_NIL:
|
case SEXPR_NIL:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return(0);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
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))
|
#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);
|
ret->value = strndup(start, ptr - start);
|
||||||
|
if (ret->value == NULL) {
|
||||||
|
virSexprError(VIR_ERR_NO_MEMORY, "failed to copy a string");
|
||||||
|
}
|
||||||
|
|
||||||
if (*ptr == '\'')
|
if (*ptr == '\'')
|
||||||
ptr++;
|
ptr++;
|
||||||
@ -330,14 +359,23 @@ _string2sexpr(const char *buffer, size_t * end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret->value = strndup(start, ptr - start);
|
ret->value = strndup(start, ptr - start);
|
||||||
|
if (ret->value == NULL) {
|
||||||
|
virSexprError(VIR_ERR_NO_MEMORY, "failed to copy a string");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->kind = SEXPR_VALUE;
|
ret->kind = SEXPR_VALUE;
|
||||||
|
if (ret->value == NULL)
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
*end = ptr - buffer;
|
*end = ptr - buffer;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
sexpr_free(ret);
|
||||||
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
19
src/virsh.c
19
src/virsh.c
@ -14,6 +14,7 @@
|
|||||||
#define _GNU_SOURCE /* isblank() */
|
#define _GNU_SOURCE /* isblank() */
|
||||||
|
|
||||||
#include "libvirt.h"
|
#include "libvirt.h"
|
||||||
|
#include "virterror.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -56,6 +57,21 @@ typedef enum {
|
|||||||
VSH_DEBUG5
|
VSH_DEBUG5
|
||||||
} vshOutType;
|
} 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:
|
* virsh command line grammar:
|
||||||
*
|
*
|
||||||
@ -1485,6 +1501,9 @@ vshInit(vshControl *ctl) {
|
|||||||
|
|
||||||
ctl->uid = getuid();
|
ctl->uid = getuid();
|
||||||
|
|
||||||
|
/* set up the library error handler */
|
||||||
|
virSetErrorFunc(NULL, virshErrorHandler);
|
||||||
|
|
||||||
/* basic connection to hypervisor */
|
/* basic connection to hypervisor */
|
||||||
if (ctl->uid == 0)
|
if (ctl->uid == 0)
|
||||||
ctl->conn = virConnectOpen(NULL);
|
ctl->conn = virConnectOpen(NULL);
|
||||||
|
@ -212,13 +212,13 @@ virConnSetErrorFunc(virConnectPtr conn, void *userData, virErrorFunc handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virReportError:
|
* virDefaultErrorFunc:
|
||||||
* @err: pointer to the error.
|
* @err: pointer to the error.
|
||||||
*
|
*
|
||||||
* Internal routine reporting an error to stderr.
|
* Default routine reporting an error to stderr.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
virReportError(virErrorPtr err) {
|
virDefaultErrorFunc(virErrorPtr err) {
|
||||||
const char *lvl = "", *dom = "", *domain = "";
|
const char *lvl = "", *dom = "", *domain = "";
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ __virRaiseError(virConnectPtr conn, virDomainPtr dom,
|
|||||||
if (handler != NULL) {
|
if (handler != NULL) {
|
||||||
handler(userData, to);
|
handler(userData, to);
|
||||||
} else {
|
} else {
|
||||||
virReportError(to);
|
virDefaultErrorFunc(to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +407,22 @@ __virErrorMsg(virErrorNumber error, const char *info) {
|
|||||||
errmsg = "got unknown HTTP error code %d";
|
errmsg = "got unknown HTTP error code %d";
|
||||||
break;
|
break;
|
||||||
case VIR_ERR_UNKNOWN_HOST:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return(errmsg);
|
return(errmsg);
|
||||||
|
@ -36,6 +36,27 @@ typedef struct hypercall_struct
|
|||||||
|
|
||||||
#define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
|
#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:
|
* xenHypervisorOpen:
|
||||||
*
|
*
|
||||||
@ -47,8 +68,10 @@ int xenHypervisorOpen(void) {
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
|
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(-1);
|
||||||
|
}
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -92,14 +115,21 @@ xenHypervisorDoOp(int handle, dom0_op_t *op) {
|
|||||||
hc.op = __HYPERVISOR_dom0_op;
|
hc.op = __HYPERVISOR_dom0_op;
|
||||||
hc.arg[0] = (unsigned long)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);
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
|
cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
|
||||||
ret = ioctl(handle, cmd, (unsigned long) &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;
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return(-1);
|
return(-1);
|
||||||
@ -128,8 +158,10 @@ xenHypervisorGetVersion(int handle) {
|
|||||||
cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
|
cmd = _IOC(_IOC_NONE, 'P', 0, sizeof(hc));
|
||||||
ret = ioctl(handle, cmd, (unsigned long) &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);
|
return(0);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* use unsigned long in case the version grows behind expectations
|
* use unsigned long in case the version grows behind expectations
|
||||||
* allowed by int
|
* allowed by int
|
||||||
@ -157,8 +189,10 @@ xenHypervisorGetDomainInfo(int handle, int domain, dom0_getdomaininfo_t *info) {
|
|||||||
|
|
||||||
memset(info, 0, sizeof(dom0_getdomaininfo_t));
|
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);
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
op.cmd = DOM0_GETDOMAININFOLIST;
|
op.cmd = DOM0_GETDOMAININFOLIST;
|
||||||
op.u.getdomaininfolist.first_domain = (domid_t) domain;
|
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);
|
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;
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return(-1);
|
return(-1);
|
||||||
|
Loading…
Reference in New Issue
Block a user