Blame SOURCES/0003-Add-a-binding-for-virConnectGetAllDomainStats-RHBZ-1.patch

3a23ed
From 380f1e05b244ae4750ca5101b5b5a182dcd0d1fd Mon Sep 17 00:00:00 2001
3a23ed
From: "Richard W.M. Jones" <rjones@redhat.com>
3a23ed
Date: Tue, 28 Mar 2017 10:08:06 +0100
3a23ed
Subject: [PATCH 3/5] Add a binding for virConnectGetAllDomainStats
3a23ed
 (RHBZ#1390171).
3a23ed
3a23ed
---
3a23ed
 .gitignore                       |   2 +
3a23ed
 Makefile.in                      |   1 +
3a23ed
 examples/.depend                 |   2 +
3a23ed
 examples/Makefile.in             |  13 ++++-
3a23ed
 examples/get_all_domain_stats.ml |  65 +++++++++++++++++++++
3a23ed
 libvirt/libvirt.ml               |  23 ++++++++
3a23ed
 libvirt/libvirt.mli              |  28 +++++++++
3a23ed
 libvirt/libvirt_c_oneoffs.c      | 119 ++++++++++++++++++++++++++++++++++++++-
3a23ed
 8 files changed, 250 insertions(+), 3 deletions(-)
3a23ed
 create mode 100644 examples/get_all_domain_stats.ml
3a23ed
3a23ed
diff --git a/.gitignore b/.gitignore
3a23ed
index 71a245e..366eb29 100644
3a23ed
--- a/.gitignore
3a23ed
+++ b/.gitignore
3a23ed
@@ -1,3 +1,4 @@
3a23ed
+.gdb_history
3a23ed
 META
3a23ed
 ocaml-libvirt-*.tar.gz
3a23ed
 ocaml-libvirt-*.exe
3a23ed
@@ -27,6 +28,7 @@ core.*
3a23ed
 *~
3a23ed
 libvirt/libvirt_version.ml
3a23ed
 examples/domain_events
3a23ed
+examples/get_all_domain_stats
3a23ed
 examples/get_cpu_stats
3a23ed
 examples/list_domains
3a23ed
 examples/node_info
3a23ed
diff --git a/Makefile.in b/Makefile.in
3a23ed
index 3b8b7ec..2605ddd 100644
3a23ed
--- a/Makefile.in
3a23ed
+++ b/Makefile.in
3a23ed
@@ -41,6 +41,7 @@ clean:
3a23ed
 	rm -f examples/node_info
3a23ed
 	rm -f examples/get_cpu_stats
3a23ed
 	rm -f examples/domain_events
3a23ed
+	rm -f examples/get_all_domain_stats
3a23ed
 
3a23ed
 distclean: clean
3a23ed
 	rm -f config.h config.log config.status configure
3a23ed
diff --git a/examples/.depend b/examples/.depend
3a23ed
index b5379d8..11f2c7c 100644
3a23ed
--- a/examples/.depend
3a23ed
+++ b/examples/.depend
3a23ed
@@ -1,5 +1,7 @@
3a23ed
 domain_events.cmo : ../libvirt/libvirt.cmi
3a23ed
 domain_events.cmx : ../libvirt/libvirt.cmx
3a23ed
+get_all_domain_stats.cmo : ../libvirt/libvirt.cmi
3a23ed
+get_all_domain_stats.cmx : ../libvirt/libvirt.cmx
3a23ed
 get_cpu_stats.cmo : ../libvirt/libvirt.cmi
3a23ed
 get_cpu_stats.cmx : ../libvirt/libvirt.cmx
3a23ed
 list_domains.cmo : ../libvirt/libvirt.cmi
3a23ed
diff --git a/examples/Makefile.in b/examples/Makefile.in
3a23ed
index 46006a0..8530edc 100644
3a23ed
--- a/examples/Makefile.in
3a23ed
+++ b/examples/Makefile.in
3a23ed
@@ -27,7 +27,8 @@ OCAMLOPTLIBS	:= $(OCAMLCLIBS)
3a23ed
 export LIBRARY_PATH=../libvirt
3a23ed
 export LD_LIBRARY_PATH=../libvirt
3a23ed
 
3a23ed
-BYTE_TARGETS	:= list_domains node_info get_cpu_stats domain_events
3a23ed
+BYTE_TARGETS	:= list_domains node_info get_cpu_stats \
3a23ed
+		   get_all_domain_stats domain_events
3a23ed
 OPT_TARGETS	:= $(BYTE_TARGETS:%=%.opt)
3a23ed
 
3a23ed
 all: $(BYTE_TARGETS)
3a23ed
@@ -64,6 +65,16 @@ get_cpu_stats.opt: get_cpu_stats.cmx
3a23ed
 	  $(OCAMLOPTPACKAGES) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
3a23ed
 	  ../libvirt/mllibvirt.cmxa -o $@ $<
3a23ed
 
3a23ed
+get_all_domain_stats: get_all_domain_stats.cmo
3a23ed
+	$(OCAMLFIND) ocamlc \
3a23ed
+	  $(OCAMLCPACKAGES) $(OCAMLCFLAGS) $(OCAMLCLIBS) \
3a23ed
+	  ../libvirt/mllibvirt.cma -o $@ $<
3a23ed
+
3a23ed
+get_all_domain_stats.opt: get_all_domain_stats.cmx
3a23ed
+	$(OCAMLFIND) ocamlopt \
3a23ed
+	  $(OCAMLOPTPACKAGES) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
3a23ed
+	  ../libvirt/mllibvirt.cmxa -o $@ $<
3a23ed
+
3a23ed
 domain_events: domain_events.cmo
3a23ed
 	$(OCAMLFIND) ocamlc \
3a23ed
 	  $(OCAMLCPACKAGES) $(OCAMLCFLAGS) $(OCAMLCLIBS) \
3a23ed
diff --git a/examples/get_all_domain_stats.ml b/examples/get_all_domain_stats.ml
3a23ed
new file mode 100644
3a23ed
index 0000000..4375639
3a23ed
--- /dev/null
3a23ed
+++ b/examples/get_all_domain_stats.ml
3a23ed
@@ -0,0 +1,65 @@
3a23ed
+(* Example of using Domain.get_all_domain_stats (virConnectGetAllDomainStats).
3a23ed
+ * Usage: get_all_domain_stats
3a23ed
+ * http://libvirt.org/
3a23ed
+ *)
3a23ed
+
3a23ed
+open Printf
3a23ed
+
3a23ed
+module C = Libvirt.Connect
3a23ed
+module D = Libvirt.Domain
3a23ed
+
3a23ed
+let print_stats stats =
3a23ed
+  try
3a23ed
+    Array.iter (
3a23ed
+      fun { D.dom = dom; D.params = params } ->
3a23ed
+        printf "domain %s:\n" (D.get_name dom);
3a23ed
+        Array.iteri (
3a23ed
+          fun i (field, value) ->
3a23ed
+            printf "\t%-20s = " field;
3a23ed
+            (match value with
3a23ed
+             | D.TypedFieldInt32 i -> printf "%ld" i
3a23ed
+             | D.TypedFieldUInt32 i -> printf "%ld" i
3a23ed
+             | D.TypedFieldInt64 i -> printf "%Ld" i
3a23ed
+             | D.TypedFieldUInt64 i -> printf "%Ld" i
3a23ed
+             | D.TypedFieldFloat f -> printf "%g" f
3a23ed
+             | D.TypedFieldBool b -> printf "%b" b
3a23ed
+             | D.TypedFieldString s -> printf "%S" s);
3a23ed
+            printf "\n";
3a23ed
+        ) params;
3a23ed
+        printf "\n"
3a23ed
+    ) stats
3a23ed
+  with
3a23ed
+    Libvirt.Virterror err ->
3a23ed
+      eprintf "error: %s\n" (Libvirt.Virterror.to_string err)
3a23ed
+
3a23ed
+let () =
3a23ed
+  if Array.length Sys.argv <> 1 then (
3a23ed
+    eprintf "error: get_all_domain_stats\n";
3a23ed
+    exit 1
3a23ed
+  );
3a23ed
+
3a23ed
+  let conn = C.connect_readonly () in
3a23ed
+
3a23ed
+  let what_stats = [D.StatsCpuTotal; D.StatsInterface; D.StatsBlock] in
3a23ed
+  let flags = [D.GetAllDomainsStatsActive; D.GetAllDomainsStatsInactive] in
3a23ed
+
3a23ed
+  let quit = ref false in
3a23ed
+
3a23ed
+  while not !quit do
3a23ed
+    let stats = D.get_all_domain_stats conn what_stats flags in
3a23ed
+
3a23ed
+    if stats <> [||] then print_stats stats
3a23ed
+    else (
3a23ed
+      printf "no guests found\n";
3a23ed
+      quit := true
3a23ed
+    );
3a23ed
+    flush stdout;
3a23ed
+
3a23ed
+    (* Run the garbage collector which is a good way to check for
3a23ed
+     * memory corruption errors and reference counting issues in
3a23ed
+     * libvirt.  You shouldn't do this in ordinary programs.
3a23ed
+     *)
3a23ed
+    Gc.compact ();
3a23ed
+
3a23ed
+    if not !quit then Unix.sleep 3
3a23ed
+  done
3a23ed
diff --git a/libvirt/libvirt.ml b/libvirt/libvirt.ml
3a23ed
index 1be023d..ce1878a 100644
3a23ed
--- a/libvirt/libvirt.ml
3a23ed
+++ b/libvirt/libvirt.ml
3a23ed
@@ -392,6 +392,27 @@ struct
3a23ed
     tx_drop : int64;
3a23ed
   }
3a23ed
 
3a23ed
+  type get_all_domain_stats_flag =
3a23ed
+    | GetAllDomainsStatsActive
3a23ed
+    | GetAllDomainsStatsInactive
3a23ed
+    | GetAllDomainsStatsOther
3a23ed
+    | GetAllDomainsStatsPaused
3a23ed
+    | GetAllDomainsStatsPersistent
3a23ed
+    | GetAllDomainsStatsRunning
3a23ed
+    | GetAllDomainsStatsShutoff
3a23ed
+    | GetAllDomainsStatsTransient
3a23ed
+    | GetAllDomainsStatsBacking
3a23ed
+    | GetAllDomainsStatsEnforceStats
3a23ed
+
3a23ed
+  type stats_type =
3a23ed
+    | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
3a23ed
+    | StatsInterface | StatsBlock | StatsPerf
3a23ed
+
3a23ed
+  type 'a domain_stats_record = {
3a23ed
+    dom : 'a t;
3a23ed
+    params : typed_param array;
3a23ed
+  }
3a23ed
+
3a23ed
   (* The maximum size for Domain.memory_peek and Domain.block_peek
3a23ed
    * supported by libvirt.  This may change with different versions
3a23ed
    * of libvirt in the future, hence it's a function.
3a23ed
@@ -446,6 +467,8 @@ struct
3a23ed
   external block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_block_peek_bytecode" "ocaml_libvirt_domain_block_peek_native"
3a23ed
   external memory_peek : [>`W] t -> memory_flag list -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
3a23ed
 
3a23ed
+  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
3a23ed
+
3a23ed
   external const : [>`R] t -> ro t = "%identity"
3a23ed
 
3a23ed
   let get_domains conn flags =
3a23ed
diff --git a/libvirt/libvirt.mli b/libvirt/libvirt.mli
3a23ed
index 8cfcae2..d1b5992 100644
3a23ed
--- a/libvirt/libvirt.mli
3a23ed
+++ b/libvirt/libvirt.mli
3a23ed
@@ -478,6 +478,27 @@ sig
3a23ed
     tx_drop : int64;
3a23ed
   }
3a23ed
 
3a23ed
+  type get_all_domain_stats_flag =
3a23ed
+    | GetAllDomainsStatsActive
3a23ed
+    | GetAllDomainsStatsInactive
3a23ed
+    | GetAllDomainsStatsOther
3a23ed
+    | GetAllDomainsStatsPaused
3a23ed
+    | GetAllDomainsStatsPersistent
3a23ed
+    | GetAllDomainsStatsRunning
3a23ed
+    | GetAllDomainsStatsShutoff
3a23ed
+    | GetAllDomainsStatsTransient
3a23ed
+    | GetAllDomainsStatsBacking
3a23ed
+    | GetAllDomainsStatsEnforceStats
3a23ed
+
3a23ed
+  type stats_type =
3a23ed
+    | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
3a23ed
+    | StatsInterface | StatsBlock | StatsPerf
3a23ed
+
3a23ed
+  type 'a domain_stats_record = {
3a23ed
+    dom : 'a t;
3a23ed
+    params : typed_param array;
3a23ed
+  }
3a23ed
+
3a23ed
   val max_peek : [>`R] t -> int
3a23ed
     (** Maximum size supported by the {!block_peek} and {!memory_peek}
3a23ed
 	functions.  If you want to peek more than this then you must
3a23ed
@@ -615,6 +636,13 @@ sig
3a23ed
 
3a23ed
 	See also {!max_peek}. *)
3a23ed
 
3a23ed
+  external get_all_domain_stats : 'a Connect.t -> stats_type list -> get_all_domain_stats_flag list -> 'a domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
3a23ed
+    (** [get_all_domain_stats conn stats flags] allows you to read
3a23ed
+        all stats across multiple/all domains in a single call.
3a23ed
+
3a23ed
+        See the libvirt documentation for
3a23ed
+        [virConnectGetAllDomainStats]. *)
3a23ed
+
3a23ed
   external const : [>`R] t -> ro t = "%identity"
3a23ed
     (** [const dom] turns a read/write domain handle into a read-only
3a23ed
 	domain handle.  Note that the opposite operation is impossible.
3a23ed
diff --git a/libvirt/libvirt_c_oneoffs.c b/libvirt/libvirt_c_oneoffs.c
3a23ed
index 5d82194..17412f5 100644
3a23ed
--- a/libvirt/libvirt_c_oneoffs.c
3a23ed
+++ b/libvirt/libvirt_c_oneoffs.c
3a23ed
@@ -1,5 +1,5 @@
3a23ed
 /* OCaml bindings for libvirt.
3a23ed
- * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
3a23ed
+ * (C) Copyright 2007-2017 Richard W.M. Jones, Red Hat Inc.
3a23ed
  * http://libvirt.org/
3a23ed
  *
3a23ed
  * This library is free software; you can redistribute it and/or
3a23ed
@@ -184,7 +184,6 @@ ocaml_libvirt_connect_set_keep_alive(value connv,
3a23ed
   CAMLreturn(Val_unit);
3a23ed
 }
3a23ed
 
3a23ed
-
3a23ed
 CAMLprim value
3a23ed
 ocaml_libvirt_domain_get_id (value domv)
3a23ed
 {
3a23ed
@@ -560,6 +559,122 @@ ocaml_libvirt_domain_get_cpu_stats (value domv)
3a23ed
   CAMLreturn (cpustats);
3a23ed
 }
3a23ed
 
3a23ed
+value
3a23ed
+ocaml_libvirt_domain_get_all_domain_stats (value connv,
3a23ed
+                                           value statsv, value flagsv)
3a23ed
+{
3a23ed
+  CAMLparam3 (connv, statsv, flagsv);
3a23ed
+  CAMLlocal5 (rv, dsv, tpv, v, v1);
3a23ed
+  CAMLlocal1 (v2);
3a23ed
+  virConnectPtr conn = Connect_val (connv);
3a23ed
+  virDomainStatsRecordPtr *rstats;
3a23ed
+  unsigned int stats = 0, flags = 0;
3a23ed
+  int i, j, r;
3a23ed
+
3a23ed
+  /* Get stats and flags. */
3a23ed
+  for (; statsv != Val_int (0); statsv = Field (statsv, 1)) {
3a23ed
+    v = Field (statsv, 0);
3a23ed
+    if (v == Val_int (0))
3a23ed
+      stats |= VIR_DOMAIN_STATS_STATE;
3a23ed
+    else if (v == Val_int (1))
3a23ed
+      stats |= VIR_DOMAIN_STATS_CPU_TOTAL;
3a23ed
+    else if (v == Val_int (2))
3a23ed
+      stats |= VIR_DOMAIN_STATS_BALLOON;
3a23ed
+    else if (v == Val_int (3))
3a23ed
+      stats |= VIR_DOMAIN_STATS_VCPU;
3a23ed
+    else if (v == Val_int (4))
3a23ed
+      stats |= VIR_DOMAIN_STATS_INTERFACE;
3a23ed
+    else if (v == Val_int (5))
3a23ed
+      stats |= VIR_DOMAIN_STATS_BLOCK;
3a23ed
+    else if (v == Val_int (6))
3a23ed
+      stats |= VIR_DOMAIN_STATS_PERF;
3a23ed
+  }
3a23ed
+  for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1)) {
3a23ed
+    v = Field (flagsv, 0);
3a23ed
+    if (v == Val_int (0))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE;
3a23ed
+    else if (v == Val_int (1))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE;
3a23ed
+    else if (v == Val_int (2))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER;
3a23ed
+    else if (v == Val_int (3))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED;
3a23ed
+    else if (v == Val_int (4))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT;
3a23ed
+    else if (v == Val_int (5))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING;
3a23ed
+    else if (v == Val_int (6))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF;
3a23ed
+    else if (v == Val_int (7))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT;
3a23ed
+    else if (v == Val_int (8))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING;
3a23ed
+    else if (v == Val_int (9))
3a23ed
+      flags |= VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS;
3a23ed
+  }
3a23ed
+
3a23ed
+  NONBLOCKING (r = virConnectGetAllDomainStats (conn, stats, &rstats, flags));
3a23ed
+  CHECK_ERROR (r == -1, "virConnectGetAllDomainStats");
3a23ed
+
3a23ed
+  rv = caml_alloc (r, 0);       /* domain_stats_record array. */
3a23ed
+  for (i = 0; i < r; ++i) {
3a23ed
+    dsv = caml_alloc (2, 0);    /* domain_stats_record */
3a23ed
+    virDomainRef (rstats[i]->dom);
3a23ed
+    Store_field (dsv, 0, Val_domain (rstats[i]->dom, connv));
3a23ed
+
3a23ed
+    tpv = caml_alloc (rstats[i]->nparams, 0); /* typed_param array */
3a23ed
+    for (j = 0; j < rstats[i]->nparams; ++j) {
3a23ed
+      v2 = caml_alloc (2, 0);   /* typed_param: field name, value */
3a23ed
+      Store_field (v2, 0, caml_copy_string (rstats[i]->params[j].field));
3a23ed
+
3a23ed
+      switch (rstats[i]->params[j].type) {
3a23ed
+      case VIR_TYPED_PARAM_INT:
3a23ed
+        v1 = caml_alloc (1, 0);
3a23ed
+        v = caml_copy_int32 (rstats[i]->params[j].value.i);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_UINT:
3a23ed
+        v1 = caml_alloc (1, 1);
3a23ed
+        v = caml_copy_int32 (rstats[i]->params[j].value.ui);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_LLONG:
3a23ed
+        v1 = caml_alloc (1, 2);
3a23ed
+        v = caml_copy_int64 (rstats[i]->params[j].value.l);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_ULLONG:
3a23ed
+        v1 = caml_alloc (1, 3);
3a23ed
+        v = caml_copy_int64 (rstats[i]->params[j].value.ul);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_DOUBLE:
3a23ed
+        v1 = caml_alloc (1, 4);
3a23ed
+        v = caml_copy_double (rstats[i]->params[j].value.d);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_BOOLEAN:
3a23ed
+        v1 = caml_alloc (1, 5);
3a23ed
+        v = Val_bool (rstats[i]->params[j].value.b);
3a23ed
+        break;
3a23ed
+      case VIR_TYPED_PARAM_STRING:
3a23ed
+        v1 = caml_alloc (1, 6);
3a23ed
+        v = caml_copy_string (rstats[i]->params[j].value.s);
3a23ed
+        break;
3a23ed
+      default:
3a23ed
+        virDomainStatsRecordListFree (rstats);
3a23ed
+        caml_failwith ("virConnectGetAllDomainStats: "
3a23ed
+                       "unknown parameter type returned");
3a23ed
+      }
3a23ed
+      Store_field (v1, 0, v);
3a23ed
+
3a23ed
+      Store_field (v2, 1, v1);
3a23ed
+      Store_field (tpv, j, v2);
3a23ed
+    }
3a23ed
+
3a23ed
+    Store_field (dsv, 1, tpv);
3a23ed
+    Store_field (rv, i, dsv);
3a23ed
+  }
3a23ed
+
3a23ed
+  virDomainStatsRecordListFree (rstats);
3a23ed
+  CAMLreturn (rv);
3a23ed
+}
3a23ed
+
3a23ed
 CAMLprim value
3a23ed
 ocaml_libvirt_domain_migrate_native (value domv, value dconnv, value flagsv, value optdnamev, value opturiv, value optbandwidthv, value unitv)
3a23ed
 {
3a23ed
-- 
3a23ed
2.9.3
3a23ed