Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IH-543: Add IPMI DCMI based power reading rrdd plugin #5561

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ install: build doc sdk doc-json
install -D -m 755 _build/install/default/bin/xcp-rrdd-iostat $(DESTDIR)$(LIBEXECDIR)/xcp-rrdd-plugins/xcp-rrdd-iostat
install -D -m 755 _build/install/default/bin/xcp-rrdd-squeezed $(DESTDIR)$(LIBEXECDIR)/xcp-rrdd-plugins/xcp-rrdd-squeezed
install -D -m 755 _build/install/default/bin/xcp-rrdd-xenpm $(DESTDIR)$(LIBEXECDIR)/xcp-rrdd-plugins/xcp-rrdd-xenpm
install -D -m 755 _build/install/default/bin/xcp-rrdd-dcmi $(DESTDIR)$(LIBEXECDIR)/xcp-rrdd-plugins/xcp-rrdd-dcmi
install -D -m 644 ocaml/xcp-rrdd/bugtool-plugin/rrdd-plugins.xml $(DESTDIR)$(ETCXENDIR)/bugtool/xcp-rrdd-plugins.xml
install -D -m 644 ocaml/xcp-rrdd/bugtool-plugin/rrdd-plugins/stuff.xml $(DESTDIR)$(ETCXENDIR)/bugtool/xcp-rrdd-plugins/stuff.xml
install -D -m 755 ocaml/xcp-rrdd/bin/rrdp-scripts/sysconfig-rrdd-plugins $(DESTDIR)/etc/sysconfig/xcp-rrdd-plugins
Expand Down
16 changes: 16 additions & 0 deletions ocaml/xcp-rrdd/bin/rrdp-dcmi/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(executable
(modes exe)
(name rrdp_dcmi)
(package rrdd-plugins)
(public_name xcp-rrdd-dcmi)
(libraries
dune-build-info
rrdd-plugin
rrdd-plugins.libs
xapi-idl.rrd
xapi-log
xapi-rrd
astring
)
)

80 changes: 80 additions & 0 deletions ocaml/xcp-rrdd/bin/rrdp-dcmi/rrdp_dcmi.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(*
* Copyright (c) 2024 Cloud Software Group, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)

(** Read power measurements from IPMI DCMI where available.
There is also IPMI SDR entity 21 that returns the same information (power consumption in watts),
but isn't always available, and seems to be slower to read, especially when missing.
*)

open Rrdd_plugin

module Process = Process (struct let name = "xcp-rrdd-dcmi" end)

open Process

let ipmitool_bin = "/usr/bin/ipmitool"

let ipmitool args =
(* we connect to the local /dev/ipmi0 if available to read measurements from local BMC *)
ipmitool_bin :: "-I" :: "open" :: args |> String.concat " "

let discover () =
Utils.exec_cmd
(module Process.D)
~cmdstring:(ipmitool ["dcmi"; "discover"])
edwintorok marked this conversation as resolved.
Show resolved Hide resolved
~f:(fun line ->
(* this code runs once on startup, logging all the output here will be useful for debugging *)
D.debug "DCMI discover: %s" line ;
edwintorok marked this conversation as resolved.
Show resolved Hide resolved
if String.trim line = "Power management available" then
Some ()
else
None
)

let get_dcmi_power_reading () =
Utils.exec_cmd
(module Process.D)
~cmdstring:(ipmitool ["dcmi"; "power"; "reading"])
~f:(fun line ->
(* example line: ' Instantaneous power reading: 34 Watts' *)
try
Scanf.sscanf line " Instantaneous power reading : %f Watts" Option.some
lindig marked this conversation as resolved.
Show resolved Hide resolved
with Scanf.Scan_failure _ | End_of_file -> None
)

let gen_dcmi_power_reading value =
( Rrd.Host
, Ds.ds_make ~name:"DCMI-power-reading"
~description:"Host power usage reported by IPMI DCMI"
~value:(Rrd.VT_Float value) ~ty:Rrd.Gauge ~default:true ~units:"W"
~min:Float.min_float ~max:65534. ()
edwintorok marked this conversation as resolved.
Show resolved Hide resolved
)

let generate_dss () =
match get_dcmi_power_reading () with
| watts :: _ ->
[gen_dcmi_power_reading watts]
| _ ->
edwintorok marked this conversation as resolved.
Show resolved Hide resolved
[]

let _ =
initialise () ;
match discover () with
| [] ->
D.info "IPMI DCMI power reading is unavailable" ;
exit 1
| _ ->
D.info "IPMI DCMI power reading is available" ;
main_loop ~neg_shift:0.5 ~target:(Reporter.Local 1)
~protocol:Rrd_interface.V2 ~dss_f:generate_dss
Empty file.
2 changes: 1 addition & 1 deletion ocaml/xcp-rrdd/bin/rrdp-scripts/sysconfig-rrdd-plugins
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PLUGINS="xcp-rrdd-iostat xcp-rrdd-squeezed xcp-rrdd-xenpm"
PLUGINS="xcp-rrdd-iostat xcp-rrdd-squeezed xcp-rrdd-xenpm xcp-rrdd-dcmi"
Loading