From 99ba7e0eae5ea7567aded458ab63c5984ed43191 Mon Sep 17 00:00:00 2001 From: Hu Tao Date: Wed, 9 May 2012 16:48:31 +0800 Subject: [PATCH] Add Libvirt.Domain.get_cpu_stats_total. Original patch by Hu Tao. RWMJ modified the patch to split this into two functions (old get_cpu_stats and new get_cpu_stats_total). Apart from that split, the code is identical. --- examples/.depend | 12 +++--- examples/get_cpu_stats.ml | 48 +++++++++++++----------- libvirt/.depend | 12 +++--- libvirt/libvirt.ml | 1 + libvirt/libvirt.mli | 6 ++- libvirt/libvirt_c_oneoffs.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 34 deletions(-) diff --git a/examples/.depend b/examples/.depend index f58db3d..3d955f9 100644 --- a/examples/.depend +++ b/examples/.depend @@ -1,6 +1,6 @@ -get_cpu_stats.cmo: ../libvirt/libvirt.cmi -get_cpu_stats.cmx: ../libvirt/libvirt.cmx -list_domains.cmo: ../libvirt/libvirt.cmi -list_domains.cmx: ../libvirt/libvirt.cmx -node_info.cmo: ../libvirt/libvirt.cmi -node_info.cmx: ../libvirt/libvirt.cmx +node_info.cmo : ../libvirt/libvirt.cmi +node_info.cmx : ../libvirt/libvirt.cmx +get_cpu_stats.cmo : ../libvirt/libvirt.cmi +get_cpu_stats.cmx : ../libvirt/libvirt.cmx +list_domains.cmo : ../libvirt/libvirt.cmi +list_domains.cmx : ../libvirt/libvirt.cmx diff --git a/examples/get_cpu_stats.ml b/examples/get_cpu_stats.ml index d7a8d0c..10b3840 100644 --- a/examples/get_cpu_stats.ml +++ b/examples/get_cpu_stats.ml @@ -18,32 +18,38 @@ 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 in + let dom = D.lookup_by_name conn domname in + let stats = D.get_cpu_stats dom in + let total_stats = D.get_cpu_stats_total dom 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 + ) stats; + + Array.iteri ( + fun n params -> + printf "total:"; + print_params n params; + printf "\n" + ) total_stats + with Libvirt.Virterror err -> eprintf "error: %s\n" (Libvirt.Virterror.to_string err) diff --git a/libvirt/.depend b/libvirt/.depend index 3f2297e..7d32e13 100644 --- a/libvirt/.depend +++ b/libvirt/.depend @@ -1,6 +1,6 @@ -libvirt.cmi: -libvirt_version.cmi: -libvirt.cmo: libvirt.cmi -libvirt.cmx: libvirt.cmi -libvirt_version.cmo: libvirt_version.cmi -libvirt_version.cmx: libvirt_version.cmi +libvirt_version.cmi : +libvirt.cmi : +libvirt_version.cmo : libvirt_version.cmi +libvirt_version.cmx : libvirt_version.cmi +libvirt.cmo : libvirt.cmi +libvirt.cmx : libvirt.cmi diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml index 07542a9..2997b0b 100644 --- a/libvirt/libvirt.ml +++ b/libvirt/libvirt.ml @@ -418,6 +418,7 @@ struct 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 -> typed_param list array = "ocaml_libvirt_domain_get_cpu_stats" + external get_cpu_stats_total : [>`R] t -> typed_param list array = "ocaml_libvirt_domain_get_cpu_stats_total" 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 5a288c0..020be59 100644 --- a/libvirt/libvirt.mli +++ b/libvirt/libvirt.mli @@ -560,7 +560,11 @@ sig of the array and bitmap returned from this function. *) val get_cpu_stats : [>`R] t -> typed_param list array - (** [get_pcpu_stats dom] returns the physical CPU stats + (** [get_cpu_stats dom] returns the per-CPU physical CPU stats + for a domain. See the libvirt documentation for details. + *) + val get_cpu_stats_total : [>`R] t -> typed_param list array + (** [get_cpu_stats dom] returns the total physical CPU stats for a domain. See the libvirt documentation for details. *) val get_max_vcpus : [>`R] t -> int diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c index 70cf96f..2a1850f 100644 --- a/libvirt/libvirt_c_oneoffs.c +++ b/libvirt/libvirt_c_oneoffs.c @@ -638,6 +638,95 @@ ocaml_libvirt_domain_get_cpu_stats (value domv) #endif } +CAMLprim value +ocaml_libvirt_domain_get_cpu_stats_total (value domv) +{ +#ifdef HAVE_VIRDOMAINGETCPUSTATS + CAMLparam1 (domv); + CAMLlocal5 (cpustats, param_head, param_node, typed_param, typed_param_value); + CAMLlocal1 (v); + virDomainPtr dom = Domain_val (domv); + virConnectPtr conn = Connect_domv (domv); + virTypedParameterPtr params; + int r, nparams, j, pos; + + /* get total information */ + NONBLOCKING (nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0)); + 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, 0)); + 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 +} + #ifdef HAVE_WEAK_SYMBOLS #ifdef HAVE_VIRDOMAINMIGRATE extern virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn, -- 1.7.11.4