1 /* OCaml bindings for libvirt.
2 * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version,
9 * with the OCaml linking exception described in ../COPYING.LIB.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /* Please read libvirt/README file. */
24 Optstring_val (value strv)
26 if (strv == Val_int (0)) /* None */
28 else /* Some string */
29 return String_val (Field (strv, 0));
33 Val_opt (void *ptr, Val_ptr_t Val_ptr)
36 CAMLlocal2 (optv, ptrv);
38 if (ptr) { /* Some ptr */
39 optv = caml_alloc (1, 0);
41 Store_field (optv, 0, ptrv);
50 option_default (value option, value deflt)
52 if (option == Val_int (0)) /* "None" */
55 return Field (option, 0);
60 _raise_virterror (virConnectPtr conn, const char *fn)
67 errp = conn ? virConnGetLastError (conn) : virGetLastError ();
70 /* Fake a _virError structure. */
71 memset (&err, 0, sizeof err);
72 err.code = VIR_ERR_INTERNAL_ERROR;
73 err.domain = VIR_FROM_NONE;
74 err.level = VIR_ERR_ERROR;
75 err.message = (char *) fn;
79 rv = Val_virterror (errp);
80 caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
86 /* Raise an error if a function is not supported. */
88 not_supported (const char *fn)
93 fnv = caml_copy_string (fn);
94 caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
100 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
101 * into values (longs because they are variants in OCaml).
103 * The enum values are part of the libvirt ABI so they cannot change,
104 * which means that we can convert these numbers directly into
105 * OCaml variants (which use the same ordering) very fast.
107 * The tricky part here is when we are linked to a newer version of
108 * libvirt than the one we were compiled against. If the newer libvirt
109 * generates an error code which we don't know about then we need
110 * to convert it into VIR_*_UNKNOWN (code).
113 #define MAX_VIR_CODE 50 /* VIR_ERR_NO_STORAGE_VOL */
114 #define MAX_VIR_DOMAIN 17 /* VIR_FROM_STORAGE */
115 #define MAX_VIR_LEVEL VIR_ERR_ERROR
118 Val_err_number (virErrorNumber code)
123 if (0 <= code && code <= MAX_VIR_CODE)
126 rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN (code) */
127 Store_field (rv, 0, Val_int (code));
134 Val_err_domain (virErrorDomain code)
139 if (0 <= code && code <= MAX_VIR_DOMAIN)
142 rv = caml_alloc (1, 0); /* VIR_FROM_UNKNOWN (code) */
143 Store_field (rv, 0, Val_int (code));
150 Val_err_level (virErrorLevel code)
155 if (0 <= code && code <= MAX_VIR_LEVEL)
158 rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN_LEVEL (code) */
159 Store_field (rv, 0, Val_int (code));
165 /* Convert a virterror to a value. */
167 Val_virterror (virErrorPtr err)
170 CAMLlocal3 (rv, connv, optv);
172 rv = caml_alloc (9, 0);
173 Store_field (rv, 0, Val_err_number (err->code));
174 Store_field (rv, 1, Val_err_domain (err->domain));
176 Val_opt (err->message, (Val_ptr_t) caml_copy_string));
177 Store_field (rv, 3, Val_err_level (err->level));
180 Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
182 Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
184 Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
185 Store_field (rv, 7, caml_copy_int32 (err->int1));
186 Store_field (rv, 8, caml_copy_int32 (err->int2));
191 static void conn_finalize (value);
192 static void dom_finalize (value);
193 static void net_finalize (value);
194 #ifdef HAVE_VIRSTORAGEPOOLPTR
195 static void pol_finalize (value);
197 #ifdef HAVE_VIRSTORAGEVOLPTR
198 static void vol_finalize (value);
200 #ifdef HAVE_VIRJOBPTR
201 static void jb_finalize (value);
204 static struct custom_operations conn_custom_operations = {
205 "conn_custom_operations",
207 custom_compare_default,
209 custom_serialize_default,
210 custom_deserialize_default
213 static struct custom_operations dom_custom_operations = {
214 "dom_custom_operations",
216 custom_compare_default,
218 custom_serialize_default,
219 custom_deserialize_default
223 static struct custom_operations net_custom_operations = {
224 "net_custom_operations",
226 custom_compare_default,
228 custom_serialize_default,
229 custom_deserialize_default
232 #ifdef HAVE_VIRSTORAGEPOOLPTR
233 static struct custom_operations pol_custom_operations = {
234 "pol_custom_operations",
236 custom_compare_default,
238 custom_serialize_default,
239 custom_deserialize_default
243 #ifdef HAVE_VIRSTORAGEVOLPTR
244 static struct custom_operations vol_custom_operations = {
245 "vol_custom_operations",
247 custom_compare_default,
249 custom_serialize_default,
250 custom_deserialize_default
254 #ifdef HAVE_VIRJOBPTR
255 static struct custom_operations jb_custom_operations = {
256 "jb_custom_operations",
258 custom_compare_default,
260 custom_serialize_default,
261 custom_deserialize_default
266 Val_connect (virConnectPtr conn)
270 rv = caml_alloc_custom (&conn_custom_operations,
271 sizeof (virConnectPtr), 0, 1);
272 Connect_val (rv) = conn;
277 Val_dom (virDomainPtr dom)
281 rv = caml_alloc_custom (&dom_custom_operations,
282 sizeof (virDomainPtr), 0, 1);
288 Val_net (virNetworkPtr net)
292 rv = caml_alloc_custom (&net_custom_operations,
293 sizeof (virNetworkPtr), 0, 1);
298 #ifdef HAVE_VIRSTORAGEPOOLPTR
300 Val_pol (virStoragePoolPtr pol)
304 rv = caml_alloc_custom (&pol_custom_operations,
305 sizeof (virStoragePoolPtr), 0, 1);
311 #ifdef HAVE_VIRSTORAGEVOLPTR
313 Val_vol (virStorageVolPtr vol)
317 rv = caml_alloc_custom (&vol_custom_operations,
318 sizeof (virStorageVolPtr), 0, 1);
324 #ifdef HAVE_VIRJOBPTR
326 Val_jb (virJobPtr jb)
330 rv = caml_alloc_custom (&jb_custom_operations,
331 sizeof (virJobPtr), 0, 1);
337 /* This wraps up the (dom, conn) pair (Domain.t). */
339 Val_domain (virDomainPtr dom, value connv)
344 rv = caml_alloc_tuple (2);
346 Store_field (rv, 0, v);
347 Store_field (rv, 1, connv);
351 /* This wraps up the (net, conn) pair (Network.t). */
353 Val_network (virNetworkPtr net, value connv)
358 rv = caml_alloc_tuple (2);
360 Store_field (rv, 0, v);
361 Store_field (rv, 1, connv);
365 #ifdef HAVE_VIRSTORAGEPOOLPTR
366 /* This wraps up the (pol, conn) pair (Pool.t). */
368 Val_pool (virStoragePoolPtr pol, value connv)
373 rv = caml_alloc_tuple (2);
375 Store_field (rv, 0, v);
376 Store_field (rv, 1, connv);
381 #ifdef HAVE_VIRSTORAGEVOLPTR
382 /* This wraps up the (vol, conn) pair (Volume.t). */
384 Val_volume (virStorageVolPtr vol, value connv)
389 rv = caml_alloc_tuple (2);
391 Store_field (rv, 0, v);
392 Store_field (rv, 1, connv);
397 #ifdef HAVE_VIRJOBPTR
398 /* This wraps up the (jb, conn) pair (Job.t). */
400 Val_job (virJobPtr jb, value connv)
405 rv = caml_alloc_tuple (2);
407 Store_field (rv, 0, v);
408 Store_field (rv, 1, connv);
414 conn_finalize (value connv)
416 virConnectPtr conn = Connect_val (connv);
417 if (conn) (void) virConnectClose (conn);
421 dom_finalize (value domv)
423 virDomainPtr dom = Dom_val (domv);
424 if (dom) (void) virDomainFree (dom);
428 net_finalize (value netv)
430 virNetworkPtr net = Net_val (netv);
431 if (net) (void) virNetworkFree (net);
434 #ifdef HAVE_VIRSTORAGEPOOLPTR
436 pol_finalize (value polv)
438 virStoragePoolPtr pol = Pol_val (polv);
439 if (pol) (void) virStoragePoolFree (pol);
443 #ifdef HAVE_VIRSTORAGEVOLPTR
445 vol_finalize (value volv)
447 virStorageVolPtr vol = Vol_val (volv);
448 if (vol) (void) virStorageVolFree (vol);
452 #ifdef HAVE_VIRJOBPTR
454 jb_finalize (value jbv)
456 virJobPtr jb = Jb_val (jbv);
457 if (jb) (void) virJobFree (jb);