From 38e7a75efaab8a6a709cbad8342bca4a45ead8cc Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] * libvirt/libvirt.mli, libvirt/libvirt.ml: New error numbers in base libvirt. * libvirt/libvirt_c.c: Gracefully handle the case where libvirt throws an error number we have not heard of before (eg. when dynamic linking with newer libvirt). * configure.ac: Check exists. * configure.ac: Version 0.3.3.4. --- ChangeLog | 16 ++++++++++++ configure.ac | 7 +++++- libvirt/libvirt.ml | 32 ++++++++++++++++-------- libvirt/libvirt.mli | 25 +++++++++++++------ libvirt/libvirt_c.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 130 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index b63912b..b3247ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2007-11-20 Richard Jones + + * libvirt/libvirt.mli, libvirt/libvirt.ml: New error numbers + in base libvirt. + * libvirt/libvirt_c.c: Gracefully handle the case where libvirt + throws an error number we have not heard of before (eg. when + dynamic linking with newer libvirt). + * configure.ac: Check exists. + * configure.ac: Version 0.3.3.4. + * virt-top/virt-top.pod: Fixed ocaml libvirt website URI in manpage. + +2007-11-19 Richard Jones + + * virt-top/virt-top.pod: Example connection URIs in virt-top manpage + (bug 390691). + 2007-11-14 Richard Jones * libvirt/libvirt.mli: Added filename = string type to clarify diff --git a/configure.ac b/configure.ac index 635b49a..c238643 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(ocaml-libvirt,0.3.3.3) +AC_INIT(ocaml-libvirt,0.3.3.4) dnl Check for basic C environment. AC_PROG_CC @@ -54,6 +54,11 @@ dnl Check for optional libvirt functions added since 0.2.1. dnl See: http://libvirt.org/hvsupport.html AC_CHECK_FUNCS([virConnectGetHostname virConnectGetURI virDomainBlockStats virDomainGetSchedulerParameters virDomainGetSchedulerType virDomainInterfaceStats virDomainMigrate virDomainSetSchedulerParameters virNodeGetFreeMemory virNodeGetCellsFreeMemory]) +dnl We also use +AC_CHECK_HEADER([libvirt/virterror.h], + [], + AC_MSG_ERROR([You must install libvirt development package])) + dnl Check for optional ncurses. AC_CHECK_LIB(ncurses,initscr) diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml index 586aa7b..69e1c0d 100644 --- a/libvirt/libvirt.ml +++ b/libvirt/libvirt.ml @@ -260,6 +260,8 @@ struct | VIR_WAR_NO_NETWORK | VIR_ERR_NO_DOMAIN | VIR_ERR_NO_NETWORK + | VIR_ERR_INVALID_MAC + | VIR_ERR_UNKNOWN of int let string_of_code = function | VIR_ERR_OK -> "VIR_ERR_OK" @@ -306,16 +308,8 @@ struct | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK" | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN" | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK" - - type level = - | VIR_ERR_NONE - | VIR_ERR_WARNING - | VIR_ERR_ERROR - - let string_of_level = function - | VIR_ERR_NONE -> "VIR_ERR_NONE" - | VIR_ERR_WARNING -> "VIR_ERR_WARNING" - | VIR_ERR_ERROR -> "VIR_ERR_ERROR" + | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC" + | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i type domain = | VIR_FROM_NONE @@ -333,6 +327,9 @@ struct | VIR_FROM_TEST | VIR_FROM_REMOTE | VIR_FROM_OPENVZ + | VIR_FROM_XENXM + | VIR_FROM_STATS_LINUX + | VIR_FROM_UNKNOWN of int let string_of_domain = function | VIR_FROM_NONE -> "VIR_FROM_NONE" @@ -350,6 +347,21 @@ struct | VIR_FROM_TEST -> "VIR_FROM_TEST" | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE" | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ" + | VIR_FROM_XENXM -> "VIR_FROM_XENXM" + | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX" + | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i + + type level = + | VIR_ERR_NONE + | VIR_ERR_WARNING + | VIR_ERR_ERROR + | VIR_ERR_UNKNOWN_LEVEL of int + + let string_of_level = function + | VIR_ERR_NONE -> "VIR_ERR_NONE" + | VIR_ERR_WARNING -> "VIR_ERR_WARNING" + | VIR_ERR_ERROR -> "VIR_ERR_ERROR" + | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i type t = { code : code; diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli index 1d9da1e..aa4b9f4 100644 --- a/libvirt/libvirt.mli +++ b/libvirt/libvirt.mli @@ -463,18 +463,13 @@ sig | VIR_WAR_NO_NETWORK | VIR_ERR_NO_DOMAIN | VIR_ERR_NO_NETWORK + | VIR_ERR_INVALID_MAC + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c:MAX_VIR_* *) + | VIR_ERR_UNKNOWN of int (** See [] for meaning of these codes. *) val string_of_code : code -> string - type level = - | VIR_ERR_NONE - | VIR_ERR_WARNING - | VIR_ERR_ERROR - (** No error, a warning or an error. *) - - val string_of_level : level -> string - type domain = | VIR_FROM_NONE | VIR_FROM_XEN @@ -491,10 +486,24 @@ sig | VIR_FROM_TEST | VIR_FROM_REMOTE | VIR_FROM_OPENVZ + | VIR_FROM_XENXM + | VIR_FROM_STATS_LINUX + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c: MAX_VIR_* *) + | VIR_FROM_UNKNOWN of int (** Subsystem / driver which produced the error. *) val string_of_domain : domain -> string + type level = + | VIR_ERR_NONE + | VIR_ERR_WARNING + | VIR_ERR_ERROR + (* ^^ NB: If you add a variant you MUST edit libvirt_c.c: MAX_VIR_* *) + | VIR_ERR_UNKNOWN_LEVEL of int + (** No error, a warning or an error. *) + + val string_of_level : level -> string + type t = { code : code; (** Error code. *) domain : domain; (** Origin of the error. *) diff --git a/libvirt/libvirt_c.c b/libvirt/libvirt_c.c index 9e2182b..a2bb1ad 100644 --- a/libvirt/libvirt_c.c +++ b/libvirt/libvirt_c.c @@ -1795,6 +1795,72 @@ _raise_virterror (virConnectPtr conn, const char *fn) CAMLreturn (Val_unit); } +/* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums + * into values (longs because they are variants in OCaml). + * + * The enum values are part of the libvirt ABI so they cannot change, + * which means that we can convert these numbers directly into + * OCaml variants (which use the same ordering) very fast. + * + * The tricky part here is when we are linked to a newer version of + * libvirt than the one we were compiled against. If the newer libvirt + * generates an error code which we don't know about then we need + * to convert it into VIR_*_UNKNOWN (code). + */ + +#define MAX_VIR_CODE 44 /* VIR_ERR_INVALID_MAC */ +#define MAX_VIR_DOMAIN 16 /* VIR_FROM_STATS_LINUX */ +#define MAX_VIR_LEVEL VIR_ERR_ERROR + +static inline value +Val_err_number (virErrorNumber code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_CODE) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +static inline value +Val_err_domain (virErrorDomain code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_DOMAIN) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_FROM_UNKNOWN (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +static inline value +Val_err_level (virErrorLevel code) +{ + CAMLparam0 (); + CAMLlocal1 (rv); + + if (0 <= code && code <= MAX_VIR_LEVEL) + rv = Val_int (code); + else { + rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN_LEVEL (code) */ + Store_field (rv, 0, Val_int (code)); + } + + CAMLreturn (rv); +} + +/* Convert a virterror to a value. */ static value Val_virterror (virErrorPtr err) { @@ -1802,11 +1868,11 @@ Val_virterror (virErrorPtr err) CAMLlocal3 (rv, connv, optv); rv = caml_alloc (12, 0); - Store_field (rv, 0, Val_int (err->code)); - Store_field (rv, 1, Val_int (err->domain)); + Store_field (rv, 0, Val_err_number (err->code)); + Store_field (rv, 1, Val_err_domain (err->domain)); Store_field (rv, 2, Val_opt (err->message, (Val_ptr_t) caml_copy_string)); - Store_field (rv, 3, Val_int (err->level)); + Store_field (rv, 3, Val_err_level (err->level)); /* conn, dom and net fields, all optional */ if (err->conn) { -- 1.8.3.1