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 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 /* Please read libvirt/README file. */
22 /*----------------------------------------------------------------------*/
25 ocaml_libvirt_get_version (value driverv, value unit)
27 CAMLparam2 (driverv, unit);
29 const char *driver = Optstring_val (driverv);
30 unsigned long libVer, typeVer = 0, *typeVer_ptr;
33 typeVer_ptr = driver ? &typeVer : NULL;
34 NONBLOCKING (r = virGetVersion (&libVer, driver, typeVer_ptr));
35 CHECK_ERROR (r == -1, NULL, "virGetVersion");
37 rv = caml_alloc_tuple (2);
38 Store_field (rv, 0, Val_int (libVer));
39 Store_field (rv, 1, Val_int (typeVer));
43 /*----------------------------------------------------------------------*/
45 /* Connection object. */
48 ocaml_libvirt_connect_open (value namev, value unit)
50 CAMLparam2 (namev, unit);
52 const char *name = Optstring_val (namev);
55 NONBLOCKING (conn = virConnectOpen (name));
56 CHECK_ERROR (!conn, NULL, "virConnectOpen");
58 rv = Val_connect (conn);
64 ocaml_libvirt_connect_open_readonly (value namev, value unit)
66 CAMLparam2 (namev, unit);
68 const char *name = Optstring_val (namev);
71 NONBLOCKING (conn = virConnectOpenReadOnly (name));
72 CHECK_ERROR (!conn, NULL, "virConnectOpen");
74 rv = Val_connect (conn);
80 ocaml_libvirt_connect_get_version (value connv)
83 virConnectPtr conn = Connect_val (connv);
87 NONBLOCKING (r = virConnectGetVersion (conn, &hvVer));
88 CHECK_ERROR (r == -1, conn, "virConnectGetVersion");
90 CAMLreturn (Val_int (hvVer));
94 ocaml_libvirt_connect_get_max_vcpus (value connv, value typev)
96 CAMLparam2 (connv, typev);
97 virConnectPtr conn = Connect_val (connv);
98 const char *type = Optstring_val (typev);
101 NONBLOCKING (r = virConnectGetMaxVcpus (conn, type));
102 CHECK_ERROR (r == -1, conn, "virConnectGetMaxVcpus");
104 CAMLreturn (Val_int (r));
108 ocaml_libvirt_connect_get_node_info (value connv)
112 virConnectPtr conn = Connect_val (connv);
116 NONBLOCKING (r = virNodeGetInfo (conn, &info));
117 CHECK_ERROR (r == -1, conn, "virNodeGetInfo");
119 rv = caml_alloc (8, 0);
120 v = caml_copy_string (info.model); Store_field (rv, 0, v);
121 v = caml_copy_int64 (info.memory); Store_field (rv, 1, v);
122 Store_field (rv, 2, Val_int (info.cpus));
123 Store_field (rv, 3, Val_int (info.mhz));
124 Store_field (rv, 4, Val_int (info.nodes));
125 Store_field (rv, 5, Val_int (info.sockets));
126 Store_field (rv, 6, Val_int (info.cores));
127 Store_field (rv, 7, Val_int (info.threads));
132 #ifdef HAVE_WEAK_SYMBOLS
133 #ifdef HAVE_VIRNODEGETFREEMEMORY
134 extern unsigned long long virNodeGetFreeMemory (virConnectPtr conn)
135 __attribute__((weak));
140 ocaml_libvirt_connect_node_get_free_memory (value connv)
142 #ifdef HAVE_VIRNODEGETFREEMEMORY
145 virConnectPtr conn = Connect_val (connv);
146 unsigned long long r;
148 WEAK_SYMBOL_CHECK (virNodeGetFreeMemory);
149 NONBLOCKING (r = virNodeGetFreeMemory (conn));
150 CHECK_ERROR (r == 0, conn, "virNodeGetFreeMemory");
152 rv = caml_copy_int64 ((int64) r);
155 not_supported ("virNodeGetFreeMemory");
159 #ifdef HAVE_WEAK_SYMBOLS
160 #ifdef HAVE_VIRNODEGETCELLSFREEMEMORY
161 extern int virNodeGetCellsFreeMemory (virConnectPtr conn,
162 unsigned long long *freeMems,
163 int startCell, int maxCells)
164 __attribute__((weak));
169 ocaml_libvirt_connect_node_get_cells_free_memory (value connv,
170 value startv, value maxv)
172 #ifdef HAVE_VIRNODEGETCELLSFREEMEMORY
173 CAMLparam3 (connv, startv, maxv);
175 virConnectPtr conn = Connect_val (connv);
176 int start = Int_val (startv);
177 int max = Int_val (maxv);
179 unsigned long long freemems[max];
181 WEAK_SYMBOL_CHECK (virNodeGetCellsFreeMemory);
182 NONBLOCKING (r = virNodeGetCellsFreeMemory (conn, freemems, start, max));
183 CHECK_ERROR (r == -1, conn, "virNodeGetCellsFreeMemory");
185 rv = caml_alloc (r, 0);
186 for (i = 0; i < r; ++i) {
187 iv = caml_copy_int64 ((int64) freemems[i]);
188 Store_field (rv, i, iv);
193 not_supported ("virNodeGetCellsFreeMemory");
197 #ifdef HAVE_WEAK_SYMBOLS
198 #ifdef HAVE_VIRCONNECTLISTALLDOMAINS
199 extern int virConnectListAllDomains (virConnectPtr conn,
200 virDomainPtr **domains,
201 virDomainInfo **infos,
203 __attribute__((weak));
208 ocaml_libvirt_connect_list_all_domains (value connv,
212 #ifdef HAVE_VIRCONNECTLISTALLDOMAINS
213 CAMLparam3 (connv, wantinfov, flagsv);
214 CAMLlocal4 (flagv, rv, rv1, rv2);
216 virConnectPtr conn = Connect_val (connv);
217 virDomainPtr *domains;
218 virDomainInfo *infos;
219 int want_info, i, r, flag, flags = 0;
222 if (wantinfov == Val_int (0)) /* None == true */
225 want_info = Bool_val (Field (wantinfov, 0));
227 /* Iterate over the list of flags. */
228 for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1)) {
229 flagv = Field (flagsv, 0);
230 flag = Int_val (flagv);
232 case 0: flags |= VIR_DOMAIN_LIST_NOSTATE; break;
233 case 1: flags |= VIR_DOMAIN_LIST_RUNNING; break;
234 case 2: flags |= VIR_DOMAIN_LIST_BLOCKED; break;
235 case 3: flags |= VIR_DOMAIN_LIST_PAUSED; break;
236 case 4: flags |= VIR_DOMAIN_LIST_SHUTDOWN; break;
237 case 5: flags |= VIR_DOMAIN_LIST_SHUTOFF; break;
238 case 6: flags |= VIR_DOMAIN_LIST_CRASHED; break;
239 case 7: flags |= VIR_DOMAIN_LIST_ACTIVE; break;
240 case 8: flags |= VIR_DOMAIN_LIST_INACTIVE; break;
241 case 9: flags |= VIR_DOMAIN_LIST_ALL; break;
245 WEAK_SYMBOL_CHECK (virConnectListAllDomains);
246 NONBLOCKING (r = virConnectListAllDomains (conn, &domains,
247 want_info ? &infos : NULL,
249 CHECK_ERROR (r == -1, conn, "virConnectListAllDomains");
251 /* Convert the result into a pair of arrays. */
252 rv1 = caml_alloc (r, 0);
253 for (i = 0; i < r; ++i) {
254 v1 = Val_domain (domains[i], connv);
255 Store_field (rv1, i, v1);
260 rv2 = caml_alloc (r, 0);
262 for (i = 0; i < r; ++i) {
263 v1 = caml_alloc (5, 0);
264 Store_field (v1, 0, Val_int (infos[i].state));
265 v2 = caml_copy_int64 (infos[i].maxMem); Store_field (v1, 1, v2);
266 v2 = caml_copy_int64 (infos[i].memory); Store_field (v1, 2, v2);
267 Store_field (v1, 3, Val_int (infos[i].nrVirtCpu));
268 v2 = caml_copy_int64 (infos[i].cpuTime); Store_field (v1, 4, v2);
270 Store_field (rv2, i, v1);
276 rv2 = caml_alloc (0, 0); /* zero-length array */
278 rv = caml_alloc_tuple (2);
279 Store_field (rv, 0, rv1);
280 Store_field (rv, 1, rv2);
283 not_supported ("virConnectListAllDomains");
288 ocaml_libvirt_domain_get_id (value domv)
291 virDomainPtr dom = Domain_val (domv);
292 virConnectPtr conn = Connect_domv (domv);
295 NONBLOCKING (r = virDomainGetID (dom));
296 /* There's a bug in libvirt which means that if you try to get
297 * the ID of a defined-but-not-running domain, it returns -1,
298 * and there's no way to distinguish that from an error.
300 CHECK_ERROR (r == (unsigned int) -1, conn, "virDomainGetID");
302 CAMLreturn (Val_int ((int) r));
306 ocaml_libvirt_domain_get_max_memory (value domv)
310 virDomainPtr dom = Domain_val (domv);
311 virConnectPtr conn = Connect_domv (domv);
314 NONBLOCKING (r = virDomainGetMaxMemory (dom));
315 CHECK_ERROR (r == 0 /* [sic] */, conn, "virDomainGetMaxMemory");
317 rv = caml_copy_int64 (r);
322 ocaml_libvirt_domain_set_max_memory (value domv, value memv)
324 CAMLparam2 (domv, memv);
325 virDomainPtr dom = Domain_val (domv);
326 virConnectPtr conn = Connect_domv (domv);
327 unsigned long mem = Int64_val (memv);
330 NONBLOCKING (r = virDomainSetMaxMemory (dom, mem));
331 CHECK_ERROR (r == -1, conn, "virDomainSetMaxMemory");
333 CAMLreturn (Val_unit);
337 ocaml_libvirt_domain_set_memory (value domv, value memv)
339 CAMLparam2 (domv, memv);
340 virDomainPtr dom = Domain_val (domv);
341 virConnectPtr conn = Connect_domv (domv);
342 unsigned long mem = Int64_val (memv);
345 NONBLOCKING (r = virDomainSetMemory (dom, mem));
346 CHECK_ERROR (r == -1, conn, "virDomainSetMemory");
348 CAMLreturn (Val_unit);
352 ocaml_libvirt_domain_get_info (value domv)
356 virDomainPtr dom = Domain_val (domv);
357 virConnectPtr conn = Connect_domv (domv);
361 NONBLOCKING (r = virDomainGetInfo (dom, &info));
362 CHECK_ERROR (r == -1, conn, "virDomainGetInfo");
364 rv = caml_alloc (5, 0);
365 Store_field (rv, 0, Val_int (info.state)); // These flags are compatible.
366 v = caml_copy_int64 (info.maxMem); Store_field (rv, 1, v);
367 v = caml_copy_int64 (info.memory); Store_field (rv, 2, v);
368 Store_field (rv, 3, Val_int (info.nrVirtCpu));
369 v = caml_copy_int64 (info.cpuTime); Store_field (rv, 4, v);
374 #ifdef HAVE_WEAK_SYMBOLS
375 #ifdef HAVE_VIRDOMAINGETSCHEDULERTYPE
376 extern char *virDomainGetSchedulerType(virDomainPtr domain,
378 __attribute__((weak));
383 ocaml_libvirt_domain_get_scheduler_type (value domv)
385 #ifdef HAVE_VIRDOMAINGETSCHEDULERTYPE
387 CAMLlocal2 (rv, strv);
388 virDomainPtr dom = Domain_val (domv);
389 virConnectPtr conn = Connect_domv (domv);
393 WEAK_SYMBOL_CHECK (virDomainGetSchedulerType);
394 NONBLOCKING (r = virDomainGetSchedulerType (dom, &nparams));
395 CHECK_ERROR (!r, conn, "virDomainGetSchedulerType");
397 rv = caml_alloc_tuple (2);
398 strv = caml_copy_string (r); Store_field (rv, 0, strv);
400 Store_field (rv, 1, nparams);
403 not_supported ("virDomainGetSchedulerType");
407 #ifdef HAVE_WEAK_SYMBOLS
408 #ifdef HAVE_VIRDOMAINGETSCHEDULERPARAMETERS
409 extern int virDomainGetSchedulerParameters (virDomainPtr domain,
410 virSchedParameterPtr params,
412 __attribute__((weak));
417 ocaml_libvirt_domain_get_scheduler_parameters (value domv, value nparamsv)
419 #ifdef HAVE_VIRDOMAINGETSCHEDULERPARAMETERS
420 CAMLparam2 (domv, nparamsv);
421 CAMLlocal4 (rv, v, v2, v3);
422 virDomainPtr dom = Domain_val (domv);
423 virConnectPtr conn = Connect_domv (domv);
424 int nparams = Int_val (nparamsv);
425 virSchedParameter params[nparams];
428 WEAK_SYMBOL_CHECK (virDomainGetSchedulerParameters);
429 NONBLOCKING (r = virDomainGetSchedulerParameters (dom, params, &nparams));
430 CHECK_ERROR (r == -1, conn, "virDomainGetSchedulerParameters");
432 rv = caml_alloc (nparams, 0);
433 for (i = 0; i < nparams; ++i) {
434 v = caml_alloc_tuple (2); Store_field (rv, i, v);
435 v2 = caml_copy_string (params[i].field); Store_field (v, 0, v2);
436 switch (params[i].type) {
437 case VIR_DOMAIN_SCHED_FIELD_INT:
438 v2 = caml_alloc (1, 0);
439 v3 = caml_copy_int32 (params[i].value.i); Store_field (v2, 0, v3);
441 case VIR_DOMAIN_SCHED_FIELD_UINT:
442 v2 = caml_alloc (1, 1);
443 v3 = caml_copy_int32 (params[i].value.ui); Store_field (v2, 0, v3);
445 case VIR_DOMAIN_SCHED_FIELD_LLONG:
446 v2 = caml_alloc (1, 2);
447 v3 = caml_copy_int64 (params[i].value.l); Store_field (v2, 0, v3);
449 case VIR_DOMAIN_SCHED_FIELD_ULLONG:
450 v2 = caml_alloc (1, 3);
451 v3 = caml_copy_int64 (params[i].value.ul); Store_field (v2, 0, v3);
453 case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
454 v2 = caml_alloc (1, 4);
455 v3 = caml_copy_double (params[i].value.d); Store_field (v2, 0, v3);
457 case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
458 v2 = caml_alloc (1, 5);
459 Store_field (v2, 0, Val_int (params[i].value.b));
462 caml_failwith ((char *)__FUNCTION__);
464 Store_field (v, 1, v2);
468 not_supported ("virDomainGetSchedulerParameters");
472 #ifdef HAVE_WEAK_SYMBOLS
473 #ifdef HAVE_VIRDOMAINSETSCHEDULERPARAMETERS
474 extern int virDomainSetSchedulerParameters (virDomainPtr domain,
475 virSchedParameterPtr params,
477 __attribute__((weak));
482 ocaml_libvirt_domain_set_scheduler_parameters (value domv, value paramsv)
484 #ifdef HAVE_VIRDOMAINSETSCHEDULERPARAMETERS
485 CAMLparam2 (domv, paramsv);
487 virDomainPtr dom = Domain_val (domv);
488 virConnectPtr conn = Connect_domv (domv);
489 int nparams = Wosize_val (paramsv);
490 virSchedParameter params[nparams];
494 for (i = 0; i < nparams; ++i) {
495 v = Field (paramsv, i); /* Points to the two-element tuple. */
496 name = String_val (Field (v, 0));
497 strncpy (params[i].field, name, VIR_DOMAIN_SCHED_FIELD_LENGTH);
498 params[i].field[VIR_DOMAIN_SCHED_FIELD_LENGTH-1] = '\0';
499 v = Field (v, 1); /* Points to the sched_param_value block. */
500 switch (Tag_val (v)) {
502 params[i].type = VIR_DOMAIN_SCHED_FIELD_INT;
503 params[i].value.i = Int32_val (Field (v, 0));
506 params[i].type = VIR_DOMAIN_SCHED_FIELD_UINT;
507 params[i].value.ui = Int32_val (Field (v, 0));
510 params[i].type = VIR_DOMAIN_SCHED_FIELD_LLONG;
511 params[i].value.l = Int64_val (Field (v, 0));
514 params[i].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;
515 params[i].value.ul = Int64_val (Field (v, 0));
518 params[i].type = VIR_DOMAIN_SCHED_FIELD_DOUBLE;
519 params[i].value.d = Double_val (Field (v, 0));
522 params[i].type = VIR_DOMAIN_SCHED_FIELD_BOOLEAN;
523 params[i].value.b = Int_val (Field (v, 0));
526 caml_failwith ((char *)__FUNCTION__);
530 WEAK_SYMBOL_CHECK (virDomainSetSchedulerParameters);
531 NONBLOCKING (r = virDomainSetSchedulerParameters (dom, params, nparams));
532 CHECK_ERROR (r == -1, conn, "virDomainSetSchedulerParameters");
534 CAMLreturn (Val_unit);
536 not_supported ("virDomainSetSchedulerParameters");
541 ocaml_libvirt_domain_set_vcpus (value domv, value nvcpusv)
543 CAMLparam2 (domv, nvcpusv);
544 virDomainPtr dom = Domain_val (domv);
545 virConnectPtr conn = Connect_domv (domv);
546 int r, nvcpus = Int_val (nvcpusv);
548 NONBLOCKING (r = virDomainSetVcpus (dom, nvcpus));
549 CHECK_ERROR (r == -1, conn, "virDomainSetVcpus");
551 CAMLreturn (Val_unit);
555 ocaml_libvirt_domain_pin_vcpu (value domv, value vcpuv, value cpumapv)
557 CAMLparam3 (domv, vcpuv, cpumapv);
558 virDomainPtr dom = Domain_val (domv);
559 virConnectPtr conn = Connect_domv (domv);
560 int maplen = caml_string_length (cpumapv);
561 unsigned char *cpumap = (unsigned char *) String_val (cpumapv);
562 int vcpu = Int_val (vcpuv);
565 NONBLOCKING (r = virDomainPinVcpu (dom, vcpu, cpumap, maplen));
566 CHECK_ERROR (r == -1, conn, "virDomainPinVcpu");
568 CAMLreturn (Val_unit);
572 ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value maplenv)
574 CAMLparam3 (domv, maxinfov, maplenv);
575 CAMLlocal5 (rv, infov, strv, v, v2);
576 virDomainPtr dom = Domain_val (domv);
577 virConnectPtr conn = Connect_domv (domv);
578 int maxinfo = Int_val (maxinfov);
579 int maplen = Int_val (maplenv);
580 virVcpuInfo info[maxinfo];
581 unsigned char cpumaps[maxinfo * maplen];
584 memset (info, 0, sizeof (virVcpuInfo) * maxinfo);
585 memset (cpumaps, 0, maxinfo * maplen);
587 NONBLOCKING (r = virDomainGetVcpus (dom, info, maxinfo, cpumaps, maplen));
588 CHECK_ERROR (r == -1, conn, "virDomainPinVcpu");
590 /* Copy the virVcpuInfo structures. */
591 infov = caml_alloc (maxinfo, 0);
592 for (i = 0; i < maxinfo; ++i) {
593 v2 = caml_alloc (4, 0); Store_field (infov, i, v2);
594 Store_field (v2, 0, Val_int (info[i].number));
595 Store_field (v2, 1, Val_int (info[i].state));
596 v = caml_copy_int64 (info[i].cpuTime); Store_field (v2, 2, v);
597 Store_field (v2, 3, Val_int (info[i].cpu));
600 /* Copy the bitmap. */
601 strv = caml_alloc_string (maxinfo * maplen);
602 memcpy (String_val (strv), cpumaps, maxinfo * maplen);
604 /* Allocate the tuple and return it. */
605 rv = caml_alloc_tuple (3);
606 Store_field (rv, 0, Val_int (r)); /* number of CPUs. */
607 Store_field (rv, 1, infov);
608 Store_field (rv, 2, strv);
613 #ifdef HAVE_WEAK_SYMBOLS
614 #ifdef HAVE_VIRDOMAINMIGRATE
615 extern virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,
616 unsigned long flags, const char *dname,
617 const char *uri, unsigned long bandwidth)
618 __attribute__((weak));
623 ocaml_libvirt_domain_migrate_native (value domv, value dconnv, value flagsv, value optdnamev, value opturiv, value optbandwidthv, value unitv)
625 #ifdef HAVE_VIRDOMAINMIGRATE
626 CAMLparam5 (domv, dconnv, flagsv, optdnamev, opturiv);
627 CAMLxparam2 (optbandwidthv, unitv);
628 CAMLlocal2 (flagv, rv);
629 virDomainPtr dom = Domain_val (domv);
630 virConnectPtr conn = Connect_domv (domv);
631 virConnectPtr dconn = Connect_val (dconnv);
633 const char *dname = Optstring_val (optdnamev);
634 const char *uri = Optstring_val (opturiv);
635 unsigned long bandwidth;
638 /* Iterate over the list of flags. */
639 for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1))
641 flagv = Field (flagsv, 0);
642 if (flagv == Val_int (0))
643 flags |= VIR_MIGRATE_LIVE;
646 if (optbandwidthv == Val_int (0)) /* None */
648 else /* Some bandwidth */
649 bandwidth = Int_val (Field (optbandwidthv, 0));
651 WEAK_SYMBOL_CHECK (virDomainMigrate);
652 NONBLOCKING (r = virDomainMigrate (dom, dconn, flags, dname, uri, bandwidth));
653 CHECK_ERROR (!r, conn, "virDomainMigrate");
655 rv = Val_domain (r, dconnv);
659 #else /* virDomainMigrate not supported */
660 not_supported ("virDomainMigrate");
665 ocaml_libvirt_domain_migrate_bytecode (value *argv, int argn)
667 return ocaml_libvirt_domain_migrate_native (argv[0], argv[1], argv[2],
668 argv[3], argv[4], argv[5],
672 #ifdef HAVE_WEAK_SYMBOLS
673 #ifdef HAVE_VIRDOMAINBLOCKSTATS
674 extern int virDomainBlockStats (virDomainPtr dom,
676 virDomainBlockStatsPtr stats,
678 __attribute__((weak));
683 ocaml_libvirt_domain_block_stats (value domv, value pathv)
685 #if HAVE_VIRDOMAINBLOCKSTATS
686 CAMLparam2 (domv, pathv);
688 virDomainPtr dom = Domain_val (domv);
689 virConnectPtr conn = Connect_domv (domv);
690 char *path = String_val (pathv);
691 struct _virDomainBlockStats stats;
694 WEAK_SYMBOL_CHECK (virDomainBlockStats);
695 NONBLOCKING (r = virDomainBlockStats (dom, path, &stats, sizeof stats));
696 CHECK_ERROR (r == -1, conn, "virDomainBlockStats");
698 rv = caml_alloc (5, 0);
699 v = caml_copy_int64 (stats.rd_req); Store_field (rv, 0, v);
700 v = caml_copy_int64 (stats.rd_bytes); Store_field (rv, 1, v);
701 v = caml_copy_int64 (stats.wr_req); Store_field (rv, 2, v);
702 v = caml_copy_int64 (stats.wr_bytes); Store_field (rv, 3, v);
703 v = caml_copy_int64 (stats.errs); Store_field (rv, 4, v);
707 not_supported ("virDomainBlockStats");
711 #ifdef HAVE_WEAK_SYMBOLS
712 #ifdef HAVE_VIRDOMAININTERFACESTATS
713 extern int virDomainInterfaceStats (virDomainPtr dom,
715 virDomainInterfaceStatsPtr stats,
717 __attribute__((weak));
722 ocaml_libvirt_domain_interface_stats (value domv, value pathv)
724 #if HAVE_VIRDOMAININTERFACESTATS
725 CAMLparam2 (domv, pathv);
727 virDomainPtr dom = Domain_val (domv);
728 virConnectPtr conn = Connect_domv (domv);
729 char *path = String_val (pathv);
730 struct _virDomainInterfaceStats stats;
733 WEAK_SYMBOL_CHECK (virDomainInterfaceStats);
734 NONBLOCKING (r = virDomainInterfaceStats (dom, path, &stats, sizeof stats));
735 CHECK_ERROR (r == -1, conn, "virDomainInterfaceStats");
737 rv = caml_alloc (8, 0);
738 v = caml_copy_int64 (stats.rx_bytes); Store_field (rv, 0, v);
739 v = caml_copy_int64 (stats.rx_packets); Store_field (rv, 1, v);
740 v = caml_copy_int64 (stats.rx_errs); Store_field (rv, 2, v);
741 v = caml_copy_int64 (stats.rx_drop); Store_field (rv, 3, v);
742 v = caml_copy_int64 (stats.tx_bytes); Store_field (rv, 4, v);
743 v = caml_copy_int64 (stats.tx_packets); Store_field (rv, 5, v);
744 v = caml_copy_int64 (stats.tx_errs); Store_field (rv, 6, v);
745 v = caml_copy_int64 (stats.tx_drop); Store_field (rv, 7, v);
749 not_supported ("virDomainInterfaceStats");
753 #ifdef HAVE_WEAK_SYMBOLS
754 #ifdef HAVE_VIRDOMAINBLOCKPEEK
755 extern int virDomainBlockPeek (virDomainPtr domain,
757 unsigned long long offset,
761 __attribute__((weak));
766 ocaml_libvirt_domain_block_peek_native (value domv, value pathv, value offsetv, value sizev, value bufferv, value boffv)
768 #ifdef HAVE_VIRDOMAINBLOCKPEEK
769 CAMLparam5 (domv, pathv, offsetv, sizev, bufferv);
771 virDomainPtr dom = Domain_val (domv);
772 virConnectPtr conn = Connect_domv (domv);
773 const char *path = String_val (pathv);
774 unsigned long long offset = Int64_val (offsetv);
775 size_t size = Int_val (sizev);
776 char *buffer = String_val (bufferv);
777 int boff = Int_val (boffv);
780 /* Check that the return buffer is big enough. */
781 if (caml_string_length (bufferv) < boff + size)
782 caml_failwith ("virDomainBlockPeek: return buffer too short");
784 WEAK_SYMBOL_CHECK (virDomainBlockPeek);
785 /* NB. not NONBLOCKING because buffer might move (XXX) */
786 r = virDomainBlockPeek (dom, path, offset, size, buffer+boff, 0);
787 CHECK_ERROR (r == -1, conn, "virDomainBlockPeek");
789 CAMLreturn (Val_unit);
791 #else /* virDomainBlockPeek not supported */
792 not_supported ("virDomainBlockPeek");
797 ocaml_libvirt_domain_block_peek_bytecode (value *argv, int argn)
799 return ocaml_libvirt_domain_block_peek_native (argv[0], argv[1], argv[2],
800 argv[3], argv[4], argv[5]);
803 #ifdef HAVE_WEAK_SYMBOLS
804 #ifdef HAVE_VIRDOMAINMEMORYPEEK
805 extern int virDomainMemoryPeek (virDomainPtr domain,
806 unsigned long long start,
810 __attribute__((weak));
815 ocaml_libvirt_domain_memory_peek_native (value domv, value flagsv, value offsetv, value sizev, value bufferv, value boffv)
817 #ifdef HAVE_VIRDOMAINMEMORYPEEK
818 CAMLparam5 (domv, flagsv, offsetv, sizev, bufferv);
821 virDomainPtr dom = Domain_val (domv);
822 virConnectPtr conn = Connect_domv (domv);
824 unsigned long long offset = Int64_val (offsetv);
825 size_t size = Int_val (sizev);
826 char *buffer = String_val (bufferv);
827 int boff = Int_val (boffv);
830 /* Check that the return buffer is big enough. */
831 if (caml_string_length (bufferv) < boff + size)
832 caml_failwith ("virDomainMemoryPeek: return buffer too short");
835 for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1))
837 flagv = Field (flagsv, 0);
838 if (flagv == Val_int (0))
839 flags |= VIR_MEMORY_VIRTUAL;
842 WEAK_SYMBOL_CHECK (virDomainMemoryPeek);
843 /* NB. not NONBLOCKING because buffer might move (XXX) */
844 r = virDomainMemoryPeek (dom, offset, size, buffer+boff, flags);
845 CHECK_ERROR (r == -1, conn, "virDomainMemoryPeek");
847 CAMLreturn (Val_unit);
849 #else /* virDomainMemoryPeek not supported */
850 not_supported ("virDomainMemoryPeek");
855 ocaml_libvirt_domain_memory_peek_bytecode (value *argv, int argn)
857 return ocaml_libvirt_domain_memory_peek_native (argv[0], argv[1], argv[2],
858 argv[3], argv[4], argv[5]);
861 #ifdef HAVE_WEAK_SYMBOLS
862 #ifdef HAVE_VIRSTORAGEPOOLGETINFO
863 extern int virStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info)
864 __attribute__((weak));
869 ocaml_libvirt_storage_pool_get_info (value poolv)
871 #if HAVE_VIRSTORAGEPOOLGETINFO
874 virStoragePoolPtr pool = Pool_val (poolv);
875 virConnectPtr conn = Connect_polv (poolv);
876 virStoragePoolInfo info;
879 WEAK_SYMBOL_CHECK (virStoragePoolGetInfo);
880 NONBLOCKING (r = virStoragePoolGetInfo (pool, &info));
881 CHECK_ERROR (r == -1, conn, "virStoragePoolGetInfo");
883 rv = caml_alloc (4, 0);
884 Store_field (rv, 0, Val_int (info.state));
885 v = caml_copy_int64 (info.capacity); Store_field (rv, 1, v);
886 v = caml_copy_int64 (info.allocation); Store_field (rv, 2, v);
887 v = caml_copy_int64 (info.available); Store_field (rv, 3, v);
891 not_supported ("virStoragePoolGetInfo");
895 #ifdef HAVE_WEAK_SYMBOLS
896 #ifdef HAVE_VIRSTORAGEVOLGETINFO
897 extern int virStorageVolGetInfo(virStorageVolPtr vol, virStorageVolInfoPtr info)
898 __attribute__((weak));
903 ocaml_libvirt_storage_vol_get_info (value volv)
905 #if HAVE_VIRSTORAGEVOLGETINFO
908 virStorageVolPtr vol = Volume_val (volv);
909 virConnectPtr conn = Connect_volv (volv);
910 virStorageVolInfo info;
913 WEAK_SYMBOL_CHECK (virStorageVolGetInfo);
914 NONBLOCKING (r = virStorageVolGetInfo (vol, &info));
915 CHECK_ERROR (r == -1, conn, "virStorageVolGetInfo");
917 rv = caml_alloc (3, 0);
918 Store_field (rv, 0, Val_int (info.type));
919 v = caml_copy_int64 (info.capacity); Store_field (rv, 1, v);
920 v = caml_copy_int64 (info.allocation); Store_field (rv, 1, v);
924 not_supported ("virStorageVolGetInfo");
928 #ifdef HAVE_WEAK_SYMBOLS
929 #ifdef HAVE_VIRJOBGETINFO
930 extern int virJobGetInfo(virJobPtr job, virJobInfoPtr info)
931 __attribute__((weak));
936 ocaml_libvirt_job_get_info (value jobv)
938 #if HAVE_VIRJOBGETINFO
941 virJobPtr job = Job_val (jobv);
942 virConnectPtr conn = Connect_jobv (jobv);
946 WEAK_SYMBOL_CHECK (virJobGetInfo);
947 NONBLOCKING (r = virJobGetInfo (job, &info));
948 CHECK_ERROR (r == -1, conn, "virJobGetInfo");
950 rv = caml_alloc (5, 0);
951 Store_field (rv, 0, Val_int (info.type));
952 Store_field (rv, 1, Val_int (info.state));
953 Store_field (rv, 2, Val_int (info.runningTime));
954 Store_field (rv, 3, Val_int (info.remainingTime));
955 Store_field (rv, 4, Val_int (info.percentComplete));
959 not_supported ("virJobGetInfo");
963 /*----------------------------------------------------------------------*/
966 ocaml_libvirt_virterror_get_last_error (value unitv)
970 virErrorPtr err = virGetLastError ();
972 rv = Val_opt (err, (Val_ptr_t) Val_virterror);
978 ocaml_libvirt_virterror_get_last_conn_error (value connv)
982 virConnectPtr conn = Connect_val (connv);
984 rv = Val_opt (conn, (Val_ptr_t) Val_connect);
990 ocaml_libvirt_virterror_reset_last_error (value unitv)
993 virResetLastError ();
994 CAMLreturn (Val_unit);
998 ocaml_libvirt_virterror_reset_last_conn_error (value connv)
1001 virConnectPtr conn = Connect_val (connv);
1002 virConnResetLastError (conn);
1003 CAMLreturn (Val_unit);
1006 /*----------------------------------------------------------------------*/
1008 /* Initialise the library. */
1010 ocaml_libvirt_init (value unit)
1016 r = virInitialize ();
1017 CHECK_ERROR (r == -1, NULL, "virInitialize");
1019 CAMLreturn (Val_unit);