Add contrib directory, and non-upstream patch to add Domain.get_cpu_stats_total.
authorRichard W.M. Jones <rjones@redhat.com>
Fri, 12 Oct 2012 10:48:17 +0000 (11:48 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Fri, 12 Oct 2012 12:46:47 +0000 (13:46 +0100)
This patch needs more thorough review.

contrib/0001-Add-Libvirt.Domain.get_cpu_stats_total.patch [new file with mode: 0644]

diff --git a/contrib/0001-Add-Libvirt.Domain.get_cpu_stats_total.patch b/contrib/0001-Add-Libvirt.Domain.get_cpu_stats_total.patch
new file mode 100644 (file)
index 0000000..d4a496d
--- /dev/null
@@ -0,0 +1,249 @@
+From 99ba7e0eae5ea7567aded458ab63c5984ed43191 Mon Sep 17 00:00:00 2001
+From: Hu Tao <hutao@cn.fujitsu.com>
+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
+