Remove parameter nr_pcpus. Add another parameter total of type bool
to indicate wheter to get total cpu statistic or per_cpu statistics.
---
examples/get_cpu_stats.ml | 50 ++++++++++++++----------
libvirt/libvirt.ml | 2 +-
libvirt/libvirt.mli | 2 +-
libvirt/libvirt_c_oneoffs.c | 89 +++++++++++++++++++++++++++++++++++++++++-
4 files changed, 117 insertions(+), 26 deletions(-)
diff --git a/examples/get_cpu_stats.ml b/examples/get_cpu_stats.ml
index 962a2a4..a4e657d 100644
--- a/examples/get_cpu_stats.ml
+++ b/examples/get_cpu_stats.ml
@@ -18,32 +18,40 @@ let () =
let domname = Sys.argv.(1) in
let conn = C.connect_readonly () in
-
- let nr_pcpus =
- let info = C.get_node_info conn in
- C.maxcpus_of_node_info info in
-
- let stats =
- let dom = D.lookup_by_name conn domname in
- D.get_cpu_stats dom nr_pcpus [D.None;] in
+ let dom = D.lookup_by_name conn domname in
+
+ let stats = D.get_cpu_stats dom false [D.Vcpu;] in
+ let total_stats = D.get_cpu_stats dom false [D.None;] in
+
+ let print_params n params =
+ List.iter (
+ fun (name, value) ->
+ printf " %s=" name;
+ match value with
+ | D.TypedFieldInt32 i -> printf "%ld" i
+ | D.TypedFieldUInt32 i -> printf "%ld" i
+ | D.TypedFieldInt64 i -> printf "%Ld" i
+ | D.TypedFieldUInt64 i -> printf "%Ld" i
+ | D.TypedFieldFloat f -> printf "%g" f
+ | D.TypedFieldBool b -> printf "%b" b
+ | D.TypedFieldString s -> printf "%S" s
+ ) params in
Array.iteri (
fun n params ->
printf "pCPU %d:" n;
- List.iter (
- fun (name, value) ->
- printf " %s=" name;
- match value with
- | D.TypedFieldInt32 i -> printf "%ld" i
- | D.TypedFieldUInt32 i -> printf "%ld" i
- | D.TypedFieldInt64 i -> printf "%Ld" i
- | D.TypedFieldUInt64 i -> printf "%Ld" i
- | D.TypedFieldFloat f -> printf "%g" f
- | D.TypedFieldBool b -> printf "%b" b
- | D.TypedFieldString s -> printf "%S" s
- ) params;
+ print_params n params;
+ printf "\n"
+ ) stats;
+
+ Array.iteri (
+ fun n params ->
+ printf "total:";
+ print_params n params;
printf "\n"
- ) stats
+ ) total_stats
+
+
with
Libvirt.Virterror err ->
eprintf "error: %s\n" (Libvirt.Virterror.to_string err)
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
index de303f7..8f7abee 100644
--- a/libvirt/libvirt.ml
+++ b/libvirt/libvirt.ml
@@ -421,7 +421,7 @@ struct
external set_vcpus : [>`W] t -> int -> unit =
"ocaml_libvirt_domain_set_vcpus"
external pin_vcpu : [>`W] t -> int -> string -> unit =
"ocaml_libvirt_domain_pin_vcpu"
external get_vcpus : [>`R] t -> int -> int -> int * vcpu_info array *
string = "ocaml_libvirt_domain_get_vcpus"
- external get_cpu_stats : [>`R] t -> int -> get_cpu_stats_flags list ->
typed_param list array = "ocaml_libvirt_domain_get_cpu_stats"
+ external get_cpu_stats : [>`R] t -> bool -> get_cpu_stats_flags list ->
typed_param list array = "ocaml_libvirt_domain_get_cpu_stats"
external get_max_vcpus : [>`R] t -> int =
"ocaml_libvirt_domain_get_max_vcpus"
external attach_device : [>`W] t -> xml -> unit =
"ocaml_libvirt_domain_attach_device"
external detach_device : [>`W] t -> xml -> unit =
"ocaml_libvirt_domain_detach_device"
diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli
index 5a7e536..4be3fe4 100644
--- a/libvirt/libvirt.mli
+++ b/libvirt/libvirt.mli
@@ -563,7 +563,7 @@ sig
for a domain. See the libvirt documentation for details
of the array and bitmap returned from this function.
*)
- val get_cpu_stats : [>`R] t -> int -> get_cpu_stats_flags list ->
typed_param list array
+ val get_cpu_stats : [>`R] t -> bool -> get_cpu_stats_flags list ->
typed_param list array
(** [get_pcpu_stats dom nr_pcpu] returns the physical CPU stats
for a domain. See the libvirt documentation for details.
*)
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index 5d1e8b2..7f8a103 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -532,18 +532,22 @@ extern int virDomainGetCPUStats (virDomainPtr domain,
#endif
CAMLprim value
-ocaml_libvirt_domain_get_cpu_stats (value domv, value nr_pcpusv, value flagsv)
+ocaml_libvirt_domain_get_cpu_stats (value domv, value totalv, value flagsv)
{
#ifdef HAVE_VIRDOMAINGETCPUSTATS
- CAMLparam3 (domv, nr_pcpusv, flagsv);
+ CAMLparam3 (domv, totalv, flagsv);
CAMLlocal5 (cpustats, param_head, param_node, typed_param, typed_param_value);
CAMLlocal1 (v);
virDomainPtr dom = Domain_val (domv);
virConnectPtr conn = Connect_domv (domv);
- int nr_pcpus = Int_val (nr_pcpusv);
+ int get_total = totalv == Val_true ? 1 : 0;
int flags = 0;
virTypedParameterPtr params;
int r, cpu, ncpus, nparams, i, j, pos;
+ int nr_pcpus;
+
+ if (get_total)
+ goto do_total;
/* Iterate over the list of flags. */
for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1))
@@ -557,6 +561,10 @@ ocaml_libvirt_domain_get_cpu_stats (value domv, value nr_pcpusv,
value flagsv)
}
}
+ /* get number of pcpus */
+ NONBLOCKING (nr_pcpus = virDomainGetCPUStats(dom, NULL, 0, 0, 0, flags));
+ CHECK_ERROR (nr_pcpus < 0, conn, "virDomainGetCPUStats");
+
/* get percpu information */
NONBLOCKING (nparams = virDomainGetCPUStats(dom, NULL, 0, 0, 1, flags));
CHECK_ERROR (nparams < 0, conn, "virDomainGetCPUStats");
@@ -642,6 +650,81 @@ ocaml_libvirt_domain_get_cpu_stats (value domv, value nr_pcpusv,
value flagsv)
}
free(params);
CAMLreturn (cpustats);
+
+do_total:
+
+ /* get total information */
+ NONBLOCKING (nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, flags));
+ CHECK_ERROR (nparams < 0, conn, "virDomainGetCPUStats");
+
+ if ((params = malloc(sizeof(*params) * nparams)) == NULL)
+ caml_failwith ("virDomainGetCPUStats: malloc");
+
+ cpustats = caml_alloc (1, 0); /* cpustats: array of params(list of typed_param) */
+
+ NONBLOCKING (r = virDomainGetCPUStats(dom, params, nparams, -1, 1, flags));
+ CHECK_ERROR (r < 0, conn, "virDomainGetCPUStats");
+
+ param_head = Val_emptylist;
+ if (params[nparams].type != 0) {
+ for (j = r - 1; j >= 0; j--) {
+ pos = j;
+
+ param_node = caml_alloc(2, 0); /* param_node: typed_param, next param_node */
+ Store_field(param_node, 1, param_head);
+ param_head = param_node;
+
+ typed_param = caml_alloc(2, 0); /* typed_param: field name(string),
typed_param_value */
+ Store_field(param_node, 0, typed_param);
+ Store_field(typed_param, 0, caml_copy_string(params[pos].field));
+
+ /* typed_param_value: value with the corresponding type tag */
+ switch(params[pos].type) {
+ case VIR_TYPED_PARAM_INT:
+ typed_param_value = caml_alloc (1, 0);
+ v = caml_copy_int32 (params[pos].value.i);
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ typed_param_value = caml_alloc (1, 1);
+ v = caml_copy_int32 (params[pos].value.ui);
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ typed_param_value = caml_alloc (1, 2);
+ v = caml_copy_int64 (params[pos].value.l);
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ typed_param_value = caml_alloc (1, 3);
+ v = caml_copy_int64 (params[pos].value.ul);
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ typed_param_value = caml_alloc (1, 4);
+ v = caml_copy_double (params[pos].value.d);
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ typed_param_value = caml_alloc (1, 5);
+ v = Val_bool (params[pos].value.b);
+ break;
+ case VIR_TYPED_PARAM_STRING:
+ typed_param_value = caml_alloc (1, 6);
+ v = caml_copy_string (params[pos].value.s);
+ free (params[pos].value.s);
+ break;
+ default:
+ /* XXX Memory leak on this path, if there are more
+ * VIR_TYPED_PARAM_STRING past this point in the array.
+ */
+ free (params);
+ caml_failwith ("virDomainGetCPUStats: "
+ "unknown parameter type returned");
+ }
+ Store_field (typed_param_value, 0, v);
+ Store_field (typed_param, 1, typed_param_value);
+ }
+ }
+ Store_field (cpustats, 0, param_head);
+
+ free(params);
+ CAMLreturn (cpustats);
#else
not_supported ("virDomainGetCPUStats");
#endif
--
1.7.1