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.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * Please see the file ../COPYING.LIB.
18 /* Please read libvirt/README file. */
21 Optstring_val (value strv)
23 if (strv == Val_int (0)) /* None */
25 else /* Some string */
26 return String_val (Field (strv, 0));
30 Val_opt (void *ptr, Val_ptr_t Val_ptr)
33 CAMLlocal2 (optv, ptrv);
35 if (ptr) { /* Some ptr */
36 optv = caml_alloc (1, 0);
38 Store_field (optv, 0, ptrv);
47 option_default (value option, value deflt)
49 if (option == Val_int (0)) /* "None" */
52 return Field (option, 0);
57 _raise_virterror (virConnectPtr conn, const char *fn)
64 errp = conn ? virConnGetLastError (conn) : virGetLastError ();
67 /* Fake a _virError structure. */
68 memset (&err, 0, sizeof err);
69 err.code = VIR_ERR_INTERNAL_ERROR;
70 err.domain = VIR_FROM_NONE;
71 err.level = VIR_ERR_ERROR;
72 err.message = (char *) fn;
76 rv = Val_virterror (errp);
77 caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
80 /* Suppresses a compiler warning. */
84 /* Raise an error if a function is not supported. */
86 not_supported (const char *fn)
91 fnv = caml_copy_string (fn);
92 caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
95 /* Suppresses a compiler warning. */
99 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
100 * into values (longs because they are variants in OCaml).
102 * The enum values are part of the libvirt ABI so they cannot change,
103 * which means that we can convert these numbers directly into
104 * OCaml variants (which use the same ordering) very fast.
106 * The tricky part here is when we are linked to a newer version of
107 * libvirt than the one we were compiled against. If the newer libvirt
108 * generates an error code which we don't know about then we need
109 * to convert it into VIR_*_UNKNOWN (code).
112 #define MAX_VIR_CODE 50 /* VIR_ERR_NO_STORAGE_VOL */
113 #define MAX_VIR_DOMAIN 17 /* VIR_FROM_STORAGE */
114 #define MAX_VIR_LEVEL VIR_ERR_ERROR
117 Val_err_number (virErrorNumber code)
122 if (0 <= code && code <= MAX_VIR_CODE)
125 rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN (code) */
126 Store_field (rv, 0, Val_int (code));
133 Val_err_domain (virErrorDomain code)
138 if (0 <= code && code <= MAX_VIR_DOMAIN)
141 rv = caml_alloc (1, 0); /* VIR_FROM_UNKNOWN (code) */
142 Store_field (rv, 0, Val_int (code));
149 Val_err_level (virErrorLevel code)
154 if (0 <= code && code <= MAX_VIR_LEVEL)
157 rv = caml_alloc (1, 0); /* VIR_ERR_UNKNOWN_LEVEL (code) */
158 Store_field (rv, 0, Val_int (code));
164 /* Convert a virterror to a value. */
166 Val_virterror (virErrorPtr err)
169 CAMLlocal3 (rv, connv, optv);
171 rv = caml_alloc (9, 0);
172 Store_field (rv, 0, Val_err_number (err->code));
173 Store_field (rv, 1, Val_err_domain (err->domain));
175 Val_opt (err->message, (Val_ptr_t) caml_copy_string));
176 Store_field (rv, 3, Val_err_level (err->level));
179 Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
181 Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
183 Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
184 Store_field (rv, 7, caml_copy_int32 (err->int1));
185 Store_field (rv, 8, caml_copy_int32 (err->int2));
190 static void conn_finalize (value);
191 static void dom_finalize (value);
192 static void net_finalize (value);
193 #ifdef HAVE_VIRSTORAGEPOOLPTR
194 static void pol_finalize (value);
196 #ifdef HAVE_VIRSTORAGEVOLPTR
197 static void vol_finalize (value);
199 #ifdef HAVE_VIRJOBPTR
200 static void jb_finalize (value);
203 static struct custom_operations conn_custom_operations = {
204 "conn_custom_operations",
206 custom_compare_default,
208 custom_serialize_default,
209 custom_deserialize_default
212 static struct custom_operations dom_custom_operations = {
213 "dom_custom_operations",
215 custom_compare_default,
217 custom_serialize_default,
218 custom_deserialize_default
222 static struct custom_operations net_custom_operations = {
223 "net_custom_operations",
225 custom_compare_default,
227 custom_serialize_default,
228 custom_deserialize_default
231 #ifdef HAVE_VIRSTORAGEPOOLPTR
232 static struct custom_operations pol_custom_operations = {
233 "pol_custom_operations",
235 custom_compare_default,
237 custom_serialize_default,
238 custom_deserialize_default
242 #ifdef HAVE_VIRSTORAGEVOLPTR
243 static struct custom_operations vol_custom_operations = {
244 "vol_custom_operations",
246 custom_compare_default,
248 custom_serialize_default,
249 custom_deserialize_default
253 #ifdef HAVE_VIRJOBPTR
254 static struct custom_operations jb_custom_operations = {
255 "jb_custom_operations",
257 custom_compare_default,
259 custom_serialize_default,
260 custom_deserialize_default
265 Val_connect (virConnectPtr conn)
269 rv = caml_alloc_custom (&conn_custom_operations,
270 sizeof (virConnectPtr), 0, 1);
271 Connect_val (rv) = conn;
276 Val_dom (virDomainPtr dom)
280 rv = caml_alloc_custom (&dom_custom_operations,
281 sizeof (virDomainPtr), 0, 1);
287 Val_net (virNetworkPtr net)
291 rv = caml_alloc_custom (&net_custom_operations,
292 sizeof (virNetworkPtr), 0, 1);
297 #ifdef HAVE_VIRSTORAGEPOOLPTR
299 Val_pol (virStoragePoolPtr pol)
303 rv = caml_alloc_custom (&pol_custom_operations,
304 sizeof (virStoragePoolPtr), 0, 1);
310 #ifdef HAVE_VIRSTORAGEVOLPTR
312 Val_vol (virStorageVolPtr vol)
316 rv = caml_alloc_custom (&vol_custom_operations,
317 sizeof (virStorageVolPtr), 0, 1);
323 #ifdef HAVE_VIRJOBPTR
325 Val_jb (virJobPtr jb)
329 rv = caml_alloc_custom (&jb_custom_operations,
330 sizeof (virJobPtr), 0, 1);
336 /* This wraps up the (dom, conn) pair (Domain.t). */
338 Val_domain (virDomainPtr dom, value connv)
343 rv = caml_alloc_tuple (2);
345 Store_field (rv, 0, v);
346 Store_field (rv, 1, connv);
350 /* This wraps up the (net, conn) pair (Network.t). */
352 Val_network (virNetworkPtr net, value connv)
357 rv = caml_alloc_tuple (2);
359 Store_field (rv, 0, v);
360 Store_field (rv, 1, connv);
364 #ifdef HAVE_VIRSTORAGEPOOLPTR
365 /* This wraps up the (pol, conn) pair (Pool.t). */
367 Val_pool (virStoragePoolPtr pol, value connv)
372 rv = caml_alloc_tuple (2);
374 Store_field (rv, 0, v);
375 Store_field (rv, 1, connv);
380 #ifdef HAVE_VIRSTORAGEVOLPTR
381 /* This wraps up the (vol, conn) pair (Volume.t). */
383 Val_volume (virStorageVolPtr vol, value connv)
388 rv = caml_alloc_tuple (2);
390 Store_field (rv, 0, v);
391 Store_field (rv, 1, connv);
396 #ifdef HAVE_VIRJOBPTR
397 /* This wraps up the (jb, conn) pair (Job.t). */
399 Val_job (virJobPtr jb, value connv)
404 rv = caml_alloc_tuple (2);
406 Store_field (rv, 0, v);
407 Store_field (rv, 1, connv);
413 conn_finalize (value connv)
415 virConnectPtr conn = Connect_val (connv);
416 if (conn) (void) virConnectClose (conn);
420 dom_finalize (value domv)
422 virDomainPtr dom = Dom_val (domv);
423 if (dom) (void) virDomainFree (dom);
427 net_finalize (value netv)
429 virNetworkPtr net = Net_val (netv);
430 if (net) (void) virNetworkFree (net);
433 #ifdef HAVE_VIRSTORAGEPOOLPTR
435 pol_finalize (value polv)
437 virStoragePoolPtr pol = Pol_val (polv);
438 if (pol) (void) virStoragePoolFree (pol);
442 #ifdef HAVE_VIRSTORAGEVOLPTR
444 vol_finalize (value volv)
446 virStorageVolPtr vol = Vol_val (volv);
447 if (vol) (void) virStorageVolFree (vol);
451 #ifdef HAVE_VIRJOBPTR
453 jb_finalize (value jbv)
455 virJobPtr jb = Jb_val (jbv);
456 if (jb) (void) virJobFree (jb);