summaryrefslogtreecommitdiffstats
path: root/libvirt/libvirt_c_epilogue.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvirt/libvirt_c_epilogue.c')
-rw-r--r--libvirt/libvirt_c_epilogue.c496
1 files changed, 496 insertions, 0 deletions
diff --git a/libvirt/libvirt_c_epilogue.c b/libvirt/libvirt_c_epilogue.c
new file mode 100644
index 0000000..fff76f9
--- /dev/null
+++ b/libvirt/libvirt_c_epilogue.c
@@ -0,0 +1,496 @@
+/* OCaml bindings for libvirt.
+ * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+ * http://libvirt.org/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Please read libvirt/README file. */
+
+static char *
+Optstring_val (value strv)
+{
+ if (strv == Val_int (0)) /* None */
+ return NULL;
+ else /* Some string */
+ return String_val (Field (strv, 0));
+}
+
+static value
+Val_opt (void *ptr, Val_ptr_t Val_ptr)
+{
+ CAMLparam0 ();
+ CAMLlocal2 (optv, ptrv);
+
+ if (ptr) { /* Some ptr */
+ optv = caml_alloc (1, 0);
+ ptrv = Val_ptr (ptr);
+ Store_field (optv, 0, ptrv);
+ } else /* None */
+ optv = Val_int (0);
+
+ CAMLreturn (optv);
+}
+
+#if 0
+static value
+option_default (value option, value deflt)
+{
+ if (option == Val_int (0)) /* "None" */
+ return deflt;
+ else /* "Some 'a" */
+ return Field (option, 0);
+}
+#endif
+
+static void
+_raise_virterror (virConnectPtr conn, const char *fn)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ virErrorPtr errp;
+ struct _virError err;
+
+ errp = conn ? virConnGetLastError (conn) : virGetLastError ();
+
+ if (!errp) {
+ /* Fake a _virError structure. */
+ memset (&err, 0, sizeof err);
+ err.code = VIR_ERR_INTERNAL_ERROR;
+ err.domain = VIR_FROM_NONE;
+ err.level = VIR_ERR_ERROR;
+ err.message = (char *) fn;
+ errp = &err;
+ }
+
+ rv = Val_virterror (errp);
+ caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
+
+ /*NOTREACHED*/
+ /* Suppresses a compiler warning. */
+ (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).
+ *
+ * The enum values are part of the libvirt ABI so they cannot change,
+ * which means that we can convert these numbers directly into
+ * OCaml variants (which use the same ordering) very fast.
+ *
+ * The tricky part here is when we are linked to a newer version of
+ * libvirt than the one we were compiled against. If the newer libvirt
+ * generates an error code which we don't know about then we need
+ * to convert it into VIR_*_UNKNOWN (code).
+ */
+
+#define MAX_VIR_CODE 44 /* VIR_ERR_INVALID_MAC */
+#define MAX_VIR_DOMAIN 16 /* VIR_FROM_STATS_LINUX */
+#define MAX_VIR_LEVEL VIR_ERR_ERROR
+
+static inline value
+Val_err_number (virErrorNumber code)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+
+ if (0 <= code && code <= MAX_VIR_CODE)
+ rv = Val_int (code);
+ else {
+ rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN (code) */
+ Store_field (rv, 0, Val_int (code));
+ }
+
+ CAMLreturn (rv);
+}
+
+static inline value
+Val_err_domain (virErrorDomain code)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+
+ if (0 <= code && code <= MAX_VIR_DOMAIN)
+ rv = Val_int (code);
+ else {
+ rv = caml_alloc (1, 0); /* VIR_FROM_UNKNOWN (code) */
+ Store_field (rv, 0, Val_int (code));
+ }
+
+ CAMLreturn (rv);
+}
+
+static inline value
+Val_err_level (virErrorLevel code)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+
+ if (0 <= code && code <= MAX_VIR_LEVEL)
+ rv = Val_int (code);
+ else {
+ rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN_LEVEL (code) */
+ Store_field (rv, 0, Val_int (code));
+ }
+
+ CAMLreturn (rv);
+}
+
+/* Convert a virterror to a value. */
+static value
+Val_virterror (virErrorPtr err)
+{
+ CAMLparam0 ();
+ CAMLlocal3 (rv, connv, optv);
+
+ rv = caml_alloc (12, 0);
+ Store_field (rv, 0, Val_err_number (err->code));
+ Store_field (rv, 1, Val_err_domain (err->domain));
+ Store_field (rv, 2,
+ Val_opt (err->message, (Val_ptr_t) caml_copy_string));
+ Store_field (rv, 3, Val_err_level (err->level));
+
+ /* conn, dom and net fields, all optional */
+ if (err->conn) {
+ connv = Val_connect_no_finalize (err->conn);
+ optv = caml_alloc (1, 0);
+ Store_field (optv, 0, connv);
+ Store_field (rv, 4, optv); /* Some conn */
+
+ if (err->dom) {
+ optv = caml_alloc (1, 0);
+ Store_field (optv, 0, Val_domain_no_finalize (err->dom, connv));
+ Store_field (rv, 5, optv); /* Some (dom, conn) */
+ }
+ else
+ Store_field (rv, 5, Val_int (0)); /* None */
+ if (err->net) {
+ optv = caml_alloc (1, 0);
+ Store_field (optv, 0, Val_network_no_finalize (err->net, connv));
+ Store_field (rv, 11, optv); /* Some (net, conn) */
+ } else
+ Store_field (rv, 11, Val_int (0)); /* None */
+ } else {
+ Store_field (rv, 4, Val_int (0)); /* None */
+ Store_field (rv, 5, Val_int (0)); /* None */
+ Store_field (rv, 11, Val_int (0)); /* None */
+ }
+
+ Store_field (rv, 6,
+ Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
+ Store_field (rv, 7,
+ Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
+ Store_field (rv, 8,
+ Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
+ Store_field (rv, 9, caml_copy_int32 (err->int1));
+ Store_field (rv, 10, caml_copy_int32 (err->int2));
+
+ CAMLreturn (rv);
+}
+
+static void conn_finalize (value);
+static void dom_finalize (value);
+static void net_finalize (value);
+#ifdef HAVE_VIRSTORAGEPOOLPTR
+static void pol_finalize (value);
+#endif
+#ifdef HAVE_VIRSTORAGEVOLPTR
+static void vol_finalize (value);
+#endif
+
+static struct custom_operations conn_custom_operations = {
+ "conn_custom_operations",
+ conn_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default
+};
+
+static struct custom_operations dom_custom_operations = {
+ "dom_custom_operations",
+ dom_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default
+
+};
+
+static struct custom_operations net_custom_operations = {
+ "net_custom_operations",
+ net_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default
+};
+
+#ifdef HAVE_VIRSTORAGEPOOLPTR
+static struct custom_operations pol_custom_operations = {
+ "pol_custom_operations",
+ pol_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default
+};
+#endif
+
+#ifdef HAVE_VIRSTORAGEVOLPTR
+static struct custom_operations vol_custom_operations = {
+ "vol_custom_operations",
+ vol_finalize,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default
+};
+#endif
+
+static value
+Val_connect (virConnectPtr conn)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc_custom (&conn_custom_operations,
+ sizeof (virConnectPtr), 0, 1);
+ Connect_val (rv) = conn;
+ CAMLreturn (rv);
+}
+
+static value
+Val_dom (virDomainPtr dom)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc_custom (&dom_custom_operations,
+ sizeof (virDomainPtr), 0, 1);
+ Dom_val (rv) = dom;
+ CAMLreturn (rv);
+}
+
+static value
+Val_net (virNetworkPtr net)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc_custom (&net_custom_operations,
+ sizeof (virNetworkPtr), 0, 1);
+ Net_val (rv) = net;
+ CAMLreturn (rv);
+}
+
+#ifdef HAVE_VIRSTORAGEPOOLPTR
+static value
+Val_pol (virStoragePoolPtr pol)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc_custom (&pol_custom_operations,
+ sizeof (virStoragePoolPtr), 0, 1);
+ Pol_val (rv) = pol;
+ CAMLreturn (rv);
+}
+#endif
+
+#ifdef HAVE_VIRSTORAGEVOLPTR
+static value
+Val_vol (virStorageVolPtr net)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc_custom (&vol_custom_operations,
+ sizeof (virStorageVolPtr), 0, 1);
+ Vol_val (rv) = vol;
+ CAMLreturn (rv);
+}
+#endif
+
+/* No-finalize versions of Val_connect, Val_dom, Val_net ONLY for use
+ * by virterror wrappers.
+ */
+static value
+Val_connect_no_finalize (virConnectPtr conn)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc (1, Abstract_tag);
+ Store_field (rv, 0, (value) conn);
+ CAMLreturn (rv);
+}
+
+static value
+Val_dom_no_finalize (virDomainPtr dom)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc (1, Abstract_tag);
+ Store_field (rv, 0, (value) dom);
+ CAMLreturn (rv);
+}
+
+static value
+Val_net_no_finalize (virNetworkPtr net)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ rv = caml_alloc (1, Abstract_tag);
+ Store_field (rv, 0, (value) net);
+ CAMLreturn (rv);
+}
+
+/* This wraps up the (dom, conn) pair (Domain.t). */
+static value
+Val_domain (virDomainPtr dom, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_dom (dom);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+
+/* This wraps up the (net, conn) pair (Network.t). */
+static value
+Val_network (virNetworkPtr net, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_net (net);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+
+#ifdef HAVE_VIRSTORAGEPOOLPTR
+/* This wraps up the (pol, conn) pair (Pool.t). */
+static value
+Val_pool (virStoragePoolPtr pol, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_pol (pol);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+#endif
+
+#ifdef HAVE_VIRSTORAGEVOLPTR
+/* This wraps up the (vol, conn) pair (Volume.t). */
+static value
+Val_volume (virStorageVolPtr vol, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_vol (vol);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+#endif
+
+/* No-finalize versions of Val_domain, Val_network ONLY for use by
+ * virterror wrappers.
+ */
+static value
+Val_domain_no_finalize (virDomainPtr dom, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_dom_no_finalize (dom);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+
+static value
+Val_network_no_finalize (virNetworkPtr net, value connv)
+{
+ CAMLparam1 (connv);
+ CAMLlocal2 (rv, v);
+
+ rv = caml_alloc_tuple (2);
+ v = Val_net_no_finalize (net);
+ Store_field (rv, 0, v);
+ Store_field (rv, 1, connv);
+ CAMLreturn (rv);
+}
+
+static void
+conn_finalize (value connv)
+{
+ virConnectPtr conn = Connect_val (connv);
+ if (conn) (void) virConnectClose (conn);
+}
+
+static void
+dom_finalize (value domv)
+{
+ virDomainPtr dom = Dom_val (domv);
+ if (dom) (void) virDomainFree (dom);
+}
+
+static void
+net_finalize (value netv)
+{
+ virNetworkPtr net = Net_val (netv);
+ if (net) (void) virNetworkFree (net);
+}
+
+#ifdef HAVE_VIRSTORAGEPOOLPTR
+static void
+pol_finalize (value polv)
+{
+ virStoragePoolPtr pol = Pol_val (polv);
+ if (pol) (void) virStoragePoolFree (pol);
+}
+#endif
+
+#ifdef HAVE_VIRSTORAGEVOLPTR
+static void
+vol_finalize (value volv)
+{
+ virStorageVolPtr vol = Vol_val (volv);
+ if (vol) (void) virStorageVolFree (vol);
+}
+#endif