Remove jobs API.
[ocaml-libvirt.git] / libvirt / libvirt_c_epilogue.c
1 /* OCaml bindings for libvirt.
2  * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
3  * http://libvirt.org/
4  *
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.
10  *
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.
15  *
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
19  */
20
21 /* Please read libvirt/README file. */
22
23 static char *
24 Optstring_val (value strv)
25 {
26   if (strv == Val_int (0))      /* None */
27     return NULL;
28   else                          /* Some string */
29     return String_val (Field (strv, 0));
30 }
31
32 static value
33 Val_opt (void *ptr, Val_ptr_t Val_ptr)
34 {
35   CAMLparam0 ();
36   CAMLlocal2 (optv, ptrv);
37
38   if (ptr) {                    /* Some ptr */
39     optv = caml_alloc (1, 0);
40     ptrv = Val_ptr (ptr);
41     Store_field (optv, 0, ptrv);
42   } else                        /* None */
43     optv = Val_int (0);
44
45   CAMLreturn (optv);
46 }
47
48 #if 0
49 static value
50 option_default (value option, value deflt)
51 {
52   if (option == Val_int (0))    /* "None" */
53     return deflt;
54   else                          /* "Some 'a" */
55     return Field (option, 0);
56 }
57 #endif
58
59 static void
60 _raise_virterror (virConnectPtr conn, const char *fn)
61 {
62   CAMLparam0 ();
63   CAMLlocal1 (rv);
64   virErrorPtr errp;
65   struct _virError err;
66
67   errp = conn ? virConnGetLastError (conn) : virGetLastError ();
68
69   if (!errp) {
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;
76     errp = &err;
77   }
78
79   rv = Val_virterror (errp);
80   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
81
82   /*NOTREACHED*/
83   /* Suppresses a compiler warning. */
84   (void) caml__frame;
85 }
86
87 /* Raise an error if a function is not supported. */
88 static void
89 not_supported (const char *fn)
90 {
91   CAMLparam0 ();
92   CAMLlocal1 (fnv);
93
94   fnv = caml_copy_string (fn);
95   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
96
97   /*NOTREACHED*/
98   /* Suppresses a compiler warning. */
99   (void) caml__frame;
100 }
101
102 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
103  * into values (longs because they are variants in OCaml).
104  *
105  * The enum values are part of the libvirt ABI so they cannot change,
106  * which means that we can convert these numbers directly into
107  * OCaml variants (which use the same ordering) very fast.
108  *
109  * The tricky part here is when we are linked to a newer version of
110  * libvirt than the one we were compiled against.  If the newer libvirt
111  * generates an error code which we don't know about then we need
112  * to convert it into VIR_*_UNKNOWN (code).
113  */
114
115 #define MAX_VIR_CODE 50 /* VIR_ERR_NO_STORAGE_VOL */
116 #define MAX_VIR_DOMAIN 17 /* VIR_FROM_STORAGE */
117 #define MAX_VIR_LEVEL VIR_ERR_ERROR
118
119 static inline value
120 Val_err_number (virErrorNumber code)
121 {
122   CAMLparam0 ();
123   CAMLlocal1 (rv);
124
125   if (0 <= code && code <= MAX_VIR_CODE)
126     rv = Val_int (code);
127   else {
128     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN (code) */
129     Store_field (rv, 0, Val_int (code));
130   }
131
132   CAMLreturn (rv);
133 }
134
135 static inline value
136 Val_err_domain (virErrorDomain code)
137 {
138   CAMLparam0 ();
139   CAMLlocal1 (rv);
140
141   if (0 <= code && code <= MAX_VIR_DOMAIN)
142     rv = Val_int (code);
143   else {
144     rv = caml_alloc (1, 0);     /* VIR_FROM_UNKNOWN (code) */
145     Store_field (rv, 0, Val_int (code));
146   }
147
148   CAMLreturn (rv);
149 }
150
151 static inline value
152 Val_err_level (virErrorLevel code)
153 {
154   CAMLparam0 ();
155   CAMLlocal1 (rv);
156
157   if (0 <= code && code <= MAX_VIR_LEVEL)
158     rv = Val_int (code);
159   else {
160     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN_LEVEL (code) */
161     Store_field (rv, 0, Val_int (code));
162   }
163
164   CAMLreturn (rv);
165 }
166
167 /* Convert a virterror to a value. */
168 static value
169 Val_virterror (virErrorPtr err)
170 {
171   CAMLparam0 ();
172   CAMLlocal3 (rv, connv, optv);
173
174   rv = caml_alloc (9, 0);
175   Store_field (rv, 0, Val_err_number (err->code));
176   Store_field (rv, 1, Val_err_domain (err->domain));
177   Store_field (rv, 2,
178                Val_opt (err->message, (Val_ptr_t) caml_copy_string));
179   Store_field (rv, 3, Val_err_level (err->level));
180
181   Store_field (rv, 4,
182                Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
183   Store_field (rv, 5,
184                Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
185   Store_field (rv, 6,
186                Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
187   Store_field (rv, 7, caml_copy_int32 (err->int1));
188   Store_field (rv, 8, caml_copy_int32 (err->int2));
189
190   CAMLreturn (rv);
191 }
192
193 static void conn_finalize (value);
194 static void dom_finalize (value);
195 static void net_finalize (value);
196 #ifdef HAVE_VIRSTORAGEPOOLPTR
197 static void pol_finalize (value);
198 #endif
199 #ifdef HAVE_VIRSTORAGEVOLPTR
200 static void vol_finalize (value);
201 #endif
202
203 static struct custom_operations conn_custom_operations = {
204   "conn_custom_operations",
205   conn_finalize,
206   custom_compare_default,
207   custom_hash_default,
208   custom_serialize_default,
209   custom_deserialize_default
210 };
211
212 static struct custom_operations dom_custom_operations = {
213   "dom_custom_operations",
214   dom_finalize,
215   custom_compare_default,
216   custom_hash_default,
217   custom_serialize_default,
218   custom_deserialize_default
219
220 };
221
222 static struct custom_operations net_custom_operations = {
223   "net_custom_operations",
224   net_finalize,
225   custom_compare_default,
226   custom_hash_default,
227   custom_serialize_default,
228   custom_deserialize_default
229 };
230
231 #ifdef HAVE_VIRSTORAGEPOOLPTR
232 static struct custom_operations pol_custom_operations = {
233   "pol_custom_operations",
234   pol_finalize,
235   custom_compare_default,
236   custom_hash_default,
237   custom_serialize_default,
238   custom_deserialize_default
239 };
240 #endif
241
242 #ifdef HAVE_VIRSTORAGEVOLPTR
243 static struct custom_operations vol_custom_operations = {
244   "vol_custom_operations",
245   vol_finalize,
246   custom_compare_default,
247   custom_hash_default,
248   custom_serialize_default,
249   custom_deserialize_default
250 };
251 #endif
252
253 static value
254 Val_connect (virConnectPtr conn)
255 {
256   CAMLparam0 ();
257   CAMLlocal1 (rv);
258   rv = caml_alloc_custom (&conn_custom_operations,
259                           sizeof (virConnectPtr), 0, 1);
260   Connect_val (rv) = conn;
261   CAMLreturn (rv);
262 }
263
264 static value
265 Val_dom (virDomainPtr dom)
266 {
267   CAMLparam0 ();
268   CAMLlocal1 (rv);
269   rv = caml_alloc_custom (&dom_custom_operations,
270                           sizeof (virDomainPtr), 0, 1);
271   Dom_val (rv) = dom;
272   CAMLreturn (rv);
273 }
274
275 static value
276 Val_net (virNetworkPtr net)
277 {
278   CAMLparam0 ();
279   CAMLlocal1 (rv);
280   rv = caml_alloc_custom (&net_custom_operations,
281                           sizeof (virNetworkPtr), 0, 1);
282   Net_val (rv) = net;
283   CAMLreturn (rv);
284 }
285
286 #ifdef HAVE_VIRSTORAGEPOOLPTR
287 static value
288 Val_pol (virStoragePoolPtr pol)
289 {
290   CAMLparam0 ();
291   CAMLlocal1 (rv);
292   rv = caml_alloc_custom (&pol_custom_operations,
293                           sizeof (virStoragePoolPtr), 0, 1);
294   Pol_val (rv) = pol;
295   CAMLreturn (rv);
296 }
297 #endif
298
299 #ifdef HAVE_VIRSTORAGEVOLPTR
300 static value
301 Val_vol (virStorageVolPtr vol)
302 {
303   CAMLparam0 ();
304   CAMLlocal1 (rv);
305   rv = caml_alloc_custom (&vol_custom_operations,
306                           sizeof (virStorageVolPtr), 0, 1);
307   Vol_val (rv) = vol;
308   CAMLreturn (rv);
309 }
310 #endif
311
312 /* This wraps up the (dom, conn) pair (Domain.t). */
313 static value
314 Val_domain (virDomainPtr dom, value connv)
315 {
316   CAMLparam1 (connv);
317   CAMLlocal2 (rv, v);
318
319   rv = caml_alloc_tuple (2);
320   v = Val_dom (dom);
321   Store_field (rv, 0, v);
322   Store_field (rv, 1, connv);
323   CAMLreturn (rv);
324 }
325
326 /* This wraps up the (net, conn) pair (Network.t). */
327 static value
328 Val_network (virNetworkPtr net, value connv)
329 {
330   CAMLparam1 (connv);
331   CAMLlocal2 (rv, v);
332
333   rv = caml_alloc_tuple (2);
334   v = Val_net (net);
335   Store_field (rv, 0, v);
336   Store_field (rv, 1, connv);
337   CAMLreturn (rv);
338 }
339
340 #ifdef HAVE_VIRSTORAGEPOOLPTR
341 /* This wraps up the (pol, conn) pair (Pool.t). */
342 static value
343 Val_pool (virStoragePoolPtr pol, value connv)
344 {
345   CAMLparam1 (connv);
346   CAMLlocal2 (rv, v);
347
348   rv = caml_alloc_tuple (2);
349   v = Val_pol (pol);
350   Store_field (rv, 0, v);
351   Store_field (rv, 1, connv);
352   CAMLreturn (rv);
353 }
354 #endif
355
356 #ifdef HAVE_VIRSTORAGEVOLPTR
357 /* This wraps up the (vol, conn) pair (Volume.t). */
358 static value
359 Val_volume (virStorageVolPtr vol, value connv)
360 {
361   CAMLparam1 (connv);
362   CAMLlocal2 (rv, v);
363
364   rv = caml_alloc_tuple (2);
365   v = Val_vol (vol);
366   Store_field (rv, 0, v);
367   Store_field (rv, 1, connv);
368   CAMLreturn (rv);
369 }
370 #endif
371
372 static void
373 conn_finalize (value connv)
374 {
375   virConnectPtr conn = Connect_val (connv);
376   if (conn) (void) virConnectClose (conn);
377 }
378
379 static void
380 dom_finalize (value domv)
381 {
382   virDomainPtr dom = Dom_val (domv);
383   if (dom) (void) virDomainFree (dom);
384 }
385
386 static void
387 net_finalize (value netv)
388 {
389   virNetworkPtr net = Net_val (netv);
390   if (net) (void) virNetworkFree (net);
391 }
392
393 #ifdef HAVE_VIRSTORAGEPOOLPTR
394 static void
395 pol_finalize (value polv)
396 {
397   virStoragePoolPtr pol = Pol_val (polv);
398   if (pol) (void) virStoragePoolFree (pol);
399 }
400 #endif
401
402 #ifdef HAVE_VIRSTORAGEVOLPTR
403 static void
404 vol_finalize (value volv)
405 {
406   virStorageVolPtr vol = Vol_val (volv);
407   if (vol) (void) virStorageVolFree (vol);
408 }
409 #endif