~alpine/aports

[alpine-aports] [PATCH] testing/ocaml-libvirt: new aport

Fernando Casas Schössow <casasfernando@outlook.com>
Details
Message ID
<VI1PR0602MB324529713FAD74CCDAE96D48A46F0@VI1PR0602MB3245.eurprd06.prod.outlook.com>
Sender timestamp
1549495981
DKIM signature
missing
Download raw message
Patch: +2943 -0
http://libvirt.org/ocaml/
OCaml binding for libvirt
---
 ...Add-a-binding-for-virDomainCreateXML.patch |  213 ++
 ...Remove-unused-not_supported-function.patch |   57 +
 ...to-stderr-and-use-thread-local-virEr.patch | 1864 +++++++++++++++++
 ...-int64_t-instead-of-OCaml-defined-an.patch |   35 +
 .../ocaml-libvirt/0001-Use-g-warn-error.patch |   78 +
 ...r-checking-return-from-virInitialize.patch |   32 +
 .../0002-Update-dependencies.patch            |   44 +
 ...r-virConnectGetAllDomainStats-RHBZ-1.patch |  393 ++++
 ...ore-stats-in-the-get_all_domain_stat.patch |   42 +
 ...f-virConnectGetAllDomainStats-to-ret.patch |  127 ++
 testing/ocaml-libvirt/APKBUILD                |   58 +
 11 files changed, 2943 insertions(+)
 create mode 100644 testing/ocaml-libvirt/0001-Add-a-binding-for-virDomainCreateXML.patch
 create mode 100644 testing/ocaml-libvirt/0001-Remove-unused-not_supported-function.patch
 create mode 100644 testing/ocaml-libvirt/0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch
 create mode 100644 testing/ocaml-libvirt/0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch
 create mode 100644 testing/ocaml-libvirt/0001-Use-g-warn-error.patch
 create mode 100644 testing/ocaml-libvirt/0002-Don-t-bother-checking-return-from-virInitialize.patch
 create mode 100644 testing/ocaml-libvirt/0002-Update-dependencies.patch
 create mode 100644 testing/ocaml-libvirt/0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch
 create mode 100644 testing/ocaml-libvirt/0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch
 create mode 100644 testing/ocaml-libvirt/0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch
 create mode 100644 testing/ocaml-libvirt/APKBUILD

diff --git a/testing/ocaml-libvirt/0001-Add-a-binding-for-virDomainCreateXML.patch b/testing/ocaml-libvirt/0001-Add-a-binding-for-virDomainCreateXML.patch
new file mode 100644
index 0000000000..a25507b4f0
--- /dev/null
+++ b/testing/ocaml-libvirt/0001-Add-a-binding-for-virDomainCreateXML.patch
@@ -0,0 +1,213 @@
From 7483c7454538584a3dbe4582096f058e6e877df6 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 6 Mar 2015 15:35:46 +0000
Subject: [PATCH] Add a binding for virDomainCreateXML.

This is more modern than the ancient virDomainCreateLinux API,
and crucially allows you to pass flags such as AUTODESTROY.
---
 configure.ac         |  2 +-
 libvirt/generator.pl | 23 +++++++++++++++++++++--
 libvirt/libvirt.ml   | 19 ++++++++++++++++++-
 libvirt/libvirt.mli  | 13 +++++++++++--
 libvirt/libvirt_c.c  | 25 ++++++++++++++++++++++++-
 5 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index b7544b4..a719fb3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 # ocaml-libvirt
-# Copyright (C) 2007-2008 Red Hat Inc., Richard W.M. Jones
+# Copyright (C) 2007-2015 Red Hat Inc., Richard W.M. Jones
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
diff --git a/libvirt/generator.pl b/libvirt/generator.pl
index 8229ad1..421592b 100755
--- a/libvirt/generator.pl
+++ b/libvirt/generator.pl
@@ -1,7 +1,7 @@
 #!/usr/bin/perl -w
 #
 # OCaml bindings for libvirt.
-# (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
+# (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
 # http://libvirt.org/
 #
 # This library is free software; you can redistribute it and/or
@@ -63,6 +63,7 @@ my @functions = (
       sig => "conn, int : unit" },
 
     { name => "virDomainCreateLinux", sig => "conn, string, 0U : dom" },
+    { name => "virDomainCreateXML", sig => "conn, string, unsigned : dom" },
     { name => "virDomainFree", sig => "dom : free" },
     { name => "virDomainDestroy", sig => "dom : free" },
     { name => "virDomainLookupByName", sig => "conn, string : dom" },
@@ -198,7 +199,7 @@ print F <<'END';
  */
 
 /* OCaml bindings for libvirt.
- * (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
+ * (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
  * http://libvirt.org/
  *
  * This library is free software; you can redistribute it and/or
@@ -310,6 +311,8 @@ sub gen_arg_names
 	( "$1v", "strv" )
     } elsif ($sig =~ /^(\w+), string, 0U? : (\w+)$/) {
 	( "$1v", "strv" )
+    } elsif ($sig =~ /^(\w+), string, unsigned : (\w+)$/) {
+	( "$1v", "strv", "uv" )
     } elsif ($sig =~ /^(\w+), u?int : (\w+)$/) {
 	( "$1v", "iv" )
     } elsif ($sig =~ /^(\w+), uuid : (\w+)$/) {
@@ -632,6 +635,22 @@ sub gen_c_code
 
   CAMLreturn (rv);
 "
+    } elsif ($sig =~ /^(\w+), string, unsigned : (\w+)$/) {
+	my $c_ret_type = short_name_to_c_type ($2);
+	"\
+  CAMLlocal1 (rv);
+  " . gen_unpack_args ($1) . "
+  char *str = String_val (strv);
+  unsigned int u = Int_val (uv);
+  $c_ret_type r;
+
+  NONBLOCKING (r = $c_name ($1, str, u));
+  CHECK_ERROR (!r, conn, \"$c_name\");
+
+  " . gen_pack_result ($2) . "
+
+  CAMLreturn (rv);
+"
     } elsif ($sig =~ /^(\w+), (u?)int : unit$/) {
 	my $unsigned = $2 eq "u" ? "unsigned " : "";
 	"\
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
index 9c9368a..1be023d 100644
--- a/libvirt/libvirt.ml
+++ b/libvirt/libvirt.ml
@@ -1,5 +1,5 @@
 (* OCaml bindings for libvirt.
-   (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+   (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
    http://libvirt.org/
 
    This library is free software; you can redistribute it and/or
@@ -337,6 +337,20 @@ struct
     cpu : int;
   }
 
+  type domain_create_flag =
+  | START_PAUSED
+  | START_AUTODESTROY
+  | START_BYPASS_CACHE
+  | START_FORCE_BOOT
+  | START_VALIDATE
+  let rec int_of_domain_create_flags = function
+    | [] -> 0
+    | START_PAUSED :: flags ->       1 lor int_of_domain_create_flags flags
+    | START_AUTODESTROY :: flags ->  2 lor int_of_domain_create_flags flags
+    | START_BYPASS_CACHE :: flags -> 4 lor int_of_domain_create_flags flags
+    | START_FORCE_BOOT :: flags ->   8 lor int_of_domain_create_flags flags
+    | START_VALIDATE :: flags ->    16 lor int_of_domain_create_flags flags
+
   type sched_param = string * sched_param_value
   and sched_param_value =
     | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
@@ -385,6 +399,9 @@ struct
   let max_peek _ = 65536
 
   external create_linux : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_create_linux"
+  external _create_xml : [>`W] Connect.t -> xml -> int -> rw t = "ocaml_libvirt_domain_create_xml"
+  let create_xml conn xml flags =
+    _create_xml conn xml (int_of_domain_create_flags flags)
   external lookup_by_id : 'a Connect.t -> int -> 'a t = "ocaml_libvirt_domain_lookup_by_id"
   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid"
   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid_string"
diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli
index 36cd113..8cfcae2 100644
--- a/libvirt/libvirt.mli
+++ b/libvirt/libvirt.mli
@@ -1,5 +1,5 @@
 (** OCaml bindings for libvirt. *)
-(* (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+(* (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
    http://libvirt.org/
 
    This library is free software; you can redistribute it and/or
@@ -430,6 +430,13 @@ sig
     cpu : int;				(** real CPU number, -1 if offline *)
   }
 
+  type domain_create_flag =
+  | START_PAUSED                        (** Launch guest in paused state *)
+  | START_AUTODESTROY                   (** Automatically kill guest on close *)
+  | START_BYPASS_CACHE                  (** Avoid filesystem cache pollution *)
+  | START_FORCE_BOOT                    (** Discard any managed save *)
+  | START_VALIDATE                      (** Validate XML against schema *)
+
   type sched_param = string * sched_param_value
   and sched_param_value =
     | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
@@ -478,8 +485,10 @@ sig
 
   val create_linux : [>`W] Connect.t -> xml -> rw t
     (** Create a new guest domain (not necessarily a Linux one)
-	from the given XML.
+	from the given XML.  Use {!create_xml} instead.
     *)
+  val create_xml : [>`W] Connect.t -> xml -> domain_create_flag list -> rw t
+    (** Create a new guest domain from the given XML. *)
   val lookup_by_id : 'a Connect.t -> int -> 'a t
     (** Lookup a domain by ID. *)
   val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
diff --git a/libvirt/libvirt_c.c b/libvirt/libvirt_c.c
index 71e6f61..6e56682 100644
--- a/libvirt/libvirt_c.c
+++ b/libvirt/libvirt_c.c
@@ -6,7 +6,7 @@
  */
 
 /* OCaml bindings for libvirt.
- * (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
+ * (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
  * http://libvirt.org/
  *
  * This library is free software; you can redistribute it and/or
@@ -525,6 +525,29 @@ ocaml_libvirt_domain_create_linux (value connv, value strv)
   CAMLreturn (rv);
 }
 
+/* Automatically generated binding for virDomainCreateXML.
+ * In generator.pl this function has signature "conn, string, unsigned : dom".
+ */
+
+CAMLprim value
+ocaml_libvirt_domain_create_xml (value connv, value strv, value uv)
+{
+  CAMLparam3 (connv, strv, uv);
+
+  CAMLlocal1 (rv);
+  virConnectPtr conn = Connect_val (connv);
+  char *str = String_val (strv);
+  unsigned int u = Int_val (uv);
+  virDomainPtr r;
+
+  NONBLOCKING (r = virDomainCreateXML (conn, str, u));
+  CHECK_ERROR (!r, conn, "virDomainCreateXML");
+
+  rv = Val_domain (r, connv);
+
+  CAMLreturn (rv);
+}
+
 /* Automatically generated binding for virDomainFree.
  * In generator.pl this function has signature "dom : free".
  */
-- 
2.3.1

diff --git a/testing/ocaml-libvirt/0001-Remove-unused-not_supported-function.patch b/testing/ocaml-libvirt/0001-Remove-unused-not_supported-function.patch
new file mode 100644
index 0000000000..851385cba3
--- /dev/null
+++ b/testing/ocaml-libvirt/0001-Remove-unused-not_supported-function.patch
@@ -0,0 +1,57 @@
From 8853f5a49587f00a7d2a5c8c7e52480a16bbdb02 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 5 Feb 2016 16:28:34 +0000
Subject: [PATCH] Remove unused 'not_supported' function.

Found by compiling under GCC 6.  The warning was:

In file included from libvirt_c.c:2058:0:
libvirt_c_epilogue.c:89:1: error: 'not_supported' defined but not used [-Werror=unused-function]
 not_supported (const char *fn)
 ^~~~~~~~~~~~~
---
 libvirt/libvirt_c_epilogue.c | 15 ---------------
 libvirt/libvirt_c_prologue.c |  1 -
 2 files changed, 16 deletions(-)

diff --git a/libvirt/libvirt_c_epilogue.c b/libvirt/libvirt_c_epilogue.c
index 4972e50..fa592c9 100644
--- a/libvirt/libvirt_c_epilogue.c
+++ b/libvirt/libvirt_c_epilogue.c
@@ -84,21 +84,6 @@ _raise_virterror (const char *fn)
   (void) caml__frame;
 }
 
-/* Raise an error if a function is not supported. */
-static void
-not_supported (const char *fn)
-{
-  CAMLparam0 ();
-  CAMLlocal1 (fnv);
-
-  fnv = caml_copy_string (fn);
-  caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
-
-  /*NOTREACHED*/
-  /* Suppresses a compiler warning. */
-  (void) caml__frame;
-}
-
 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
  * into values (longs because they are variants in OCaml).
  *
diff --git a/libvirt/libvirt_c_prologue.c b/libvirt/libvirt_c_prologue.c
index bf972e9..710c0d6 100644
--- a/libvirt/libvirt_c_prologue.c
+++ b/libvirt/libvirt_c_prologue.c
@@ -25,7 +25,6 @@ typedef value (*Val_ptr_t) (void *);
 static value Val_opt (void *ptr, Val_ptr_t Val_ptr);
 /*static value option_default (value option, value deflt);*/
 static void _raise_virterror (const char *fn) Noreturn;
-static void not_supported (const char *fn) Noreturn;
 static value Val_virterror (virErrorPtr err);
 
 /* Use this around synchronous libvirt API calls to release the OCaml
-- 
2.5.0

diff --git a/testing/ocaml-libvirt/0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch b/testing/ocaml-libvirt/0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch
new file mode 100644
index 0000000000..f3655349e8
--- /dev/null
+++ b/testing/ocaml-libvirt/0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch
@@ -0,0 +1,1864 @@
From 68fae1ec3de46fd9eec88fb7c1894ea7ed85ccc9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 17 Mar 2015 12:51:50 +0000
Subject: [PATCH 1/2] Suppress errors to stderr and use thread-local
 virErrorPtr

This allows us to capture errors that happen during virConnectOpen,
without spewing error messages on stderr.

The patch is rather large, only because we don't need to pass the
virConnectPtr argument to CHECK_ERROR/_raise_virterror any longer.
---
 libvirt/generator.pl         |  66 ++++++------
 libvirt/libvirt_c.c          | 241 +++++++++++++++++--------------------------
 libvirt/libvirt_c_epilogue.c |   4 +-
 libvirt/libvirt_c_oneoffs.c  |  94 +++++++----------
 libvirt/libvirt_c_prologue.c |   6 +-
 5 files changed, 169 insertions(+), 242 deletions(-)

diff --git a/libvirt/generator.pl b/libvirt/generator.pl
index 421592b..34801ba 100755
--- a/libvirt/generator.pl
+++ b/libvirt/generator.pl
@@ -343,17 +343,13 @@ sub gen_unpack_args
     if ($_ eq "conn") {
 	"virConnectPtr conn = Connect_val (connv);"
     } elsif ($_ eq "dom") {
-	"virDomainPtr dom = Domain_val (domv);\n".
-	"  virConnectPtr conn = Connect_domv (domv);"
+	"virDomainPtr dom = Domain_val (domv);"
     } elsif ($_ eq "net") {
-	"virNetworkPtr net = Network_val (netv);\n".
-	"  virConnectPtr conn = Connect_netv (netv);"
+	"virNetworkPtr net = Network_val (netv);"
     } elsif ($_ eq "pool") {
-	"virStoragePoolPtr pool = Pool_val (poolv);\n".
-	"  virConnectPtr conn = Connect_polv (poolv);"
+	"virStoragePoolPtr pool = Pool_val (poolv);"
     } elsif ($_ eq "vol") {
-	"virStorageVolPtr vol = Volume_val (volv);\n".
-	"  virConnectPtr conn = Connect_volv (volv);"
+	"virStorageVolPtr vol = Volume_val (volv);"
     } else {
 	die "unknown short name $_"
     }
@@ -402,7 +398,7 @@ sub gen_c_code
   char *r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   rv = caml_copy_string (r);
   free (r);
@@ -415,7 +411,7 @@ sub gen_c_code
   const char *r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -426,7 +422,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_int (r));
 "
@@ -438,7 +434,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, uuid));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   /* UUIDs are byte arrays with a fixed length. */
   rv = caml_alloc_string (VIR_UUID_BUFLEN);
@@ -453,7 +449,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, uuid));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   rv = caml_copy_string (uuid);
   CAMLreturn (rv);
@@ -464,7 +460,7 @@ sub gen_c_code
   int r, b;
 
   NONBLOCKING (r = $c_name ($1, &b));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (b ? Val_true : Val_false);
 "
@@ -476,7 +472,7 @@ sub gen_c_code
   b = bv == Val_true ? 1 : 0;
 
   NONBLOCKING (r = $c_name ($1, b));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -498,7 +494,7 @@ sub gen_c_code
   }
 
   NONBLOCKING (r = $c_name (conn, ids, i));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i)
@@ -525,7 +521,7 @@ sub gen_c_code
   }
 
   NONBLOCKING (r = $c_name ($1, names, i));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -543,7 +539,7 @@ sub gen_c_code
   char *r;
 
   NONBLOCKING (r = $c_name ($1, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   rv = caml_copy_string (r);
   free (r);
@@ -555,7 +551,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, 0));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -565,7 +561,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -575,7 +571,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   /* So that we don't double-free in the finalizer: */
   " . gen_free_arg ($1) . "
@@ -589,7 +585,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, str));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -601,7 +597,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, str, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -614,7 +610,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, str));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -629,7 +625,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, str, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -645,7 +641,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, str, u));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -659,7 +655,7 @@ sub gen_c_code
   int r;
 
   NONBLOCKING (r = $c_name ($1, i));
-  CHECK_ERROR (r == -1, conn, \"$c_name\");
+  CHECK_ERROR (r == -1, \"$c_name\");
 
   CAMLreturn (Val_unit);
 "
@@ -673,7 +669,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, i));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($3) . "
 
@@ -688,7 +684,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, uuid));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -702,7 +698,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -716,7 +712,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   " . gen_pack_result ($2) . "
 
@@ -731,7 +727,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, str));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   connv = Field ($3v, 1);
   " . gen_pack_result ($2) . "
@@ -747,7 +743,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, str, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   connv = Field ($3v, 1);
   " . gen_pack_result ($2) . "
@@ -762,7 +758,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1, 0));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   connv = Field ($3v, 1);
   " . gen_pack_result ($2) . "
@@ -777,7 +773,7 @@ sub gen_c_code
   $c_ret_type r;
 
   NONBLOCKING (r = $c_name ($1));
-  CHECK_ERROR (!r, conn, \"$c_name\");
+  CHECK_ERROR (!r, \"$c_name\");
 
   connv = Field ($3v, 1);
   " . gen_pack_result ($2) . "
diff --git a/libvirt/libvirt_c.c b/libvirt/libvirt_c.c
index 6e56682..8d51944 100644
--- a/libvirt/libvirt_c.c
+++ b/libvirt/libvirt_c.c
@@ -61,7 +61,7 @@ ocaml_libvirt_connect_close (value connv)
   int r;
 
   NONBLOCKING (r = virConnectClose (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectClose");
+  CHECK_ERROR (r == -1, "virConnectClose");
 
   /* So that we don't double-free in the finalizer: */
   Connect_val (connv) = NULL;
@@ -83,7 +83,7 @@ ocaml_libvirt_connect_get_hostname (value connv)
   char *r;
 
   NONBLOCKING (r = virConnectGetHostname (conn));
-  CHECK_ERROR (!r, conn, "virConnectGetHostname");
+  CHECK_ERROR (!r, "virConnectGetHostname");
 
   rv = caml_copy_string (r);
   free (r);
@@ -104,7 +104,7 @@ ocaml_libvirt_connect_get_uri (value connv)
   char *r;
 
   NONBLOCKING (r = virConnectGetURI (conn));
-  CHECK_ERROR (!r, conn, "virConnectGetURI");
+  CHECK_ERROR (!r, "virConnectGetURI");
 
   rv = caml_copy_string (r);
   free (r);
@@ -125,7 +125,7 @@ ocaml_libvirt_connect_get_type (value connv)
   const char *r;
 
   NONBLOCKING (r = virConnectGetType (conn));
-  CHECK_ERROR (!r, conn, "virConnectGetType");
+  CHECK_ERROR (!r, "virConnectGetType");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -144,7 +144,7 @@ ocaml_libvirt_connect_num_of_domains (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfDomains (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfDomains");
+  CHECK_ERROR (r == -1, "virConnectNumOfDomains");
 
   CAMLreturn (Val_int (r));
 }
@@ -174,7 +174,7 @@ ocaml_libvirt_connect_list_domains (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListDomains (conn, ids, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListDomains");
+  CHECK_ERROR (r == -1, "virConnectListDomains");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i)
@@ -196,7 +196,7 @@ ocaml_libvirt_connect_num_of_defined_domains (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfDefinedDomains (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfDefinedDomains");
+  CHECK_ERROR (r == -1, "virConnectNumOfDefinedDomains");
 
   CAMLreturn (Val_int (r));
 }
@@ -227,7 +227,7 @@ ocaml_libvirt_connect_list_defined_domains (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListDefinedDomains (conn, names, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListDefinedDomains");
+  CHECK_ERROR (r == -1, "virConnectListDefinedDomains");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -252,7 +252,7 @@ ocaml_libvirt_connect_num_of_networks (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfNetworks (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfNetworks");
+  CHECK_ERROR (r == -1, "virConnectNumOfNetworks");
 
   CAMLreturn (Val_int (r));
 }
@@ -283,7 +283,7 @@ ocaml_libvirt_connect_list_networks (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListNetworks (conn, names, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListNetworks");
+  CHECK_ERROR (r == -1, "virConnectListNetworks");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -308,7 +308,7 @@ ocaml_libvirt_connect_num_of_defined_networks (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfDefinedNetworks (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfDefinedNetworks");
+  CHECK_ERROR (r == -1, "virConnectNumOfDefinedNetworks");
 
   CAMLreturn (Val_int (r));
 }
@@ -339,7 +339,7 @@ ocaml_libvirt_connect_list_defined_networks (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListDefinedNetworks (conn, names, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListDefinedNetworks");
+  CHECK_ERROR (r == -1, "virConnectListDefinedNetworks");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -364,7 +364,7 @@ ocaml_libvirt_connect_num_of_storage_pools (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfStoragePools (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfStoragePools");
+  CHECK_ERROR (r == -1, "virConnectNumOfStoragePools");
 
   CAMLreturn (Val_int (r));
 }
@@ -395,7 +395,7 @@ ocaml_libvirt_connect_list_storage_pools (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListStoragePools (conn, names, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListStoragePools");
+  CHECK_ERROR (r == -1, "virConnectListStoragePools");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -420,7 +420,7 @@ ocaml_libvirt_connect_num_of_defined_storage_pools (value connv)
   int r;
 
   NONBLOCKING (r = virConnectNumOfDefinedStoragePools (conn));
-  CHECK_ERROR (r == -1, conn, "virConnectNumOfDefinedStoragePools");
+  CHECK_ERROR (r == -1, "virConnectNumOfDefinedStoragePools");
 
   CAMLreturn (Val_int (r));
 }
@@ -451,7 +451,7 @@ ocaml_libvirt_connect_list_defined_storage_pools (value connv, value iv)
   }
 
   NONBLOCKING (r = virConnectListDefinedStoragePools (conn, names, i));
-  CHECK_ERROR (r == -1, conn, "virConnectListDefinedStoragePools");
+  CHECK_ERROR (r == -1, "virConnectListDefinedStoragePools");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -477,7 +477,7 @@ ocaml_libvirt_connect_get_capabilities (value connv)
   char *r;
 
   NONBLOCKING (r = virConnectGetCapabilities (conn));
-  CHECK_ERROR (!r, conn, "virConnectGetCapabilities");
+  CHECK_ERROR (!r, "virConnectGetCapabilities");
 
   rv = caml_copy_string (r);
   free (r);
@@ -498,7 +498,7 @@ ocaml_libvirt_connect_domain_event_deregister_any (value connv, value iv)
   int r;
 
   NONBLOCKING (r = virConnectDomainEventDeregisterAny (conn, i));
-  CHECK_ERROR (r == -1, conn, "virConnectDomainEventDeregisterAny");
+  CHECK_ERROR (r == -1, "virConnectDomainEventDeregisterAny");
 
   CAMLreturn (Val_unit);
 }
@@ -518,7 +518,7 @@ ocaml_libvirt_domain_create_linux (value connv, value strv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainCreateLinux (conn, str, 0));
-  CHECK_ERROR (!r, conn, "virDomainCreateLinux");
+  CHECK_ERROR (!r, "virDomainCreateLinux");
 
   rv = Val_domain (r, connv);
 
@@ -541,7 +541,7 @@ ocaml_libvirt_domain_create_xml (value connv, value strv, value uv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainCreateXML (conn, str, u));
-  CHECK_ERROR (!r, conn, "virDomainCreateXML");
+  CHECK_ERROR (!r, "virDomainCreateXML");
 
   rv = Val_domain (r, connv);
 
@@ -558,11 +558,10 @@ ocaml_libvirt_domain_free (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainFree (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainFree");
+  CHECK_ERROR (r == -1, "virDomainFree");
 
   /* So that we don't double-free in the finalizer: */
   Domain_val (domv) = NULL;
@@ -580,11 +579,10 @@ ocaml_libvirt_domain_destroy (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainDestroy (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainDestroy");
+  CHECK_ERROR (r == -1, "virDomainDestroy");
 
   /* So that we don't double-free in the finalizer: */
   Domain_val (domv) = NULL;
@@ -607,7 +605,7 @@ ocaml_libvirt_domain_lookup_by_name (value connv, value strv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainLookupByName (conn, str));
-  CHECK_ERROR (!r, conn, "virDomainLookupByName");
+  CHECK_ERROR (!r, "virDomainLookupByName");
 
   rv = Val_domain (r, connv);
 
@@ -629,7 +627,7 @@ ocaml_libvirt_domain_lookup_by_id (value connv, value iv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainLookupByID (conn, i));
-  CHECK_ERROR (!r, conn, "virDomainLookupByID");
+  CHECK_ERROR (!r, "virDomainLookupByID");
 
   rv = Val_domain (r, connv);
 
@@ -651,7 +649,7 @@ ocaml_libvirt_domain_lookup_by_uuid (value connv, value uuidv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainLookupByUUID (conn, uuid));
-  CHECK_ERROR (!r, conn, "virDomainLookupByUUID");
+  CHECK_ERROR (!r, "virDomainLookupByUUID");
 
   rv = Val_domain (r, connv);
 
@@ -673,7 +671,7 @@ ocaml_libvirt_domain_lookup_by_uuid_string (value connv, value strv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainLookupByUUIDString (conn, str));
-  CHECK_ERROR (!r, conn, "virDomainLookupByUUIDString");
+  CHECK_ERROR (!r, "virDomainLookupByUUIDString");
 
   rv = Val_domain (r, connv);
 
@@ -691,11 +689,10 @@ ocaml_libvirt_domain_get_name (value domv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   const char *r;
 
   NONBLOCKING (r = virDomainGetName (dom));
-  CHECK_ERROR (!r, conn, "virDomainGetName");
+  CHECK_ERROR (!r, "virDomainGetName");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -712,11 +709,10 @@ ocaml_libvirt_domain_get_os_type (value domv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *r;
 
   NONBLOCKING (r = virDomainGetOSType (dom));
-  CHECK_ERROR (!r, conn, "virDomainGetOSType");
+  CHECK_ERROR (!r, "virDomainGetOSType");
 
   rv = caml_copy_string (r);
   free (r);
@@ -734,11 +730,10 @@ ocaml_libvirt_domain_get_xml_desc (value domv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *r;
 
   NONBLOCKING (r = virDomainGetXMLDesc (dom, 0));
-  CHECK_ERROR (!r, conn, "virDomainGetXMLDesc");
+  CHECK_ERROR (!r, "virDomainGetXMLDesc");
 
   rv = caml_copy_string (r);
   free (r);
@@ -756,12 +751,11 @@ ocaml_libvirt_domain_get_uuid (value domv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   unsigned char uuid[VIR_UUID_BUFLEN];
   int r;
 
   NONBLOCKING (r = virDomainGetUUID (dom, uuid));
-  CHECK_ERROR (r == -1, conn, "virDomainGetUUID");
+  CHECK_ERROR (r == -1, "virDomainGetUUID");
 
   /* UUIDs are byte arrays with a fixed length. */
   rv = caml_alloc_string (VIR_UUID_BUFLEN);
@@ -780,12 +774,11 @@ ocaml_libvirt_domain_get_uuid_string (value domv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char uuid[VIR_UUID_STRING_BUFLEN];
   int r;
 
   NONBLOCKING (r = virDomainGetUUIDString (dom, uuid));
-  CHECK_ERROR (r == -1, conn, "virDomainGetUUIDString");
+  CHECK_ERROR (r == -1, "virDomainGetUUIDString");
 
   rv = caml_copy_string (uuid);
   CAMLreturn (rv);
@@ -801,11 +794,10 @@ ocaml_libvirt_domain_get_max_vcpus (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainGetMaxVcpus (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainGetMaxVcpus");
+  CHECK_ERROR (r == -1, "virDomainGetMaxVcpus");
 
   CAMLreturn (Val_int (r));
 }
@@ -820,12 +812,11 @@ ocaml_libvirt_domain_save (value domv, value strv)
   CAMLparam2 (domv, strv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *str = String_val (strv);
   int r;
 
   NONBLOCKING (r = virDomainSave (dom, str));
-  CHECK_ERROR (r == -1, conn, "virDomainSave");
+  CHECK_ERROR (r == -1, "virDomainSave");
 
   CAMLreturn (Val_unit);
 }
@@ -844,7 +835,7 @@ ocaml_libvirt_domain_restore (value connv, value strv)
   int r;
 
   NONBLOCKING (r = virDomainRestore (conn, str));
-  CHECK_ERROR (r == -1, conn, "virDomainRestore");
+  CHECK_ERROR (r == -1, "virDomainRestore");
 
   CAMLreturn (Val_unit);
 }
@@ -860,12 +851,11 @@ ocaml_libvirt_domain_core_dump (value domv, value strv)
 
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *str = String_val (strv);
   int r;
 
   NONBLOCKING (r = virDomainCoreDump (dom, str, 0));
-  CHECK_ERROR (!r, conn, "virDomainCoreDump");
+  CHECK_ERROR (!r, "virDomainCoreDump");
 
   CAMLreturn (Val_unit);
 }
@@ -880,11 +870,10 @@ ocaml_libvirt_domain_suspend (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainSuspend (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainSuspend");
+  CHECK_ERROR (r == -1, "virDomainSuspend");
 
   CAMLreturn (Val_unit);
 }
@@ -899,11 +888,10 @@ ocaml_libvirt_domain_resume (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainResume (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainResume");
+  CHECK_ERROR (r == -1, "virDomainResume");
 
   CAMLreturn (Val_unit);
 }
@@ -918,11 +906,10 @@ ocaml_libvirt_domain_shutdown (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainShutdown (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainShutdown");
+  CHECK_ERROR (r == -1, "virDomainShutdown");
 
   CAMLreturn (Val_unit);
 }
@@ -937,11 +924,10 @@ ocaml_libvirt_domain_reboot (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainReboot (dom, 0));
-  CHECK_ERROR (r == -1, conn, "virDomainReboot");
+  CHECK_ERROR (r == -1, "virDomainReboot");
 
   CAMLreturn (Val_unit);
 }
@@ -961,7 +947,7 @@ ocaml_libvirt_domain_define_xml (value connv, value strv)
   virDomainPtr r;
 
   NONBLOCKING (r = virDomainDefineXML (conn, str));
-  CHECK_ERROR (!r, conn, "virDomainDefineXML");
+  CHECK_ERROR (!r, "virDomainDefineXML");
 
   rv = Val_domain (r, connv);
 
@@ -978,11 +964,10 @@ ocaml_libvirt_domain_undefine (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainUndefine (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainUndefine");
+  CHECK_ERROR (r == -1, "virDomainUndefine");
 
   CAMLreturn (Val_unit);
 }
@@ -997,11 +982,10 @@ ocaml_libvirt_domain_create (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r;
 
   NONBLOCKING (r = virDomainCreate (dom));
-  CHECK_ERROR (r == -1, conn, "virDomainCreate");
+  CHECK_ERROR (r == -1, "virDomainCreate");
 
   CAMLreturn (Val_unit);
 }
@@ -1016,12 +1000,11 @@ ocaml_libvirt_domain_attach_device (value domv, value strv)
   CAMLparam2 (domv, strv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *str = String_val (strv);
   int r;
 
   NONBLOCKING (r = virDomainAttachDevice (dom, str));
-  CHECK_ERROR (r == -1, conn, "virDomainAttachDevice");
+  CHECK_ERROR (r == -1, "virDomainAttachDevice");
 
   CAMLreturn (Val_unit);
 }
@@ -1036,12 +1019,11 @@ ocaml_libvirt_domain_detach_device (value domv, value strv)
   CAMLparam2 (domv, strv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *str = String_val (strv);
   int r;
 
   NONBLOCKING (r = virDomainDetachDevice (dom, str));
-  CHECK_ERROR (r == -1, conn, "virDomainDetachDevice");
+  CHECK_ERROR (r == -1, "virDomainDetachDevice");
 
   CAMLreturn (Val_unit);
 }
@@ -1056,11 +1038,10 @@ ocaml_libvirt_domain_get_autostart (value domv)
   CAMLparam1 (domv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r, b;
 
   NONBLOCKING (r = virDomainGetAutostart (dom, &b));
-  CHECK_ERROR (r == -1, conn, "virDomainGetAutostart");
+  CHECK_ERROR (r == -1, "virDomainGetAutostart");
 
   CAMLreturn (b ? Val_true : Val_false);
 }
@@ -1075,13 +1056,12 @@ ocaml_libvirt_domain_set_autostart (value domv, value bv)
   CAMLparam2 (domv, bv);
 
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r, b;
 
   b = bv == Val_true ? 1 : 0;
 
   NONBLOCKING (r = virDomainSetAutostart (dom, b));
-  CHECK_ERROR (r == -1, conn, "virDomainSetAutostart");
+  CHECK_ERROR (r == -1, "virDomainSetAutostart");
 
   CAMLreturn (Val_unit);
 }
@@ -1096,11 +1076,10 @@ ocaml_libvirt_network_free (value netv)
   CAMLparam1 (netv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r;
 
   NONBLOCKING (r = virNetworkFree (net));
-  CHECK_ERROR (r == -1, conn, "virNetworkFree");
+  CHECK_ERROR (r == -1, "virNetworkFree");
 
   /* So that we don't double-free in the finalizer: */
   Network_val (netv) = NULL;
@@ -1118,11 +1097,10 @@ ocaml_libvirt_network_destroy (value netv)
   CAMLparam1 (netv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r;
 
   NONBLOCKING (r = virNetworkDestroy (net));
-  CHECK_ERROR (r == -1, conn, "virNetworkDestroy");
+  CHECK_ERROR (r == -1, "virNetworkDestroy");
 
   /* So that we don't double-free in the finalizer: */
   Network_val (netv) = NULL;
@@ -1145,7 +1123,7 @@ ocaml_libvirt_network_lookup_by_name (value connv, value strv)
   virNetworkPtr r;
 
   NONBLOCKING (r = virNetworkLookupByName (conn, str));
-  CHECK_ERROR (!r, conn, "virNetworkLookupByName");
+  CHECK_ERROR (!r, "virNetworkLookupByName");
 
   rv = Val_network (r, connv);
 
@@ -1167,7 +1145,7 @@ ocaml_libvirt_network_lookup_by_uuid (value connv, value uuidv)
   virNetworkPtr r;
 
   NONBLOCKING (r = virNetworkLookupByUUID (conn, uuid));
-  CHECK_ERROR (!r, conn, "virNetworkLookupByUUID");
+  CHECK_ERROR (!r, "virNetworkLookupByUUID");
 
   rv = Val_network (r, connv);
 
@@ -1189,7 +1167,7 @@ ocaml_libvirt_network_lookup_by_uuid_string (value connv, value strv)
   virNetworkPtr r;
 
   NONBLOCKING (r = virNetworkLookupByUUIDString (conn, str));
-  CHECK_ERROR (!r, conn, "virNetworkLookupByUUIDString");
+  CHECK_ERROR (!r, "virNetworkLookupByUUIDString");
 
   rv = Val_network (r, connv);
 
@@ -1207,11 +1185,10 @@ ocaml_libvirt_network_get_name (value netv)
 
   CAMLlocal1 (rv);
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   const char *r;
 
   NONBLOCKING (r = virNetworkGetName (net));
-  CHECK_ERROR (!r, conn, "virNetworkGetName");
+  CHECK_ERROR (!r, "virNetworkGetName");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -1228,11 +1205,10 @@ ocaml_libvirt_network_get_xml_desc (value netv)
 
   CAMLlocal1 (rv);
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   char *r;
 
   NONBLOCKING (r = virNetworkGetXMLDesc (net, 0));
-  CHECK_ERROR (!r, conn, "virNetworkGetXMLDesc");
+  CHECK_ERROR (!r, "virNetworkGetXMLDesc");
 
   rv = caml_copy_string (r);
   free (r);
@@ -1250,11 +1226,10 @@ ocaml_libvirt_network_get_bridge_name (value netv)
 
   CAMLlocal1 (rv);
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   char *r;
 
   NONBLOCKING (r = virNetworkGetBridgeName (net));
-  CHECK_ERROR (!r, conn, "virNetworkGetBridgeName");
+  CHECK_ERROR (!r, "virNetworkGetBridgeName");
 
   rv = caml_copy_string (r);
   free (r);
@@ -1272,12 +1247,11 @@ ocaml_libvirt_network_get_uuid (value netv)
 
   CAMLlocal1 (rv);
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   unsigned char uuid[VIR_UUID_BUFLEN];
   int r;
 
   NONBLOCKING (r = virNetworkGetUUID (net, uuid));
-  CHECK_ERROR (r == -1, conn, "virNetworkGetUUID");
+  CHECK_ERROR (r == -1, "virNetworkGetUUID");
 
   /* UUIDs are byte arrays with a fixed length. */
   rv = caml_alloc_string (VIR_UUID_BUFLEN);
@@ -1296,12 +1270,11 @@ ocaml_libvirt_network_get_uuid_string (value netv)
 
   CAMLlocal1 (rv);
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   char uuid[VIR_UUID_STRING_BUFLEN];
   int r;
 
   NONBLOCKING (r = virNetworkGetUUIDString (net, uuid));
-  CHECK_ERROR (r == -1, conn, "virNetworkGetUUIDString");
+  CHECK_ERROR (r == -1, "virNetworkGetUUIDString");
 
   rv = caml_copy_string (uuid);
   CAMLreturn (rv);
@@ -1317,11 +1290,10 @@ ocaml_libvirt_network_undefine (value netv)
   CAMLparam1 (netv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r;
 
   NONBLOCKING (r = virNetworkUndefine (net));
-  CHECK_ERROR (r == -1, conn, "virNetworkUndefine");
+  CHECK_ERROR (r == -1, "virNetworkUndefine");
 
   CAMLreturn (Val_unit);
 }
@@ -1341,7 +1313,7 @@ ocaml_libvirt_network_create_xml (value connv, value strv)
   virNetworkPtr r;
 
   NONBLOCKING (r = virNetworkCreateXML (conn, str));
-  CHECK_ERROR (!r, conn, "virNetworkCreateXML");
+  CHECK_ERROR (!r, "virNetworkCreateXML");
 
   rv = Val_network (r, connv);
 
@@ -1363,7 +1335,7 @@ ocaml_libvirt_network_define_xml (value connv, value strv)
   virNetworkPtr r;
 
   NONBLOCKING (r = virNetworkDefineXML (conn, str));
-  CHECK_ERROR (!r, conn, "virNetworkDefineXML");
+  CHECK_ERROR (!r, "virNetworkDefineXML");
 
   rv = Val_network (r, connv);
 
@@ -1380,11 +1352,10 @@ ocaml_libvirt_network_create (value netv)
   CAMLparam1 (netv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r;
 
   NONBLOCKING (r = virNetworkCreate (net));
-  CHECK_ERROR (r == -1, conn, "virNetworkCreate");
+  CHECK_ERROR (r == -1, "virNetworkCreate");
 
   CAMLreturn (Val_unit);
 }
@@ -1399,11 +1370,10 @@ ocaml_libvirt_network_get_autostart (value netv)
   CAMLparam1 (netv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r, b;
 
   NONBLOCKING (r = virNetworkGetAutostart (net, &b));
-  CHECK_ERROR (r == -1, conn, "virNetworkGetAutostart");
+  CHECK_ERROR (r == -1, "virNetworkGetAutostart");
 
   CAMLreturn (b ? Val_true : Val_false);
 }
@@ -1418,13 +1388,12 @@ ocaml_libvirt_network_set_autostart (value netv, value bv)
   CAMLparam2 (netv, bv);
 
   virNetworkPtr net = Network_val (netv);
-  virConnectPtr conn = Connect_netv (netv);
   int r, b;
 
   b = bv == Val_true ? 1 : 0;
 
   NONBLOCKING (r = virNetworkSetAutostart (net, b));
-  CHECK_ERROR (r == -1, conn, "virNetworkSetAutostart");
+  CHECK_ERROR (r == -1, "virNetworkSetAutostart");
 
   CAMLreturn (Val_unit);
 }
@@ -1439,11 +1408,10 @@ ocaml_libvirt_storage_pool_free (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolFree (pool));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolFree");
+  CHECK_ERROR (r == -1, "virStoragePoolFree");
 
   /* So that we don't double-free in the finalizer: */
   Pool_val (poolv) = NULL;
@@ -1461,11 +1429,10 @@ ocaml_libvirt_storage_pool_destroy (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolDestroy (pool));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolDestroy");
+  CHECK_ERROR (r == -1, "virStoragePoolDestroy");
 
   /* So that we don't double-free in the finalizer: */
   Pool_val (poolv) = NULL;
@@ -1488,7 +1455,7 @@ ocaml_libvirt_storage_pool_lookup_by_name (value connv, value strv)
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolLookupByName (conn, str));
-  CHECK_ERROR (!r, conn, "virStoragePoolLookupByName");
+  CHECK_ERROR (!r, "virStoragePoolLookupByName");
 
   rv = Val_pool (r, connv);
 
@@ -1510,7 +1477,7 @@ ocaml_libvirt_storage_pool_lookup_by_uuid (value connv, value uuidv)
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolLookupByUUID (conn, uuid));
-  CHECK_ERROR (!r, conn, "virStoragePoolLookupByUUID");
+  CHECK_ERROR (!r, "virStoragePoolLookupByUUID");
 
   rv = Val_pool (r, connv);
 
@@ -1532,7 +1499,7 @@ ocaml_libvirt_storage_pool_lookup_by_uuid_string (value connv, value strv)
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolLookupByUUIDString (conn, str));
-  CHECK_ERROR (!r, conn, "virStoragePoolLookupByUUIDString");
+  CHECK_ERROR (!r, "virStoragePoolLookupByUUIDString");
 
   rv = Val_pool (r, connv);
 
@@ -1550,11 +1517,10 @@ ocaml_libvirt_storage_pool_get_name (value poolv)
 
   CAMLlocal1 (rv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   const char *r;
 
   NONBLOCKING (r = virStoragePoolGetName (pool));
-  CHECK_ERROR (!r, conn, "virStoragePoolGetName");
+  CHECK_ERROR (!r, "virStoragePoolGetName");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -1571,11 +1537,10 @@ ocaml_libvirt_storage_pool_get_xml_desc (value poolv)
 
   CAMLlocal1 (rv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   char *r;
 
   NONBLOCKING (r = virStoragePoolGetXMLDesc (pool, 0));
-  CHECK_ERROR (!r, conn, "virStoragePoolGetXMLDesc");
+  CHECK_ERROR (!r, "virStoragePoolGetXMLDesc");
 
   rv = caml_copy_string (r);
   free (r);
@@ -1593,12 +1558,11 @@ ocaml_libvirt_storage_pool_get_uuid (value poolv)
 
   CAMLlocal1 (rv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   unsigned char uuid[VIR_UUID_BUFLEN];
   int r;
 
   NONBLOCKING (r = virStoragePoolGetUUID (pool, uuid));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolGetUUID");
+  CHECK_ERROR (r == -1, "virStoragePoolGetUUID");
 
   /* UUIDs are byte arrays with a fixed length. */
   rv = caml_alloc_string (VIR_UUID_BUFLEN);
@@ -1617,12 +1581,11 @@ ocaml_libvirt_storage_pool_get_uuid_string (value poolv)
 
   CAMLlocal1 (rv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   char uuid[VIR_UUID_STRING_BUFLEN];
   int r;
 
   NONBLOCKING (r = virStoragePoolGetUUIDString (pool, uuid));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolGetUUIDString");
+  CHECK_ERROR (r == -1, "virStoragePoolGetUUIDString");
 
   rv = caml_copy_string (uuid);
   CAMLreturn (rv);
@@ -1643,7 +1606,7 @@ ocaml_libvirt_storage_pool_create_xml (value connv, value strv)
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolCreateXML (conn, str, 0));
-  CHECK_ERROR (!r, conn, "virStoragePoolCreateXML");
+  CHECK_ERROR (!r, "virStoragePoolCreateXML");
 
   rv = Val_pool (r, connv);
 
@@ -1665,7 +1628,7 @@ ocaml_libvirt_storage_pool_define_xml (value connv, value strv)
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolDefineXML (conn, str, 0));
-  CHECK_ERROR (!r, conn, "virStoragePoolDefineXML");
+  CHECK_ERROR (!r, "virStoragePoolDefineXML");
 
   rv = Val_pool (r, connv);
 
@@ -1682,12 +1645,11 @@ ocaml_libvirt_storage_pool_build (value poolv, value iv)
   CAMLparam2 (poolv, iv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   unsigned int i = Int_val (iv);
   int r;
 
   NONBLOCKING (r = virStoragePoolBuild (pool, i));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolBuild");
+  CHECK_ERROR (r == -1, "virStoragePoolBuild");
 
   CAMLreturn (Val_unit);
 }
@@ -1702,11 +1664,10 @@ ocaml_libvirt_storage_pool_undefine (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolUndefine (pool));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolUndefine");
+  CHECK_ERROR (r == -1, "virStoragePoolUndefine");
 
   CAMLreturn (Val_unit);
 }
@@ -1721,11 +1682,10 @@ ocaml_libvirt_storage_pool_create (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolCreate (pool, 0));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolCreate");
+  CHECK_ERROR (r == -1, "virStoragePoolCreate");
 
   CAMLreturn (Val_unit);
 }
@@ -1740,12 +1700,11 @@ ocaml_libvirt_storage_pool_delete (value poolv, value iv)
   CAMLparam2 (poolv, iv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   unsigned int i = Int_val (iv);
   int r;
 
   NONBLOCKING (r = virStoragePoolDelete (pool, i));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolDelete");
+  CHECK_ERROR (r == -1, "virStoragePoolDelete");
 
   CAMLreturn (Val_unit);
 }
@@ -1760,11 +1719,10 @@ ocaml_libvirt_storage_pool_refresh (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolRefresh (pool, 0));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolRefresh");
+  CHECK_ERROR (r == -1, "virStoragePoolRefresh");
 
   CAMLreturn (Val_unit);
 }
@@ -1779,11 +1737,10 @@ ocaml_libvirt_storage_pool_get_autostart (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r, b;
 
   NONBLOCKING (r = virStoragePoolGetAutostart (pool, &b));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolGetAutostart");
+  CHECK_ERROR (r == -1, "virStoragePoolGetAutostart");
 
   CAMLreturn (b ? Val_true : Val_false);
 }
@@ -1798,13 +1755,12 @@ ocaml_libvirt_storage_pool_set_autostart (value poolv, value bv)
   CAMLparam2 (poolv, bv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r, b;
 
   b = bv == Val_true ? 1 : 0;
 
   NONBLOCKING (r = virStoragePoolSetAutostart (pool, b));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolSetAutostart");
+  CHECK_ERROR (r == -1, "virStoragePoolSetAutostart");
 
   CAMLreturn (Val_unit);
 }
@@ -1819,11 +1775,10 @@ ocaml_libvirt_storage_pool_num_of_volumes (value poolv)
   CAMLparam1 (poolv);
 
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int r;
 
   NONBLOCKING (r = virStoragePoolNumOfVolumes (pool));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolNumOfVolumes");
+  CHECK_ERROR (r == -1, "virStoragePoolNumOfVolumes");
 
   CAMLreturn (Val_int (r));
 }
@@ -1839,7 +1794,6 @@ ocaml_libvirt_storage_pool_list_volumes (value poolv, value iv)
 
   CAMLlocal2 (rv, strv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   int i = Int_val (iv);
   char *names[i];
   int r;
@@ -1855,7 +1809,7 @@ ocaml_libvirt_storage_pool_list_volumes (value poolv, value iv)
   }
 
   NONBLOCKING (r = virStoragePoolListVolumes (pool, names, i));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolListVolumes");
+  CHECK_ERROR (r == -1, "virStoragePoolListVolumes");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -1877,11 +1831,10 @@ ocaml_libvirt_storage_vol_free (value volv)
   CAMLparam1 (volv);
 
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   int r;
 
   NONBLOCKING (r = virStorageVolFree (vol));
-  CHECK_ERROR (r == -1, conn, "virStorageVolFree");
+  CHECK_ERROR (r == -1, "virStorageVolFree");
 
   /* So that we don't double-free in the finalizer: */
   Volume_val (volv) = NULL;
@@ -1899,12 +1852,11 @@ ocaml_libvirt_storage_vol_delete (value volv, value iv)
   CAMLparam2 (volv, iv);
 
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   unsigned int i = Int_val (iv);
   int r;
 
   NONBLOCKING (r = virStorageVolDelete (vol, i));
-  CHECK_ERROR (r == -1, conn, "virStorageVolDelete");
+  CHECK_ERROR (r == -1, "virStorageVolDelete");
 
   CAMLreturn (Val_unit);
 }
@@ -1920,12 +1872,11 @@ ocaml_libvirt_storage_vol_lookup_by_name (value poolv, value strv)
 
   CAMLlocal2 (rv, connv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   char *str = String_val (strv);
   virStorageVolPtr r;
 
   NONBLOCKING (r = virStorageVolLookupByName (pool, str));
-  CHECK_ERROR (!r, conn, "virStorageVolLookupByName");
+  CHECK_ERROR (!r, "virStorageVolLookupByName");
 
   connv = Field (poolv, 1);
   rv = Val_volume (r, connv);
@@ -1948,7 +1899,7 @@ ocaml_libvirt_storage_vol_lookup_by_key (value connv, value strv)
   virStorageVolPtr r;
 
   NONBLOCKING (r = virStorageVolLookupByKey (conn, str));
-  CHECK_ERROR (!r, conn, "virStorageVolLookupByKey");
+  CHECK_ERROR (!r, "virStorageVolLookupByKey");
 
   rv = Val_volume (r, connv);
 
@@ -1970,7 +1921,7 @@ ocaml_libvirt_storage_vol_lookup_by_path (value connv, value strv)
   virStorageVolPtr r;
 
   NONBLOCKING (r = virStorageVolLookupByPath (conn, str));
-  CHECK_ERROR (!r, conn, "virStorageVolLookupByPath");
+  CHECK_ERROR (!r, "virStorageVolLookupByPath");
 
   rv = Val_volume (r, connv);
 
@@ -1988,12 +1939,11 @@ ocaml_libvirt_storage_vol_create_xml (value poolv, value strv)
 
   CAMLlocal2 (rv, connv);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   char *str = String_val (strv);
   virStorageVolPtr r;
 
   NONBLOCKING (r = virStorageVolCreateXML (pool, str, 0));
-  CHECK_ERROR (!r, conn, "virStorageVolCreateXML");
+  CHECK_ERROR (!r, "virStorageVolCreateXML");
 
   connv = Field (poolv, 1);
   rv = Val_volume (r, connv);
@@ -2012,11 +1962,10 @@ ocaml_libvirt_storage_vol_get_xml_desc (value volv)
 
   CAMLlocal1 (rv);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   char *r;
 
   NONBLOCKING (r = virStorageVolGetXMLDesc (vol, 0));
-  CHECK_ERROR (!r, conn, "virStorageVolGetXMLDesc");
+  CHECK_ERROR (!r, "virStorageVolGetXMLDesc");
 
   rv = caml_copy_string (r);
   free (r);
@@ -2034,11 +1983,10 @@ ocaml_libvirt_storage_vol_get_path (value volv)
 
   CAMLlocal1 (rv);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   char *r;
 
   NONBLOCKING (r = virStorageVolGetPath (vol));
-  CHECK_ERROR (!r, conn, "virStorageVolGetPath");
+  CHECK_ERROR (!r, "virStorageVolGetPath");
 
   rv = caml_copy_string (r);
   free (r);
@@ -2056,11 +2004,10 @@ ocaml_libvirt_storage_vol_get_key (value volv)
 
   CAMLlocal1 (rv);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   const char *r;
 
   NONBLOCKING (r = virStorageVolGetKey (vol));
-  CHECK_ERROR (!r, conn, "virStorageVolGetKey");
+  CHECK_ERROR (!r, "virStorageVolGetKey");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -2077,11 +2024,10 @@ ocaml_libvirt_storage_vol_get_name (value volv)
 
   CAMLlocal1 (rv);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   const char *r;
 
   NONBLOCKING (r = virStorageVolGetName (vol));
-  CHECK_ERROR (!r, conn, "virStorageVolGetName");
+  CHECK_ERROR (!r, "virStorageVolGetName");
 
   rv = caml_copy_string (r);
   CAMLreturn (rv);
@@ -2098,11 +2044,10 @@ ocaml_libvirt_storage_pool_lookup_by_volume (value volv)
 
   CAMLlocal2 (rv, connv);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   virStoragePoolPtr r;
 
   NONBLOCKING (r = virStoragePoolLookupByVolume (vol));
-  CHECK_ERROR (!r, conn, "virStoragePoolLookupByVolume");
+  CHECK_ERROR (!r, "virStoragePoolLookupByVolume");
 
   connv = Field (volv, 1);
   rv = Val_pool (r, connv);
diff --git a/libvirt/libvirt_c_epilogue.c b/libvirt/libvirt_c_epilogue.c
index 4649724..4972e50 100644
--- a/libvirt/libvirt_c_epilogue.c
+++ b/libvirt/libvirt_c_epilogue.c
@@ -57,14 +57,14 @@ option_default (value option, value deflt)
 #endif
 
 static void
-_raise_virterror (virConnectPtr conn, const char *fn)
+_raise_virterror (const char *fn)
 {
   CAMLparam0 ();
   CAMLlocal1 (rv);
   virErrorPtr errp;
   struct _virError err;
 
-  errp = conn ? virConnGetLastError (conn) : virGetLastError ();
+  errp = virGetLastError ();
 
   if (!errp) {
     /* Fake a _virError structure. */
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 06b3852..32e5a4b 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -32,7 +32,7 @@ ocaml_libvirt_get_version (value driverv, value unit)
 
   typeVer_ptr = driver ? &typeVer : NULL;
   NONBLOCKING (r = virGetVersion (&libVer, driver, typeVer_ptr));
-  CHECK_ERROR (r == -1, NULL, "virGetVersion");
+  CHECK_ERROR (r == -1, "virGetVersion");
 
   rv = caml_alloc_tuple (2);
   Store_field (rv, 0, Val_int (libVer));
@@ -53,7 +53,7 @@ ocaml_libvirt_connect_open (value namev, value unit)
   virConnectPtr conn;
 
   NONBLOCKING (conn = virConnectOpen (name));
-  CHECK_ERROR (!conn, NULL, "virConnectOpen");
+  CHECK_ERROR (!conn, "virConnectOpen");
 
   rv = Val_connect (conn);
 
@@ -69,7 +69,7 @@ ocaml_libvirt_connect_open_readonly (value namev, value unit)
   virConnectPtr conn;
 
   NONBLOCKING (conn = virConnectOpenReadOnly (name));
-  CHECK_ERROR (!conn, NULL, "virConnectOpen");
+  CHECK_ERROR (!conn, "virConnectOpen");
 
   rv = Val_connect (conn);
 
@@ -85,7 +85,7 @@ ocaml_libvirt_connect_get_version (value connv)
   int r;
 
   NONBLOCKING (r = virConnectGetVersion (conn, &hvVer));
-  CHECK_ERROR (r == -1, conn, "virConnectGetVersion");
+  CHECK_ERROR (r == -1, "virConnectGetVersion");
 
   CAMLreturn (Val_int (hvVer));
 }
@@ -99,7 +99,7 @@ ocaml_libvirt_connect_get_max_vcpus (value connv, value typev)
   int r;
 
   NONBLOCKING (r = virConnectGetMaxVcpus (conn, type));
-  CHECK_ERROR (r == -1, conn, "virConnectGetMaxVcpus");
+  CHECK_ERROR (r == -1, "virConnectGetMaxVcpus");
 
   CAMLreturn (Val_int (r));
 }
@@ -114,7 +114,7 @@ ocaml_libvirt_connect_get_node_info (value connv)
   int r;
 
   NONBLOCKING (r = virNodeGetInfo (conn, &info));
-  CHECK_ERROR (r == -1, conn, "virNodeGetInfo");
+  CHECK_ERROR (r == -1, "virNodeGetInfo");
 
   rv = caml_alloc (8, 0);
   v = caml_copy_string (info.model); Store_field (rv, 0, v);
@@ -138,7 +138,7 @@ ocaml_libvirt_connect_node_get_free_memory (value connv)
   unsigned long long r;
 
   NONBLOCKING (r = virNodeGetFreeMemory (conn));
-  CHECK_ERROR (r == 0, conn, "virNodeGetFreeMemory");
+  CHECK_ERROR (r == 0, "virNodeGetFreeMemory");
 
   rv = caml_copy_int64 ((int64_t) r);
   CAMLreturn (rv);
@@ -157,7 +157,7 @@ ocaml_libvirt_connect_node_get_cells_free_memory (value connv,
   unsigned long long freemems[max];
 
   NONBLOCKING (r = virNodeGetCellsFreeMemory (conn, freemems, start, max));
-  CHECK_ERROR (r == -1, conn, "virNodeGetCellsFreeMemory");
+  CHECK_ERROR (r == -1, "virNodeGetCellsFreeMemory");
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
@@ -179,7 +179,7 @@ ocaml_libvirt_connect_set_keep_alive(value connv,
   int r;
 
   NONBLOCKING(r = virConnectSetKeepAlive(conn, interval, count));
-  CHECK_ERROR (r == -1, conn, "virConnectSetKeepAlive");
+  CHECK_ERROR (r == -1, "virConnectSetKeepAlive");
 
   CAMLreturn(Val_unit);
 }
@@ -190,7 +190,6 @@ ocaml_libvirt_domain_get_id (value domv)
 {
   CAMLparam1 (domv);
   virDomainPtr dom = Domain_val (domv);
-  /*virConnectPtr conn = Connect_domv (domv);*/
   unsigned int r;
 
   NONBLOCKING (r = virDomainGetID (dom));
@@ -208,11 +207,10 @@ ocaml_libvirt_domain_get_max_memory (value domv)
   CAMLparam1 (domv);
   CAMLlocal1 (rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   unsigned long r;
 
   NONBLOCKING (r = virDomainGetMaxMemory (dom));
-  CHECK_ERROR (r == 0 /* [sic] */, conn, "virDomainGetMaxMemory");
+  CHECK_ERROR (r == 0 /* [sic] */, "virDomainGetMaxMemory");
 
   rv = caml_copy_int64 (r);
   CAMLreturn (rv);
@@ -223,12 +221,11 @@ ocaml_libvirt_domain_set_max_memory (value domv, value memv)
 {
   CAMLparam2 (domv, memv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   unsigned long mem = Int64_val (memv);
   int r;
 
   NONBLOCKING (r = virDomainSetMaxMemory (dom, mem));
-  CHECK_ERROR (r == -1, conn, "virDomainSetMaxMemory");
+  CHECK_ERROR (r == -1, "virDomainSetMaxMemory");
 
   CAMLreturn (Val_unit);
 }
@@ -238,12 +235,11 @@ ocaml_libvirt_domain_set_memory (value domv, value memv)
 {
   CAMLparam2 (domv, memv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   unsigned long mem = Int64_val (memv);
   int r;
 
   NONBLOCKING (r = virDomainSetMemory (dom, mem));
-  CHECK_ERROR (r == -1, conn, "virDomainSetMemory");
+  CHECK_ERROR (r == -1, "virDomainSetMemory");
 
   CAMLreturn (Val_unit);
 }
@@ -254,12 +250,11 @@ ocaml_libvirt_domain_get_info (value domv)
   CAMLparam1 (domv);
   CAMLlocal2 (rv, v);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   virDomainInfo info;
   int r;
 
   NONBLOCKING (r = virDomainGetInfo (dom, &info));
-  CHECK_ERROR (r == -1, conn, "virDomainGetInfo");
+  CHECK_ERROR (r == -1, "virDomainGetInfo");
 
   rv = caml_alloc (5, 0);
   Store_field (rv, 0, Val_int (info.state)); // These flags are compatible.
@@ -277,12 +272,11 @@ ocaml_libvirt_domain_get_scheduler_type (value domv)
   CAMLparam1 (domv);
   CAMLlocal2 (rv, strv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *r;
   int nparams;
 
   NONBLOCKING (r = virDomainGetSchedulerType (dom, &nparams));
-  CHECK_ERROR (!r, conn, "virDomainGetSchedulerType");
+  CHECK_ERROR (!r, "virDomainGetSchedulerType");
 
   rv = caml_alloc_tuple (2);
   strv = caml_copy_string (r); Store_field (rv, 0, strv);
@@ -297,13 +291,12 @@ ocaml_libvirt_domain_get_scheduler_parameters (value domv, value nparamsv)
   CAMLparam2 (domv, nparamsv);
   CAMLlocal4 (rv, v, v2, v3);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int nparams = Int_val (nparamsv);
   virSchedParameter params[nparams];
   int r, i;
 
   NONBLOCKING (r = virDomainGetSchedulerParameters (dom, params, &nparams));
-  CHECK_ERROR (r == -1, conn, "virDomainGetSchedulerParameters");
+  CHECK_ERROR (r == -1, "virDomainGetSchedulerParameters");
 
   rv = caml_alloc (nparams, 0);
   for (i = 0; i < nparams; ++i) {
@@ -348,7 +341,6 @@ ocaml_libvirt_domain_set_scheduler_parameters (value domv, value paramsv)
   CAMLparam2 (domv, paramsv);
   CAMLlocal1 (v);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int nparams = Wosize_val (paramsv);
   virSchedParameter params[nparams];
   int r, i;
@@ -391,7 +383,7 @@ ocaml_libvirt_domain_set_scheduler_parameters (value domv, value paramsv)
   }
 
   NONBLOCKING (r = virDomainSetSchedulerParameters (dom, params, nparams));
-  CHECK_ERROR (r == -1, conn, "virDomainSetSchedulerParameters");
+  CHECK_ERROR (r == -1, "virDomainSetSchedulerParameters");
 
   CAMLreturn (Val_unit);
 }
@@ -401,11 +393,10 @@ ocaml_libvirt_domain_set_vcpus (value domv, value nvcpusv)
 {
   CAMLparam2 (domv, nvcpusv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int r, nvcpus = Int_val (nvcpusv);
 
   NONBLOCKING (r = virDomainSetVcpus (dom, nvcpus));
-  CHECK_ERROR (r == -1, conn, "virDomainSetVcpus");
+  CHECK_ERROR (r == -1, "virDomainSetVcpus");
 
   CAMLreturn (Val_unit);
 }
@@ -415,14 +406,13 @@ ocaml_libvirt_domain_pin_vcpu (value domv, value vcpuv, value cpumapv)
 {
   CAMLparam3 (domv, vcpuv, cpumapv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int maplen = caml_string_length (cpumapv);
   unsigned char *cpumap = (unsigned char *) String_val (cpumapv);
   int vcpu = Int_val (vcpuv);
   int r;
 
   NONBLOCKING (r = virDomainPinVcpu (dom, vcpu, cpumap, maplen));
-  CHECK_ERROR (r == -1, conn, "virDomainPinVcpu");
+  CHECK_ERROR (r == -1, "virDomainPinVcpu");
 
   CAMLreturn (Val_unit);
 }
@@ -433,7 +423,6 @@ ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value maplenv)
   CAMLparam3 (domv, maxinfov, maplenv);
   CAMLlocal5 (rv, infov, strv, v, v2);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int maxinfo = Int_val (maxinfov);
   int maplen = Int_val (maplenv);
   virVcpuInfo info[maxinfo];
@@ -444,7 +433,7 @@ ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value maplenv)
   memset (cpumaps, 0, maxinfo * maplen);
 
   NONBLOCKING (r = virDomainGetVcpus (dom, info, maxinfo, cpumaps, maplen));
-  CHECK_ERROR (r == -1, conn, "virDomainPinVcpu");
+  CHECK_ERROR (r == -1, "virDomainPinVcpu");
 
   /* Copy the virVcpuInfo structures. */
   infov = caml_alloc (maxinfo, 0);
@@ -476,18 +465,17 @@ ocaml_libvirt_domain_get_cpu_stats (value domv)
   CAMLlocal5 (cpustats, param_head, param_node, typed_param, typed_param_value);
   CAMLlocal1 (v);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   virTypedParameterPtr params;
   int r, cpu, ncpus, nparams, i, j, pos;
   int nr_pcpus;
 
   /* get number of pcpus */
   NONBLOCKING (nr_pcpus = virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0));
-  CHECK_ERROR (nr_pcpus < 0, conn, "virDomainGetCPUStats");
+  CHECK_ERROR (nr_pcpus < 0, "virDomainGetCPUStats");
 
   /* get percpu information */
   NONBLOCKING (nparams = virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0));
-  CHECK_ERROR (nparams < 0, conn, "virDomainGetCPUStats");
+  CHECK_ERROR (nparams < 0, "virDomainGetCPUStats");
 
   if ((params = malloc(sizeof(*params) * nparams * 128)) == NULL)
     caml_failwith ("virDomainGetCPUStats: malloc");
@@ -498,7 +486,7 @@ ocaml_libvirt_domain_get_cpu_stats (value domv)
     ncpus = nr_pcpus - cpu > 128 ? 128 : nr_pcpus - cpu;
 
     NONBLOCKING (r = virDomainGetCPUStats(dom, params, nparams, cpu, ncpus, 0));
-    CHECK_ERROR (r < 0, conn, "virDomainGetCPUStats");
+    CHECK_ERROR (r < 0, "virDomainGetCPUStats");
 
     for (i = 0; i < ncpus; i++) {
       /* list of typed_param: single linked list of param_nodes */
@@ -579,7 +567,6 @@ ocaml_libvirt_domain_migrate_native (value domv, value dconnv, value flagsv, val
   CAMLxparam2 (optbandwidthv, unitv);
   CAMLlocal2 (flagv, rv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   virConnectPtr dconn = Connect_val (dconnv);
   int flags = 0;
   const char *dname = Optstring_val (optdnamev);
@@ -601,7 +588,7 @@ ocaml_libvirt_domain_migrate_native (value domv, value dconnv, value flagsv, val
     bandwidth = Int_val (Field (optbandwidthv, 0));
 
   NONBLOCKING (r = virDomainMigrate (dom, dconn, flags, dname, uri, bandwidth));
-  CHECK_ERROR (!r, conn, "virDomainMigrate");
+  CHECK_ERROR (!r, "virDomainMigrate");
 
   rv = Val_domain (r, dconnv);
 
@@ -622,13 +609,12 @@ ocaml_libvirt_domain_block_stats (value domv, value pathv)
   CAMLparam2 (domv, pathv);
   CAMLlocal2 (rv,v);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *path = String_val (pathv);
   struct _virDomainBlockStats stats;
   int r;
 
   NONBLOCKING (r = virDomainBlockStats (dom, path, &stats, sizeof stats));
-  CHECK_ERROR (r == -1, conn, "virDomainBlockStats");
+  CHECK_ERROR (r == -1, "virDomainBlockStats");
 
   rv = caml_alloc (5, 0);
   v = caml_copy_int64 (stats.rd_req); Store_field (rv, 0, v);
@@ -646,13 +632,12 @@ ocaml_libvirt_domain_interface_stats (value domv, value pathv)
   CAMLparam2 (domv, pathv);
   CAMLlocal2 (rv,v);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   char *path = String_val (pathv);
   struct _virDomainInterfaceStats stats;
   int r;
 
   NONBLOCKING (r = virDomainInterfaceStats (dom, path, &stats, sizeof stats));
-  CHECK_ERROR (r == -1, conn, "virDomainInterfaceStats");
+  CHECK_ERROR (r == -1, "virDomainInterfaceStats");
 
   rv = caml_alloc (8, 0);
   v = caml_copy_int64 (stats.rx_bytes); Store_field (rv, 0, v);
@@ -673,7 +658,6 @@ ocaml_libvirt_domain_block_peek_native (value domv, value pathv, value offsetv,
   CAMLparam5 (domv, pathv, offsetv, sizev, bufferv);
   CAMLxparam1 (boffv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   const char *path = String_val (pathv);
   unsigned long long offset = Int64_val (offsetv);
   size_t size = Int_val (sizev);
@@ -687,7 +671,7 @@ ocaml_libvirt_domain_block_peek_native (value domv, value pathv, value offsetv,
 
   /* NB. not NONBLOCKING because buffer might move (XXX) */
   r = virDomainBlockPeek (dom, path, offset, size, buffer+boff, 0);
-  CHECK_ERROR (r == -1, conn, "virDomainBlockPeek");
+  CHECK_ERROR (r == -1, "virDomainBlockPeek");
 
   CAMLreturn (Val_unit);
 }
@@ -706,7 +690,6 @@ ocaml_libvirt_domain_memory_peek_native (value domv, value flagsv, value offsetv
   CAMLxparam1 (boffv);
   CAMLlocal1 (flagv);
   virDomainPtr dom = Domain_val (domv);
-  virConnectPtr conn = Connect_domv (domv);
   int flags = 0;
   unsigned long long offset = Int64_val (offsetv);
   size_t size = Int_val (sizev);
@@ -728,7 +711,7 @@ ocaml_libvirt_domain_memory_peek_native (value domv, value flagsv, value offsetv
 
   /* NB. not NONBLOCKING because buffer might move (XXX) */
   r = virDomainMemoryPeek (dom, offset, size, buffer+boff, flags);
-  CHECK_ERROR (r == -1, conn, "virDomainMemoryPeek");
+  CHECK_ERROR (r == -1, "virDomainMemoryPeek");
 
   CAMLreturn (Val_unit);
 }
@@ -1042,7 +1025,6 @@ CAMLprim value
 ocaml_libvirt_event_add_timeout (value connv, value ms, value callback_id)
 {
   CAMLparam3 (connv, ms, callback_id);
-  virConnectPtr conn = Connect_val (connv);
   void *opaque;
   virFreeCallback freecb = free;
   virEventTimeoutCallback cb = timeout_callback;
@@ -1055,7 +1037,7 @@ ocaml_libvirt_event_add_timeout (value connv, value ms, value callback_id)
     caml_failwith ("virEventAddTimeout: malloc");
   *((long*)opaque) = Int64_val(callback_id);
   NONBLOCKING(r = virEventAddTimeout(Int_val(ms), cb, opaque, freecb));
-  CHECK_ERROR(r == -1, conn, "virEventAddTimeout");
+  CHECK_ERROR(r == -1, "virEventAddTimeout");
 
   CAMLreturn(Val_int(r));
 }
@@ -1064,11 +1046,10 @@ CAMLprim value
 ocaml_libvirt_event_remove_timeout (value connv, value timer_id)
 {
   CAMLparam2 (connv, timer_id);
-  virConnectPtr conn = Connect_val (connv);
   int r;
 
   NONBLOCKING(r = virEventRemoveTimeout(Int_val(timer_id)));
-  CHECK_ERROR(r == -1, conn, "virEventRemoveTimeout");
+  CHECK_ERROR(r == -1, "virEventRemoveTimeout");
 
   CAMLreturn(Val_int(r));
 }
@@ -1146,7 +1127,7 @@ ocaml_libvirt_connect_domain_event_register_any(value connv, value domv, value c
     caml_failwith ("virConnectDomainEventRegisterAny: malloc");
   *((long*)opaque) = Int64_val(callback_id);
   NONBLOCKING(r = virConnectDomainEventRegisterAny(conn, dom, eventID, cb, opaque, freecb));
-  CHECK_ERROR(r == -1, conn, "virConnectDomainEventRegisterAny");
+  CHECK_ERROR(r == -1, "virConnectDomainEventRegisterAny");
 
   CAMLreturn(Val_int(r));
 }
@@ -1157,12 +1138,11 @@ ocaml_libvirt_storage_pool_get_info (value poolv)
   CAMLparam1 (poolv);
   CAMLlocal2 (rv, v);
   virStoragePoolPtr pool = Pool_val (poolv);
-  virConnectPtr conn = Connect_polv (poolv);
   virStoragePoolInfo info;
   int r;
 
   NONBLOCKING (r = virStoragePoolGetInfo (pool, &info));
-  CHECK_ERROR (r == -1, conn, "virStoragePoolGetInfo");
+  CHECK_ERROR (r == -1, "virStoragePoolGetInfo");
 
   rv = caml_alloc (4, 0);
   Store_field (rv, 0, Val_int (info.state));
@@ -1179,12 +1159,11 @@ ocaml_libvirt_storage_vol_get_info (value volv)
   CAMLparam1 (volv);
   CAMLlocal2 (rv, v);
   virStorageVolPtr vol = Volume_val (volv);
-  virConnectPtr conn = Connect_volv (volv);
   virStorageVolInfo info;
   int r;
 
   NONBLOCKING (r = virStorageVolGetInfo (vol, &info));
-  CHECK_ERROR (r == -1, conn, "virStorageVolGetInfo");
+  CHECK_ERROR (r == -1, "virStorageVolGetInfo");
 
   rv = caml_alloc (3, 0);
   Store_field (rv, 0, Val_int (info.type));
@@ -1239,6 +1218,12 @@ ocaml_libvirt_virterror_reset_last_conn_error (value connv)
 
 /*----------------------------------------------------------------------*/
 
+static void
+ignore_errors (void *user_data, virErrorPtr error)
+{
+  /* do nothing */
+}
+
 /* Initialise the library. */
 CAMLprim value
 ocaml_libvirt_init (value unit)
@@ -1247,8 +1232,9 @@ ocaml_libvirt_init (value unit)
   CAMLlocal1 (rv);
   int r;
 
+  virSetErrorFunc (NULL, ignore_errors);
   r = virInitialize ();
-  CHECK_ERROR (r == -1, NULL, "virInitialize");
+  CHECK_ERROR (r == -1, "virInitialize");
 
   CAMLreturn (Val_unit);
 }
diff --git a/libvirt/libvirt_c_prologue.c b/libvirt/libvirt_c_prologue.c
index 7d9c0f5..bf972e9 100644
--- a/libvirt/libvirt_c_prologue.c
+++ b/libvirt/libvirt_c_prologue.c
@@ -24,7 +24,7 @@ static char *Optstring_val (value strv);
 typedef value (*Val_ptr_t) (void *);
 static value Val_opt (void *ptr, Val_ptr_t Val_ptr);
 /*static value option_default (value option, value deflt);*/
-static void _raise_virterror (virConnectPtr conn, const char *fn) Noreturn;
+static void _raise_virterror (const char *fn) Noreturn;
 static void not_supported (const char *fn) Noreturn;
 static value Val_virterror (virErrorPtr err);
 
@@ -43,8 +43,8 @@ static value Val_virterror (virErrorPtr err);
 /* Check error condition from a libvirt function, and automatically raise
  * an exception if one is found.
  */
-#define CHECK_ERROR(cond, conn, fn) \
-  do { if (cond) _raise_virterror (conn, fn); } while (0)
+#define CHECK_ERROR(cond, fn) \
+  do { if (cond) _raise_virterror (fn); } while (0)
 
 /*----------------------------------------------------------------------*/
 
-- 
2.3.1

diff --git a/testing/ocaml-libvirt/0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch b/testing/ocaml-libvirt/0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch
new file mode 100644
index 0000000000..c00a75a103
--- /dev/null
+++ b/testing/ocaml-libvirt/0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch
@@ -0,0 +1,35 @@
From 21ac993da0a187821e812fe7b5b31a426121a546 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 30 Aug 2014 19:10:19 +0100
Subject: [PATCH] Use C99 standard int64_t instead of OCaml defined (and soon
 to go) int64.

---
 libvirt/libvirt_c_oneoffs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 3bb572f..06b3852 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -140,7 +140,7 @@ ocaml_libvirt_connect_node_get_free_memory (value connv)
   NONBLOCKING (r = virNodeGetFreeMemory (conn));
   CHECK_ERROR (r == 0, conn, "virNodeGetFreeMemory");
 
-  rv = caml_copy_int64 ((int64) r);
+  rv = caml_copy_int64 ((int64_t) r);
   CAMLreturn (rv);
 }
 
@@ -161,7 +161,7 @@ ocaml_libvirt_connect_node_get_cells_free_memory (value connv,
 
   rv = caml_alloc (r, 0);
   for (i = 0; i < r; ++i) {
-    iv = caml_copy_int64 ((int64) freemems[i]);
+    iv = caml_copy_int64 ((int64_t) freemems[i]);
     Store_field (rv, i, iv);
   }
 
-- 
2.0.4

diff --git a/testing/ocaml-libvirt/0001-Use-g-warn-error.patch b/testing/ocaml-libvirt/0001-Use-g-warn-error.patch
new file mode 100644
index 0000000000..7c6bf35a54
--- /dev/null
+++ b/testing/ocaml-libvirt/0001-Use-g-warn-error.patch
@@ -0,0 +1,78 @@
From 2ba6898b4dc121b00078e36d5416b3caadd5d05e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 27 Mar 2017 14:12:50 +0100
Subject: [PATCH 1/5] Use -g -warn-error.

Use -g for ocamlopt.  ocamlopt has supported generating DWARF
information for quite a long time.

Also use -warn-error with the same set of warnings as is used
by libguestfs.

Fix a warning in examples/get_cpu_stats.ml found by enabling
-warn-error.
---
 examples/Makefile.in      | 4 ++--
 examples/get_cpu_stats.ml | 2 ++
 libvirt/Makefile.in       | 6 +++---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/examples/Makefile.in b/examples/Makefile.in
index 041e382..46006a0 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -18,10 +18,10 @@
 OCAMLFIND	= @OCAMLFIND@
 
 OCAMLCPACKAGES	:= -package unix -I ../libvirt
-OCAMLCFLAGS	:= -g
+OCAMLCFLAGS	:= -g -warn-error CDEFLMPSUVYZX-3
 OCAMLCLIBS	:= -linkpkg
 OCAMLOPTPACKAGES := $(OCAMLCPACKAGES)
-OCAMLOPTFLAGS	:=
+OCAMLOPTFLAGS	:= -g -warn-error CDEFLMPSUVYZX-3
 OCAMLOPTLIBS	:= $(OCAMLCLIBS)
 
 export LIBRARY_PATH=../libvirt
diff --git a/examples/get_cpu_stats.ml b/examples/get_cpu_stats.ml
index d7a8d0c..814c85e 100644
--- a/examples/get_cpu_stats.ml
+++ b/examples/get_cpu_stats.ml
@@ -19,9 +19,11 @@ let () =
 
     let conn = C.connect_readonly () in
 
+    (*
     let nr_pcpus =
       let info = C.get_node_info conn in
       C.maxcpus_of_node_info info in
+     *)
 
     let stats =
       let dom = D.lookup_by_name conn domname in
diff --git a/libvirt/Makefile.in b/libvirt/Makefile.in
index f7c04bb..cf614fc 100644
--- a/libvirt/Makefile.in
+++ b/libvirt/Makefile.in
@@ -31,15 +31,15 @@ OCAMLMKLIB	= @OCAMLMKLIB@
 
 ifneq ($(OCAMLFIND),)
 OCAMLCPACKAGES	:= -package unix
-OCAMLCFLAGS	:= -g
+OCAMLCFLAGS	:= -g -warn-error CDEFLMPSUVYZX-3
 OCAMLCLIBS	:= -linkpkg
 else
 OCAMLCINCS	:=
-OCAMLCFLAGS	:= -g
+OCAMLCFLAGS	:= -g -warn-error CDEFLMPSUVYZX-3
 OCAMLCLIBS	:= unix.cma
 endif
 
-OCAMLOPTFLAGS	:=
+OCAMLOPTFLAGS	:= $(OCAMLCFLAGS)
 ifneq ($(OCAMLFIND),)
 OCAMLOPTPACKAGES := $(OCAMLCPACKAGES)
 OCAMLOPTLIBS	:= $(OCAMLCLIBS)
-- 
2.9.3

diff --git a/testing/ocaml-libvirt/0002-Don-t-bother-checking-return-from-virInitialize.patch b/testing/ocaml-libvirt/0002-Don-t-bother-checking-return-from-virInitialize.patch
new file mode 100644
index 0000000000..bbf01a6a50
--- /dev/null
+++ b/testing/ocaml-libvirt/0002-Don-t-bother-checking-return-from-virInitialize.patch
@@ -0,0 +1,32 @@
From 06b24089986523806d386b9e3cfa4fcf5eeb87e6 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 17 Mar 2015 12:53:29 +0000
Subject: [PATCH 2/2] Don't bother checking return from virInitialize.

The Perl bindings don't do this, and it seems that the call can never
fail, or if it does we don't care.
---
 libvirt/libvirt_c_oneoffs.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 32e5a4b..5d82194 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -1229,12 +1229,9 @@ CAMLprim value
 ocaml_libvirt_init (value unit)
 {
   CAMLparam1 (unit);
-  CAMLlocal1 (rv);
-  int r;
 
   virSetErrorFunc (NULL, ignore_errors);
-  r = virInitialize ();
-  CHECK_ERROR (r == -1, "virInitialize");
+  virInitialize ();
 
   CAMLreturn (Val_unit);
 }
-- 
2.3.1

diff --git a/testing/ocaml-libvirt/0002-Update-dependencies.patch b/testing/ocaml-libvirt/0002-Update-dependencies.patch
new file mode 100644
index 0000000000..1ba95ea3a6
--- /dev/null
+++ b/testing/ocaml-libvirt/0002-Update-dependencies.patch
@@ -0,0 +1,44 @@
From ca9a3227f9937f9cdeb84126f1c74502c9a25047 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 27 Mar 2017 14:13:47 +0100
Subject: [PATCH 2/5] Update dependencies.

---
 examples/.depend | 8 ++++----
 libvirt/.depend  | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/examples/.depend b/examples/.depend
index b305b76..b5379d8 100644
--- a/examples/.depend
+++ b/examples/.depend
@@ -1,8 +1,8 @@
-node_info.cmo : ../libvirt/libvirt.cmi
-node_info.cmx : ../libvirt/libvirt.cmx
-get_cpu_stats.cmo : ../libvirt/libvirt.cmi
-get_cpu_stats.cmx : ../libvirt/libvirt.cmx
 domain_events.cmo : ../libvirt/libvirt.cmi
 domain_events.cmx : ../libvirt/libvirt.cmx
+get_cpu_stats.cmo : ../libvirt/libvirt.cmi
+get_cpu_stats.cmx : ../libvirt/libvirt.cmx
 list_domains.cmo : ../libvirt/libvirt.cmi
 list_domains.cmx : ../libvirt/libvirt.cmx
+node_info.cmo : ../libvirt/libvirt.cmi
+node_info.cmx : ../libvirt/libvirt.cmx
diff --git a/libvirt/.depend b/libvirt/.depend
index 7d32e13..ee1180c 100644
--- a/libvirt/.depend
+++ b/libvirt/.depend
@@ -1,6 +1,6 @@
-libvirt_version.cmi :
+libvirt.cmo : libvirt.cmi
+libvirt.cmx : libvirt.cmi
 libvirt.cmi :
 libvirt_version.cmo : libvirt_version.cmi
 libvirt_version.cmx : libvirt_version.cmi
-libvirt.cmo : libvirt.cmi
-libvirt.cmx : libvirt.cmi
+libvirt_version.cmi :
-- 
2.9.3

diff --git a/testing/ocaml-libvirt/0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch b/testing/ocaml-libvirt/0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch
new file mode 100644
index 0000000000..0eb1b28eef
--- /dev/null
+++ b/testing/ocaml-libvirt/0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch
@@ -0,0 +1,393 @@
From 380f1e05b244ae4750ca5101b5b5a182dcd0d1fd Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Mar 2017 10:08:06 +0100
Subject: [PATCH 3/5] Add a binding for virConnectGetAllDomainStats
 (RHBZ#1390171).

---
 .gitignore                       |   2 +
 Makefile.in                      |   1 +
 examples/.depend                 |   2 +
 examples/Makefile.in             |  13 ++++-
 examples/get_all_domain_stats.ml |  65 +++++++++++++++++++++
 libvirt/libvirt.ml               |  23 ++++++++
 libvirt/libvirt.mli              |  28 +++++++++
 libvirt/libvirt_c_oneoffs.c      | 119 ++++++++++++++++++++++++++++++++++++++-
 8 files changed, 250 insertions(+), 3 deletions(-)
 create mode 100644 examples/get_all_domain_stats.ml

diff --git a/.gitignore b/.gitignore
index 71a245e..366eb29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.gdb_history
 META
 ocaml-libvirt-*.tar.gz
 ocaml-libvirt-*.exe
@@ -27,6 +28,7 @@ core.*
 *~
 libvirt/libvirt_version.ml
 examples/domain_events
+examples/get_all_domain_stats
 examples/get_cpu_stats
 examples/list_domains
 examples/node_info
diff --git a/Makefile.in b/Makefile.in
index 3b8b7ec..2605ddd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -41,6 +41,7 @@ clean:
 	rm -f examples/node_info
 	rm -f examples/get_cpu_stats
 	rm -f examples/domain_events
+	rm -f examples/get_all_domain_stats
 
 distclean: clean
 	rm -f config.h config.log config.status configure
diff --git a/examples/.depend b/examples/.depend
index b5379d8..11f2c7c 100644
--- a/examples/.depend
+++ b/examples/.depend
@@ -1,5 +1,7 @@
 domain_events.cmo : ../libvirt/libvirt.cmi
 domain_events.cmx : ../libvirt/libvirt.cmx
+get_all_domain_stats.cmo : ../libvirt/libvirt.cmi
+get_all_domain_stats.cmx : ../libvirt/libvirt.cmx
 get_cpu_stats.cmo : ../libvirt/libvirt.cmi
 get_cpu_stats.cmx : ../libvirt/libvirt.cmx
 list_domains.cmo : ../libvirt/libvirt.cmi
diff --git a/examples/Makefile.in b/examples/Makefile.in
index 46006a0..8530edc 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -27,7 +27,8 @@ OCAMLOPTLIBS	:= $(OCAMLCLIBS)
 export LIBRARY_PATH=../libvirt
 export LD_LIBRARY_PATH=../libvirt
 
-BYTE_TARGETS	:= list_domains node_info get_cpu_stats domain_events
+BYTE_TARGETS	:= list_domains node_info get_cpu_stats \
+		   get_all_domain_stats domain_events
 OPT_TARGETS	:= $(BYTE_TARGETS:%=%.opt)
 
 all: $(BYTE_TARGETS)
@@ -64,6 +65,16 @@ get_cpu_stats.opt: get_cpu_stats.cmx
 	  $(OCAMLOPTPACKAGES) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
 	  ../libvirt/mllibvirt.cmxa -o $@ $<
 
+get_all_domain_stats: get_all_domain_stats.cmo
+	$(OCAMLFIND) ocamlc \
+	  $(OCAMLCPACKAGES) $(OCAMLCFLAGS) $(OCAMLCLIBS) \
+	  ../libvirt/mllibvirt.cma -o $@ $<
+
+get_all_domain_stats.opt: get_all_domain_stats.cmx
+	$(OCAMLFIND) ocamlopt \
+	  $(OCAMLOPTPACKAGES) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
+	  ../libvirt/mllibvirt.cmxa -o $@ $<
+
 domain_events: domain_events.cmo
 	$(OCAMLFIND) ocamlc \
 	  $(OCAMLCPACKAGES) $(OCAMLCFLAGS) $(OCAMLCLIBS) \
diff --git a/examples/get_all_domain_stats.ml b/examples/get_all_domain_stats.ml
new file mode 100644
index 0000000..4375639
--- /dev/null
+++ b/examples/get_all_domain_stats.ml
@@ -0,0 +1,65 @@
+(* Example of using Domain.get_all_domain_stats (virConnectGetAllDomainStats).
+ * Usage: get_all_domain_stats
+ * http://libvirt.org/
+ *)
+
+open Printf
+
+module C = Libvirt.Connect
+module D = Libvirt.Domain
+
+let print_stats stats =
+  try
+    Array.iter (
+      fun { D.dom = dom; D.params = params } ->
+        printf "domain %s:\n" (D.get_name dom);
+        Array.iteri (
+          fun i (field, value) ->
+            printf "\t%-20s = " field;
+            (match value with
+             | D.TypedFieldInt32 i -> printf "%ld" i
+             | D.TypedFieldUInt32 i -> printf "%ld" i
+             | D.TypedFieldInt64 i -> printf "%Ld" i
+             | D.TypedFieldUInt64 i -> printf "%Ld" i
+             | D.TypedFieldFloat f -> printf "%g" f
+             | D.TypedFieldBool b -> printf "%b" b
+             | D.TypedFieldString s -> printf "%S" s);
+            printf "\n";
+        ) params;
+        printf "\n"
+    ) stats
+  with
+    Libvirt.Virterror err ->
+      eprintf "error: %s\n" (Libvirt.Virterror.to_string err)
+
+let () =
+  if Array.length Sys.argv <> 1 then (
+    eprintf "error: get_all_domain_stats\n";
+    exit 1
+  );
+
+  let conn = C.connect_readonly () in
+
+  let what_stats = [D.StatsCpuTotal; D.StatsInterface; D.StatsBlock] in
+  let flags = [D.GetAllDomainsStatsActive; D.GetAllDomainsStatsInactive] in
+
+  let quit = ref false in
+
+  while not !quit do
+    let stats = D.get_all_domain_stats conn what_stats flags in
+
+    if stats <> [||] then print_stats stats
+    else (
+      printf "no guests found\n";
+      quit := true
+    );
+    flush stdout;
+
+    (* Run the garbage collector which is a good way to check for
+     * memory corruption errors and reference counting issues in
+     * libvirt.  You shouldn't do this in ordinary programs.
+     *)
+    Gc.compact ();
+
+    if not !quit then Unix.sleep 3
+  done
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
index 1be023d..ce1878a 100644
--- a/libvirt/libvirt.ml
+++ b/libvirt/libvirt.ml
@@ -392,6 +392,27 @@ struct
     tx_drop : int64;
   }
 
+  type get_all_domain_stats_flag =
+    | GetAllDomainsStatsActive
+    | GetAllDomainsStatsInactive
+    | GetAllDomainsStatsOther
+    | GetAllDomainsStatsPaused
+    | GetAllDomainsStatsPersistent
+    | GetAllDomainsStatsRunning
+    | GetAllDomainsStatsShutoff
+    | GetAllDomainsStatsTransient
+    | GetAllDomainsStatsBacking
+    | GetAllDomainsStatsEnforceStats
+
+  type stats_type =
+    | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
+    | StatsInterface | StatsBlock | StatsPerf
+
+  type 'a domain_stats_record = {
+    dom : 'a t;
+    params : typed_param array;
+  }
+
   (* The maximum size for Domain.memory_peek and Domain.block_peek
    * supported by libvirt.  This may change with different versions
    * of libvirt in the future, hence it's a function.
@@ -446,6 +467,8 @@ struct
   external block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_block_peek_bytecode" "ocaml_libvirt_domain_block_peek_native"
   external memory_peek : [>`W] t -> memory_flag list -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
 
+  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
+
   external const : [>`R] t -> ro t = "%identity"
 
   let get_domains conn flags =
diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli
index 8cfcae2..d1b5992 100644
--- a/libvirt/libvirt.mli
+++ b/libvirt/libvirt.mli
@@ -478,6 +478,27 @@ sig
     tx_drop : int64;
   }
 
+  type get_all_domain_stats_flag =
+    | GetAllDomainsStatsActive
+    | GetAllDomainsStatsInactive
+    | GetAllDomainsStatsOther
+    | GetAllDomainsStatsPaused
+    | GetAllDomainsStatsPersistent
+    | GetAllDomainsStatsRunning
+    | GetAllDomainsStatsShutoff
+    | GetAllDomainsStatsTransient
+    | GetAllDomainsStatsBacking
+    | GetAllDomainsStatsEnforceStats
+
+  type stats_type =
+    | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
+    | StatsInterface | StatsBlock | StatsPerf
+
+  type 'a domain_stats_record = {
+    dom : 'a t;
+    params : typed_param array;
+  }
+
   val max_peek : [>`R] t -> int
     (** Maximum size supported by the {!block_peek} and {!memory_peek}
 	functions.  If you want to peek more than this then you must
@@ -615,6 +636,13 @@ sig
 
 	See also {!max_peek}. *)
 
+  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
+    (** [get_all_domain_stats conn stats flags] allows you to read
+        all stats across multiple/all domains in a single call.
+
+        See the libvirt documentation for
+        [virConnectGetAllDomainStats]. *)
+
   external const : [>`R] t -> ro t = "%identity"
     (** [const dom] turns a read/write domain handle into a read-only
 	domain handle.  Note that the opposite operation is impossible.
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 5d82194..17412f5 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -1,5 +1,5 @@
 /* OCaml bindings for libvirt.
- * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+ * (C) Copyright 2007-2017 Richard W.M. Jones, Red Hat Inc.
  * http://libvirt.org/
  *
  * This library is free software; you can redistribute it and/or
@@ -184,7 +184,6 @@ ocaml_libvirt_connect_set_keep_alive(value connv,
   CAMLreturn(Val_unit);
 }
 
-
 CAMLprim value
 ocaml_libvirt_domain_get_id (value domv)
 {
@@ -560,6 +559,122 @@ ocaml_libvirt_domain_get_cpu_stats (value domv)
   CAMLreturn (cpustats);
 }
 
+value
+ocaml_libvirt_domain_get_all_domain_stats (value connv,
+                                           value statsv, value flagsv)
+{
+  CAMLparam3 (connv, statsv, flagsv);
+  CAMLlocal5 (rv, dsv, tpv, v, v1);
+  CAMLlocal1 (v2);
+  virConnectPtr conn = Connect_val (connv);
+  virDomainStatsRecordPtr *rstats;
+  unsigned int stats = 0, flags = 0;
+  int i, j, r;
+
+  /* Get stats and flags. */
+  for (; statsv != Val_int (0); statsv = Field (statsv, 1)) {
+    v = Field (statsv, 0);
+    if (v == Val_int (0))
+      stats |= VIR_DOMAIN_STATS_STATE;
+    else if (v == Val_int (1))
+      stats |= VIR_DOMAIN_STATS_CPU_TOTAL;
+    else if (v == Val_int (2))
+      stats |= VIR_DOMAIN_STATS_BALLOON;
+    else if (v == Val_int (3))
+      stats |= VIR_DOMAIN_STATS_VCPU;
+    else if (v == Val_int (4))
+      stats |= VIR_DOMAIN_STATS_INTERFACE;
+    else if (v == Val_int (5))
+      stats |= VIR_DOMAIN_STATS_BLOCK;
+    else if (v == Val_int (6))
+      stats |= VIR_DOMAIN_STATS_PERF;
+  }
+  for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1)) {
+    v = Field (flagsv, 0);
+    if (v == Val_int (0))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE;
+    else if (v == Val_int (1))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE;
+    else if (v == Val_int (2))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER;
+    else if (v == Val_int (3))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED;
+    else if (v == Val_int (4))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT;
+    else if (v == Val_int (5))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING;
+    else if (v == Val_int (6))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF;
+    else if (v == Val_int (7))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT;
+    else if (v == Val_int (8))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING;
+    else if (v == Val_int (9))
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS;
+  }
+
+  NONBLOCKING (r = virConnectGetAllDomainStats (conn, stats, &rstats, flags));
+  CHECK_ERROR (r == -1, "virConnectGetAllDomainStats");
+
+  rv = caml_alloc (r, 0);       /* domain_stats_record array. */
+  for (i = 0; i < r; ++i) {
+    dsv = caml_alloc (2, 0);    /* domain_stats_record */
+    virDomainRef (rstats[i]->dom);
+    Store_field (dsv, 0, Val_domain (rstats[i]->dom, connv));
+
+    tpv = caml_alloc (rstats[i]->nparams, 0); /* typed_param array */
+    for (j = 0; j < rstats[i]->nparams; ++j) {
+      v2 = caml_alloc (2, 0);   /* typed_param: field name, value */
+      Store_field (v2, 0, caml_copy_string (rstats[i]->params[j].field));
+
+      switch (rstats[i]->params[j].type) {
+      case VIR_TYPED_PARAM_INT:
+        v1 = caml_alloc (1, 0);
+        v = caml_copy_int32 (rstats[i]->params[j].value.i);
+        break;
+      case VIR_TYPED_PARAM_UINT:
+        v1 = caml_alloc (1, 1);
+        v = caml_copy_int32 (rstats[i]->params[j].value.ui);
+        break;
+      case VIR_TYPED_PARAM_LLONG:
+        v1 = caml_alloc (1, 2);
+        v = caml_copy_int64 (rstats[i]->params[j].value.l);
+        break;
+      case VIR_TYPED_PARAM_ULLONG:
+        v1 = caml_alloc (1, 3);
+        v = caml_copy_int64 (rstats[i]->params[j].value.ul);
+        break;
+      case VIR_TYPED_PARAM_DOUBLE:
+        v1 = caml_alloc (1, 4);
+        v = caml_copy_double (rstats[i]->params[j].value.d);
+        break;
+      case VIR_TYPED_PARAM_BOOLEAN:
+        v1 = caml_alloc (1, 5);
+        v = Val_bool (rstats[i]->params[j].value.b);
+        break;
+      case VIR_TYPED_PARAM_STRING:
+        v1 = caml_alloc (1, 6);
+        v = caml_copy_string (rstats[i]->params[j].value.s);
+        break;
+      default:
+        virDomainStatsRecordListFree (rstats);
+        caml_failwith ("virConnectGetAllDomainStats: "
+                       "unknown parameter type returned");
+      }
+      Store_field (v1, 0, v);
+
+      Store_field (v2, 1, v1);
+      Store_field (tpv, j, v2);
+    }
+
+    Store_field (dsv, 1, tpv);
+    Store_field (rv, i, dsv);
+  }
+
+  virDomainStatsRecordListFree (rstats);
+  CAMLreturn (rv);
+}
+
 CAMLprim value
 ocaml_libvirt_domain_migrate_native (value domv, value dconnv, value flagsv, value optdnamev, value opturiv, value optbandwidthv, value unitv)
 {
-- 
2.9.3

diff --git a/testing/ocaml-libvirt/0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch b/testing/ocaml-libvirt/0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch
new file mode 100644
index 0000000000..a4baded24a
--- /dev/null
+++ b/testing/ocaml-libvirt/0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch
@@ -0,0 +1,42 @@
From 2bb6200934090f34f81d1badb9a55f5a86a7fb32 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Mar 2017 13:11:09 +0100
Subject: [PATCH 4/5] examples: Print more stats in the get_all_domain_stats.ml
 example.

Updates commit 380f1e05b244ae4750ca5101b5b5a182dcd0d1fd.
---
 examples/get_all_domain_stats.ml | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/examples/get_all_domain_stats.ml b/examples/get_all_domain_stats.ml
index 4375639..cc86da6 100644
--- a/examples/get_all_domain_stats.ml
+++ b/examples/get_all_domain_stats.ml
@@ -40,13 +40,20 @@ let () =
 
   let conn = C.connect_readonly () in
 
-  let what_stats = [D.StatsCpuTotal; D.StatsInterface; D.StatsBlock] in
-  let flags = [D.GetAllDomainsStatsActive; D.GetAllDomainsStatsInactive] in
+  let what = [
+    D.StatsState;
+    D.StatsCpuTotal;
+    D.StatsBalloon;
+    D.StatsVcpu;
+    D.StatsInterface;
+    D.StatsBlock;
+  ] in
+  let who = [] in (* empty list means returns all domains *)
 
   let quit = ref false in
 
   while not !quit do
-    let stats = D.get_all_domain_stats conn what_stats flags in
+    let stats = D.get_all_domain_stats conn what who in
 
     if stats <> [||] then print_stats stats
     else (
-- 
2.9.3

diff --git a/testing/ocaml-libvirt/0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch b/testing/ocaml-libvirt/0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch
new file mode 100644
index 0000000000..955a4ca71b
--- /dev/null
+++ b/testing/ocaml-libvirt/0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch
@@ -0,0 +1,127 @@
From 3169af3337938e18bf9ecc6ce936d644e14ff3de Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 28 Mar 2017 13:52:51 +0100
Subject: [PATCH 5/5] Change binding of virConnectGetAllDomainStats to return
 dom UUID.

The virDomainPtr object returned by this binding isn't a reliable
virDomainPtr object.  The only thing we can safely do with it is to
get its UUID.  Modify the API correspondingly.

Updates commit 380f1e05b244ae4750ca5101b5b5a182dcd0d1fd.
---
 examples/get_all_domain_stats.ml |  7 ++++---
 libvirt/libvirt.ml               |  6 +++---
 libvirt/libvirt.mli              |  6 +++---
 libvirt/libvirt_c_oneoffs.c      | 13 +++++++++++--
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/examples/get_all_domain_stats.ml b/examples/get_all_domain_stats.ml
index cc86da6..be91f77 100644
--- a/examples/get_all_domain_stats.ml
+++ b/examples/get_all_domain_stats.ml
@@ -8,10 +8,11 @@ open Printf
 module C = Libvirt.Connect
 module D = Libvirt.Domain
 
-let print_stats stats =
+let print_stats conn stats =
   try
     Array.iter (
-      fun { D.dom = dom; D.params = params } ->
+      fun { D.dom_uuid = uuid; D.params = params } ->
+        let dom = D.lookup_by_uuid conn uuid in
         printf "domain %s:\n" (D.get_name dom);
         Array.iteri (
           fun i (field, value) ->
@@ -55,7 +56,7 @@ let () =
   while not !quit do
     let stats = D.get_all_domain_stats conn what who in
 
-    if stats <> [||] then print_stats stats
+    if stats <> [||] then print_stats conn stats
     else (
       printf "no guests found\n";
       quit := true
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
index ce1878a..d03a127 100644
--- a/libvirt/libvirt.ml
+++ b/libvirt/libvirt.ml
@@ -408,8 +408,8 @@ struct
     | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
     | StatsInterface | StatsBlock | StatsPerf
 
-  type 'a domain_stats_record = {
-    dom : 'a t;
+  type domain_stats_record = {
+    dom_uuid : uuid;
     params : typed_param array;
   }
 
@@ -467,7 +467,7 @@ struct
   external block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_block_peek_bytecode" "ocaml_libvirt_domain_block_peek_native"
   external memory_peek : [>`W] t -> memory_flag list -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
 
-  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
+  external get_all_domain_stats : [>`R] Connect.t -> stats_type list -> get_all_domain_stats_flag list -> domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
 
   external const : [>`R] t -> ro t = "%identity"
 
diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli
index d1b5992..dc0033b 100644
--- a/libvirt/libvirt.mli
+++ b/libvirt/libvirt.mli
@@ -494,8 +494,8 @@ sig
     | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
     | StatsInterface | StatsBlock | StatsPerf
 
-  type 'a domain_stats_record = {
-    dom : 'a t;
+  type domain_stats_record = {
+    dom_uuid : uuid;
     params : typed_param array;
   }
 
@@ -636,7 +636,7 @@ sig
 
 	See also {!max_peek}. *)
 
-  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
+  external get_all_domain_stats : [>`R] Connect.t -> stats_type list -> get_all_domain_stats_flag list -> domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
     (** [get_all_domain_stats conn stats flags] allows you to read
         all stats across multiple/all domains in a single call.
 
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 17412f5..958ba69 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -570,6 +570,7 @@ ocaml_libvirt_domain_get_all_domain_stats (value connv,
   virDomainStatsRecordPtr *rstats;
   unsigned int stats = 0, flags = 0;
   int i, j, r;
+  unsigned char uuid[VIR_UUID_BUFLEN];
 
   /* Get stats and flags. */
   for (; statsv != Val_int (0); statsv = Field (statsv, 1)) {
@@ -619,8 +620,16 @@ ocaml_libvirt_domain_get_all_domain_stats (value connv,
   rv = caml_alloc (r, 0);       /* domain_stats_record array. */
   for (i = 0; i < r; ++i) {
     dsv = caml_alloc (2, 0);    /* domain_stats_record */
-    virDomainRef (rstats[i]->dom);
-    Store_field (dsv, 0, Val_domain (rstats[i]->dom, connv));
+
+    /* Libvirt returns something superficially resembling a
+     * virDomainPtr, but it's not a real virDomainPtr object
+     * (eg. dom->id == -1, and its refcount is wrong).  The only thing
+     * we can safely get from it is the UUID.
+     */
+    v = caml_alloc_string (VIR_UUID_BUFLEN);
+    virDomainGetUUID (rstats[i]->dom, uuid);
+    memcpy (String_val (v), uuid, VIR_UUID_BUFLEN);
+    Store_field (dsv, 0, v);
 
     tpv = caml_alloc (rstats[i]->nparams, 0); /* typed_param array */
     for (j = 0; j < rstats[i]->nparams; ++j) {
-- 
2.9.3

diff --git a/testing/ocaml-libvirt/APKBUILD b/testing/ocaml-libvirt/APKBUILD
new file mode 100644
index 0000000000..b0bd940dc9
--- /dev/null
+++ b/testing/ocaml-libvirt/APKBUILD
@@ -0,0 +1,58 @@
# Contributor: Fernando Casas Schossow <casasfernando@outlook.com>
# Maintainer: Fernando Casas Schossow <casasfernando@outlook.com>
pkgname=ocaml-libvirt
pkgver=0.6.1.4
pkgrel=0
pkgdesc="OCaml binding for libvirt"
url="http://libvirt.org/ocaml/"
arch="all"
license="LGPL-2.1-or-later-WITH-linking-exception"
makedepends="ocaml ocaml-ocamldoc ocaml-findlib-dev libvirt-dev perl gawk"
subpackages="$pkgname-dev $pkgname-doc"
source="https://libvirt.org/sources/ocaml/$pkgname-$pkgver.tar.gz
	0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch
	0001-Add-a-binding-for-virDomainCreateXML.patch
	0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch
	0002-Don-t-bother-checking-return-from-virInitialize.patch
	0001-Remove-unused-not_supported-function.patch
	0001-Use-g-warn-error.patch
	0002-Update-dependencies.patch
	0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch
	0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch
	0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch"
builddir="$srcdir/$pkgname-$pkgver"
options="!check" # there is no test suite/unit tests

build() {
	cd "$builddir"
	export OCAMLPARAM="safe-string=0,_"
	./configure --prefix=/usr
	make -C libvirt all
	make opt
}

check() {
	cd "$builddir"
}

package() {
	cd "$builddir"
	export DESTDIR="$pkgdir"
	export OCAMLFIND_DESTDIR="$DESTDIR/usr/lib/ocaml"
	mkdir -p "$OCAMLFIND_DESTDIR" "$OCAMLFIND_DESTDIR/stublibs"
	make install-opt
	install -D -m644 COPYING "$pkgdir/usr/share/licenses/$pkgname/COPYING"
	install -D -m644 COPYING.LIB "$pkgdir/usr/share/licenses/$pkgname/COPYING.LIB"
}

sha512sums="ed081a9b6f1388935e6a2ba0400e15881b3abb81a1079ab7fd88e72392ad29a0fd61550d3d7dc00682f283bc181d298af6519d19c3d15cf077988a3d6281d204  ocaml-libvirt-0.6.1.4.tar.gz
ca1c6503a121ae392c46a37e4b260041a12b692afb7f2da39396f490020fe11b2284ff6fe110eac6fabd01296adf2aa030f598e7349a0984323f7cd1c9fa67b0  0001-Use-C99-standard-int64_t-instead-of-OCaml-defined-an.patch
6404b398da1b41cd1fef41ce597a3d2b1dee44b636a403a9b730e9cec455c87b4bd4fa35eea869a12698623d4d9d667f5588032bac4938d4114f606fa499a1e0  0001-Add-a-binding-for-virDomainCreateXML.patch
e59b4127c2244ef6465090ccf6965f8ca4431e543bd4b8772527b0080af30da9834655fce195b61e860676f9f4747d2d22caf38dc0c2ecd102c4933f0a5da668  0001-Suppress-errors-to-stderr-and-use-thread-local-virEr.patch
7106aa55357b54409ca982ac60ff1243f4210a12fc3db7e6d355a5f317b947abe11d283ffc1c86193e93e6e30bd037f8883079a6dc83da33091adc449a31ddcd  0002-Don-t-bother-checking-return-from-virInitialize.patch
bbc97d03031ef187230607de4830a3b250b8283d52ec0a60a220d165b4af9fe0deeacf43b00c056b4e090d6cf8f6aae8eb26c72e38cfca95df9e85ce0b72fd40  0001-Remove-unused-not_supported-function.patch
830d93d7cd1dec1fcf3c0f762c61d056d62589972c26904b3711f9739745ab0125b117aff873abd3ff852c8ad03b3e779891d1420c3f21008915b4eb69d977bf  0001-Use-g-warn-error.patch
f1dd3862b6c3a5ee04a2d54a885bc0baa053de60cde4ceeb9b70c6de9a8b4bfcac77429bf64400973a2d867bab542ca728438b30f07ac756cd362db454d684c0  0002-Update-dependencies.patch
2b9ce951486ada9d700c4560e0d5c069d2b58c70d71ac70ee95900246a53ad6c5b2557fe82fc45b3f0fcdf7a966c2e1f442cc391758b0c9c6f7e755206e5e2c7  0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch
2a2f48cd744d5b697ffded415993aa21aea5b3335abb6dd1d2ae9efeb443ead362b9b6988764a0405e96f054d949b2927c0a7316dcb0e41e02b19379a40b8471  0004-examples-Print-more-stats-in-the-get_all_domain_stat.patch
abfcac22d22be5e2b552f2443244d62663d055d3eb9fd9ee9e82bcf21667d1a868cecc2bc5eac25097e9faca2ae20bd4ad6c0bb81eb072fa581ffbcd7ec3779b  0005-Change-binding-of-virConnectGetAllDomainStats-to-ret.patch"
-- 
2.20.1



---
Unsubscribe:  alpine-aports+unsubscribe@lists.alpinelinux.org
Help:         alpine-aports+help@lists.alpinelinux.org
---
Reply to thread Export thread (mbox)