* libvirt/libvirt.mli, libvirt/libvirt.ml: New error numbers
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 20 Nov 2007 13:11:29 +0000 (13:11 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 20 Nov 2007 13:11:29 +0000 (13:11 +0000)
  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 <libvirt/virterror.h> exists.
* configure.ac: Version 0.3.3.4.

ChangeLog
configure.ac
libvirt/libvirt.ml
libvirt/libvirt.mli
libvirt/libvirt_c.c

index b63912b..b3247ca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-11-20  Richard Jones  <rjones@redhat.com>
+
+       * 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 <libvirt/virterror.h> 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  <rjones@redhat.com>
+
+       * virt-top/virt-top.pod: Example connection URIs in virt-top manpage
+         (bug 390691).
+
 2007-11-14  Richard Jones  <rjones@redhat.com>
 
        * libvirt/libvirt.mli: Added filename = string type to clarify
index 635b49a..c238643 100644 (file)
@@ -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 <libvirt/virterror.h>
+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)
 
index 586aa7b..69e1c0d 100644 (file)
@@ -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;
index 1d9da1e..aa4b9f4 100644 (file)
@@ -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 [<libvirt/virterror.h>] 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. *)
index 9e2182b..a2bb1ad 100644 (file)
@@ -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) {