From 1b96133f8d93f5cdab2231f68be08e4e12c4f17e Mon Sep 17 00:00:00 2001 From: Lunfan Zhang Date: Tue, 5 Dec 2023 04:46:49 +0000 Subject: [PATCH] CP-44531 Toolstack: Add Dom0 CPU usage, total and free memory into rrdd Signed-off-by: Lunfan Zhang --- ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml | 147 ++++++++++++++++++---------- 1 file changed, 95 insertions(+), 52 deletions(-) diff --git a/ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml b/ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml index ad1876f01eb..e9830eecd22 100644 --- a/ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml +++ b/ocaml/xcp-rrdd/bin/rrdd/xcp_rrdd.ml @@ -237,57 +237,68 @@ let dss_vcpus xc doms = in (* Runstate info is per-domain rather than per-vcpu *) let dss = - try - let ri = Xenctrl.domain_get_runstate_info xc domid in - ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_fullrun" ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time0 /. 1.0e9)) - ~description:"Fraction of time that all VCPUs are running" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_full_contention" ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time1 /. 1.0e9)) - ~description: - "Fraction of time that all VCPUs are runnable (i.e., \ - waiting for CPU)" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_concurrency_hazard" - ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time2 /. 1.0e9)) - ~description: - "Fraction of time that some VCPUs are running and some are \ - runnable" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_blocked" ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time3 /. 1.0e9)) - ~description: - "Fraction of time that all VCPUs are blocked or offline" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_partial_run" ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time4 /. 1.0e9)) - ~description: - "Fraction of time that some VCPUs are running, and some are \ - blocked" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: ( Rrd.VM uuid - , Ds.ds_make ~name:"runstate_partial_contention" - ~units:"(fraction)" - ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time5 /. 1.0e9)) - ~description: - "Fraction of time that some VCPUs are runnable and some are \ - blocked" - ~ty:Rrd.Derive ~default:false ~min:0.0 () - ) - :: dss - with _ -> dss + let dom_cpu_time = + Int64.( + to_float @@ logand dom.Xenctrl.cpu_time xen_flag_complement + ) + in + let dom_cpu_time = dom_cpu_time /. 1.0e9 in + try + let ri = Xenctrl.domain_get_runstate_info xc domid in + ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_fullrun" ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time0 /. 1.0e9)) + ~description:"Fraction of time that all VCPUs are running" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_full_contention" ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time1 /. 1.0e9)) + ~description: + "Fraction of time that all VCPUs are runnable (i.e., \ + waiting for CPU)" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_concurrency_hazard" + ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time2 /. 1.0e9)) + ~description: + "Fraction of time that some VCPUs are running and some are \ + runnable" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_blocked" ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time3 /. 1.0e9)) + ~description: + "Fraction of time that all VCPUs are blocked or offline" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_partial_run" ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time4 /. 1.0e9)) + ~description: + "Fraction of time that some VCPUs are running, and some are \ + blocked" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:"runstate_partial_contention" + ~units:"(fraction)" + ~value:(Rrd.VT_Float (Int64.to_float ri.Xenctrl.time5 /. 1.0e9)) + ~description: + "Fraction of time that some VCPUs are runnable and some are \ + blocked" + ~ty:Rrd.Derive ~default:false ~min:0.0 () + ) + :: ( Rrd.VM uuid + , Ds.ds_make ~name:(Printf.sprintf "cpu_usage") ~units:"(fraction)" + ~description:(Printf.sprintf "domain: %d CPU usage" domid) + ~value:(Rrd.VT_Float dom_cpu_time) ~ty:Rrd.Derive ~default:true + ~min:0.0 ~max:1.0 () + ) :: dss + with _ -> dss in try cpus 0 dss with _ -> dss ) @@ -545,6 +556,30 @@ let bytes_per_mem_vm = 1024 let mem_vm_writer_pages = ((max_supported_vms * bytes_per_mem_vm) + 4095) / 4096 +let read_mem_available () = + let meminfo_file = "/proc/meminfo" in + let rec read_lines ic = + try + let line = input_line ic in + if String.contains line ':' then begin + let parts = String.split_on_char ':' line in + match parts with + | key :: value :: _ when String.trim key = "MemAvailable" -> + (* Extract the value, remove the 'kB' suffix, trim spaces, and convert to Int64 *) + Scanf.sscanf value " %Ld kB" (fun v -> v) + | _ -> read_lines ic + end else read_lines ic + with + | End_of_file -> close_in ic; Int64.zero + in + try + let ic = open_in meminfo_file in + let value = read_lines ic in + close_in ic; + value + with + | Sys_error _ -> Int64.zero + let dss_mem_vms doms = List.fold_left (fun acc (dom, uuid, domid) -> @@ -580,7 +615,15 @@ let dss_mem_vms doms = in let other_ds = if domid = 0 then - None + let free_mem = read_mem_available() + in + Some + ( Rrd.VM uuid + , Ds.ds_make ~name:"memory_internal_free" ~units:"KiB" + ~description:"Dom 0 current free memory to use" + ~value:(Rrd.VT_Int64 free_mem) ~ty:Rrd.Gauge ~min:0.0 + ~default:true () + ) else try let mem_free =