mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 03:25:20 +00: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>
|
||||
|
||||
* 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_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,
|
||||
|
@ -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,
|
||||
|
@ -37,5 +37,6 @@
|
||||
virSetErrorFunc;
|
||||
virConnCopyLastError;
|
||||
virConnResetLastError;
|
||||
virDefaultErrorFunc;
|
||||
local: *;
|
||||
};
|
||||
|
52
src/sexpr.c
52
src/sexpr.c
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
19
src/virsh.c
19
src/virsh.c
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user