Changed from V3:
use new virDomainGetCPUStats() libvirt-API.
use C code to construct the typed_param list array
Acked-by: "Richard W.M. Jones" <rjones(a)redhat.com>
Signed-off-by: Lai Jiangshan <laijs(a)cn.fujitsu.com>
---
libvirt/libvirt.ml | 8 ++++
libvirt/libvirt.mli | 11 +++++
libvirt/libvirt_c_oneoffs.c | 91 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
index fc29264..08c501b 100644
--- a/libvirt/libvirt.ml
+++ b/libvirt/libvirt.ml
@@ -343,6 +343,13 @@ struct
| SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
| SchedFieldFloat of float | SchedFieldBool of bool
+ type typed_param = string * typed_param_value
+ and typed_param_value =
+ | TypedFieldInt32 of int32 | TypedFieldUInt32 of int32
+ | TypedFieldInt64 of int64 | TypedFieldUInt64 of int64
+ | TypedFieldFloat of float | TypedFieldBool of bool
+ | TypedFieldString of string
+
type migrate_flag = Live
type memory_flag = Virtual
@@ -419,6 +426,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 -> 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 7bda889..31f2ca2 100644
--- a/libvirt/libvirt.mli
+++ b/libvirt/libvirt.mli
@@ -439,6 +439,13 @@ sig
| SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
| SchedFieldFloat of float | SchedFieldBool of bool
+ type typed_param = string * typed_param_value
+ and typed_param_value =
+ | TypedFieldInt32 of int32 | TypedFieldUInt32 of int32
+ | TypedFieldInt64 of int64 | TypedFieldUInt64 of int64
+ | TypedFieldFloat of float | TypedFieldBool of bool
+ | TypedFieldString of string
+
type migrate_flag = Live
type memory_flag = Virtual
@@ -586,6 +593,10 @@ 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 -> typed_param list array
+ (** [get_pcpu_stats dom nr_pcpu] returns the physic CPU stats
+ for a domain. See the libvirt documentation for details.
+ *)
val get_max_vcpus : [>`R] t -> int
(** Returns the maximum number of vCPUs supported for this domain. *)
val attach_device : [>`W] t -> xml -> unit
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
index d87dd21..a0c74be 100644
--- a/libvirt/libvirt_c_oneoffs.c
+++ b/libvirt/libvirt_c_oneoffs.c
@@ -604,6 +604,97 @@ ocaml_libvirt_domain_get_vcpus (value domv, value maxinfov, value
maplenv)
CAMLreturn (rv);
}
+CAMLprim value
+ocaml_libvirt_domain_get_cpu_stats (value domv, value nr_pcpusv)
+{
+ CAMLparam2 (domv, nr_pcpusv);
+ CAMLlocal5 (cpustats, param_head, param_node, typed_param, typed_param_value);
+ virDomainPtr dom = Domain_val (domv);
+ virConnectPtr conn = Connect_domv (domv);
+ int nr_pcpus = Int_val (nr_pcpusv);
+ virTypedParameterPtr params;
+ int r, cpu, ncpus, nparams, i, j, pos;
+
+ /* get percpu information */
+ NONBLOCKING (nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0));
+ CHECK_ERROR (nparams < 0, conn, "virDomainGetCPUStats");
+
+ if ((params = malloc(sizeof(*params) * nparams * 128)) == NULL)
+ caml_failwith ((char *)__FUNCTION__);
+
+ cpustats = caml_alloc (nr_pcpus, 0); /* cpustats: array of params(list of typed_param)
*/
+ cpu = 0;
+ while (cpu < nr_pcpus) {
+ ncpus = nr_pcpus - cpu > 128 ? 128 : nr_pcpus - cpu;
+
+ NONBLOCKING (r = virDomainGetCPUStats(dom, params, nparams, cpu, ncpus, 0));
+ CHECK_ERROR (r < 0, conn, "virDomainGetCPUStats");
+
+ for (i = 0; i < ncpus; i++) {
+ /* list of typed_param: single linked list of param_nodes */
+ param_head = Val_emptylist; /* param_head: the head param_node of list of
typed_param */
+
+ if (params[i * nparams].type == 0) {
+ Store_field(cpustats, cpu + i, param_head);
+ continue;
+ }
+
+ for (j = nparams - 1; j >= 0; j--) {
+ pos = i * nparams + j;
+ if (params[pos].type == 0)
+ continue;
+
+ 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);
+ Store_field(typed_param_value, 0, caml_copy_int32(params[pos].value.i));
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ typed_param_value = caml_alloc (1, 1);
+ Store_field(typed_param_value, 0, caml_copy_int32(params[pos].value.ui));
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ typed_param_value = caml_alloc (1, 2);
+ Store_field(typed_param_value, 0, caml_copy_int64(params[pos].value.l));
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ typed_param_value = caml_alloc (1, 3);
+ Store_field(typed_param_value, 0, caml_copy_int64(params[pos].value.ul));
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ typed_param_value = caml_alloc (1, 4);
+ Store_field(typed_param_value, 0, caml_copy_double(params[pos].value.d));
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ typed_param_value = caml_alloc (1, 5);
+ Store_field(typed_param_value, 0, Int_val(!!(params[pos].value.b)));
+ break;
+ case VIR_TYPED_PARAM_STRING:
+ typed_param_value = caml_alloc (1, 6);
+ Store_field(typed_param_value, 0, caml_copy_string(params[pos].value.s));
+ break;
+ default:
+ free(params);
+ caml_failwith ((char *)__FUNCTION__);
+ }
+ Store_field(typed_param, 1, typed_param_value);
+ }
+ Store_field(cpustats, cpu + i, param_head);
+ }
+ cpu += ncpus;
+ }
+ free(params);
+ CAMLreturn (cpustats);
+}
#ifdef HAVE_WEAK_SYMBOLS
#ifdef HAVE_VIRDOMAINMIGRATE
extern virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,