From c6c9c3fff5993056e0af7219f4fe67ab8db3cdf2 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 12 Oct 2012 11:48:17 +0100 Subject: [PATCH] Add contrib directory, and non-upstream patch to add Domain.get_cpu_stats_total. This patch needs more thorough review. --- ...01-Add-Libvirt.Domain.get_cpu_stats_total.patch | 249 +++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 contrib/0001-Add-Libvirt.Domain.get_cpu_stats_total.patch 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 index 0000000..d4a496d --- /dev/null +++ b/contrib/0001-Add-Libvirt.Domain.get_cpu_stats_total.patch @@ -0,0 +1,249 @@ +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 + -- 1.8.3.1