X-Git-Url: http://git.annexia.org/?p=virt-top.git;a=blobdiff_plain;f=libvirt%2Flibvirt_c.c;h=a2bb1ade61a422ee95ba659d5c43806809dfa86b;hp=f896097ed2e7e062d8975e2925032731be63ff19;hb=38e7a75efaab8a6a709cbad8342bca4a45ead8cc;hpb=0e09861c06a0c274bcfdacceaee347f8aaa969cb diff --git a/libvirt/libvirt_c.c b/libvirt/libvirt_c.c index f896097..a2bb1ad 100644 --- a/libvirt/libvirt_c.c +++ b/libvirt/libvirt_c.c @@ -1,6 +1,20 @@ /* 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 */ #include "config.h" @@ -102,6 +116,16 @@ extern int virDomainSetSchedulerParameters (virDomainPtr domain, int nparams) __attribute__((weak)); #endif +#ifdef HAVE_VIRNODEGETFREEMEMORY +extern unsigned long long virNodeGetFreeMemory (virConnectPtr conn) + __attribute__((weak)); +#endif +#ifdef HAVE_VIRNODEGETCELLSFREEMEMORY +extern int virNodeGetCellsFreeMemory (virConnectPtr conn, + unsigned long long *freeMems, + int startCell, int maxCells) + __attribute__((weak)); +#endif #endif /* HAVE_WEAK_SYMBOLS */ /*----------------------------------------------------------------------*/ @@ -520,6 +544,55 @@ ocaml_libvirt_connect_get_node_info (value connv) } CAMLprim value +ocaml_libvirt_connect_node_get_free_memory (value connv) +{ +#ifdef HAVE_VIRNODEGETFREEMEMORY + CAMLparam1 (connv); + CAMLlocal1 (rv); + virConnectPtr conn = Connect_val (connv); + unsigned long long r; + + WEAK_SYMBOL_CHECK (virNodeGetFreeMemory); + r = virNodeGetFreeMemory (conn); + CHECK_ERROR (r == 0, conn, "virNodeGetFreeMemory"); + + rv = caml_copy_int64 ((int64) r); + CAMLreturn (rv); +#else + NOT_SUPPORTED ("virNodeGetFreeMemory"); +#endif +} + +CAMLprim value +ocaml_libvirt_connect_node_get_cells_free_memory (value connv, + value startv, value maxv) +{ +#ifdef HAVE_VIRNODEGETCELLSFREEMEMORY + CAMLparam3 (connv, startv, maxv); + CAMLlocal2 (rv, iv); + virConnectPtr conn = Connect_val (connv); + int start = Int_val (startv); + int max = Int_val (maxv); + int r, i; + unsigned long long freemems[max]; + + WEAK_SYMBOL_CHECK (virNodeGetCellsFreeMemory); + r = virNodeGetCellsFreeMemory (conn, freemems, start, max); + CHECK_ERROR (r == -1, conn, "virNodeGetCellsFreeMemory"); + + rv = caml_alloc (r, 0); + for (i = 0; i < r; ++i) { + iv = caml_copy_int64 ((int64) freemems[i]); + Store_field (rv, i, iv); + } + + CAMLreturn (rv); +#else + NOT_SUPPORTED ("virNodeGetCellsFreeMemory"); +#endif +} + +CAMLprim value ocaml_libvirt_domain_create_linux (value connv, value xmlv) { CAMLparam2 (connv, xmlv); @@ -1722,6 +1795,72 @@ _raise_virterror (virConnectPtr conn, const char *fn) CAMLreturn (Val_unit); } +/* 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) { @@ -1729,11 +1868,11 @@ Val_virterror (virErrorPtr err) CAMLlocal3 (rv, connv, optv); rv = caml_alloc (12, 0); - Store_field (rv, 0, Val_int (err->code)); - Store_field (rv, 1, Val_int (err->domain)); + 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_int (err->level)); + Store_field (rv, 3, Val_err_level (err->level)); /* conn, dom and net fields, all optional */ if (err->conn) {