Skip to content

Commit 8e3cb5f

Browse files
authored
CA-400124 - rrd: Serialize transform parameter for data sources (#6043)
Previously, the transform function was not serialized in the plugin-server protocol (it was only used in xcp_rrdd itself, not in plugins). This issue was revealed by the previous work around splitting cpu metrics into a separate plugin. Instead of allowing arbitrary functions (which would be difficult to serialize), for 'fun x' offer just two options: * Inverse (1.0 - x), and * Identity (x) Default (if the parameter is not provided, either in OCaml or JSON), is Identity.
2 parents c8232df + fe79b0f commit 8e3cb5f

File tree

11 files changed

+55
-26
lines changed

11 files changed

+55
-26
lines changed

ocaml/libs/xapi-rrd/lib/rrd.ml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ exception No_RRA_Available
2222

2323
exception Invalid_data_source of string
2424

25+
(** Inverse is (fun x -> 1.0 - x) *)
26+
type ds_transform_function = Inverse | Identity
27+
28+
let apply_transform_function f x =
29+
match f with Inverse -> 1.0 -. x | Identity -> x
30+
2531
type ds_owner = VM of string | Host | SR of string
2632

2733
(** Data source types - see ds datatype *)
@@ -84,6 +90,12 @@ let ds_value_to_string = function
8490
| _ ->
8591
"0.0"
8692

93+
let ds_transform_function_to_string = function
94+
| Inverse ->
95+
"inverse"
96+
| Identity ->
97+
"identity"
98+
8799
(** The CDP preparation scratch area.
88100
The 'value' field should be accumulated in such a way that it always
89101
contains the value that will eventually be the CDP. This means that
@@ -417,7 +429,7 @@ let ds_update rrd timestamp values transforms new_domid =
417429
)
418430
in
419431
(* Apply the transform after the raw value has been calculated *)
420-
let raw = transforms.(i) raw in
432+
let raw = apply_transform_function transforms.(i) raw in
421433
(* Make sure the values are not out of bounds after all the processing *)
422434
if raw < ds.ds_min || raw > ds.ds_max then
423435
nan
@@ -450,7 +462,7 @@ let ds_update_named rrd timestamp ~new_domid valuesandtransforms =
450462
valuesandtransforms |> List.to_seq |> StringMap.of_seq
451463
in
452464
let get_value_and_transform {ds_name; _} =
453-
Option.value ~default:(VT_Unknown, Fun.id)
465+
Option.value ~default:(VT_Unknown, Identity)
454466
(StringMap.find_opt ds_name valuesandtransforms)
455467
in
456468
let ds_values, ds_transforms =
@@ -519,7 +531,7 @@ let rrd_create dss rras timestep inittime =
519531
}
520532
in
521533
let values = Array.map (fun ds -> ds.ds_last) dss in
522-
let transforms = Array.make (Array.length values) (fun x -> x) in
534+
let transforms = Array.make (Array.length values) Identity in
523535
ds_update rrd inittime values transforms true ;
524536
rrd
525537

ocaml/libs/xapi-rrd/lib_test/crowbar_tests.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ let rrd =
8181
List.iteri
8282
(fun i v ->
8383
let t = 5. *. (init_time +. float_of_int i) in
84-
ds_update rrd t [|VT_Int64 v|] [|Fun.id|] (i = 0)
84+
ds_update rrd t [|VT_Int64 v|] [|Identity|] (i = 0)
8585
)
8686
values ;
8787
rrd

ocaml/libs/xapi-rrd/lib_test/unit_tests.ml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ let gauge_rrd =
131131
let rrd =
132132
rrd_create [|ds; ds2; ds3; ds4|] [|rra; rra2; rra3; rra4|] 1L 1000000000.0
133133
in
134-
let id x = x in
134+
let id = Identity in
135135
for i = 1 to 100000 do
136136
let t = 1000000000.0 +. (0.7 *. float_of_int i) in
137137
let v1 = VT_Float (0.5 +. (0.5 *. sin (t /. 10.0))) in
@@ -159,7 +159,7 @@ let _deserialize_verify_rrd =
159159

160160
let rrd = rrd_create [|ds|] [|rra1; rra2; rra3|] 5L init_time in
161161

162-
let id x = x in
162+
let id = Identity in
163163
for i = 1 to 100 do
164164
let t = init_time +. float_of_int i in
165165
let t64 = Int64.of_float t in
@@ -178,7 +178,7 @@ let ca_322008_rrd =
178178

179179
let rrd = rrd_create [|ds|] [|rra1; rra2; rra3|] 5L init_time in
180180

181-
let id x = x in
181+
let id = Identity in
182182

183183
for i = 1 to 100000 do
184184
let t = init_time +. float_of_int i in
@@ -198,7 +198,7 @@ let ca_329043_rrd_1 =
198198

199199
let rrd = rrd_create [|ds|] [|rra1; rra2; rra3|] 5L init_time in
200200

201-
let id x = x in
201+
let id = Identity in
202202

203203
let time_value_of_i i =
204204
let t = 5. *. (init_time +. float_of_int i) in
@@ -228,7 +228,7 @@ let create_rrd ?(rows = 2) values min max =
228228
rrd_create [|ds1; ds2; ds3|] [|rra1; rra2; rra3; rra4|] 5L init_time
229229
in
230230

231-
let id x = x in
231+
let id = Identity in
232232

233233
List.iteri
234234
(fun i v ->

ocaml/xapi-idl/rrd/ds.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ type ds = {
2525
; ds_min: float
2626
; ds_max: float
2727
; ds_units: string
28-
; ds_pdp_transform_function: float -> float
28+
; ds_pdp_transform_function: Rrd.ds_transform_function
2929
}
3030

3131
let ds_make ~name ~description ~value ~ty ~default ~units ?(min = neg_infinity)
32-
?(max = infinity) ?(transform = fun x -> x) () =
32+
?(max = infinity) ?(transform = Rrd.Identity) () =
3333
{
3434
ds_name= name
3535
; ds_description= description

ocaml/xcp-rrdd/bin/rrdd/rrdd_monitor.ml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,6 @@ module OwnerMap = Map.Make (struct
7777
String.compare a b
7878
end)
7979

80-
let owner_to_string () = function
81-
| Host ->
82-
"host"
83-
| VM uuid ->
84-
"VM " ^ uuid
85-
| SR uuid ->
86-
"SR " ^ uuid
87-
8880
(** Updates all of the hosts rrds. We are passed a list of uuids that is used as
8981
the primary source for which VMs are resident on us. When a new uuid turns
9082
up that we haven't got an RRD for in our hashtbl, we create a new one. When

ocaml/xcp-rrdd/bin/rrdp-cpu/rrdp_cpu.ml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,7 @@ let dss_pcpus xc =
142142
~description:("Physical cpu usage for cpu " ^ string_of_int i)
143143
~value:(Rrd.VT_Float (Int64.to_float v /. 1.0e9))
144144
~min:0.0 ~max:1.0 ~ty:Rrd.Derive ~default:true
145-
~transform:(fun x -> 1.0 -. x)
146-
()
145+
~transform:Rrd.Inverse ()
147146
)
148147
:: acc
149148
, i + 1
@@ -158,9 +157,7 @@ let dss_pcpus xc =
158157
, Ds.ds_make ~name:"cpu_avg" ~units:"(fraction)"
159158
~description:"Average physical cpu usage"
160159
~value:(Rrd.VT_Float (avg_array /. 1.0e9))
161-
~min:0.0 ~max:1.0 ~ty:Rrd.Derive ~default:true
162-
~transform:(fun x -> 1.0 -. x)
163-
()
160+
~min:0.0 ~max:1.0 ~ty:Rrd.Derive ~default:true ~transform:Rrd.Inverse ()
164161
)
165162
in
166163
avgcpu_ds :: dss

ocaml/xcp-rrdd/lib/transport/base/rrd_json.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ let ds_owner x =
4444
string "sr %s" sr
4545
)
4646

47+
let ds_transform x =
48+
match x with
49+
| Rrd.Identity ->
50+
[]
51+
(* This is the default when transform is absent, and not including it
52+
makes the file smaller *)
53+
| Rrd.Inverse ->
54+
[("transform", string "inverse")]
55+
4756
let bool b = string "%b" b (* Should use `Bool b *)
4857

4958
let float x = string "%.2f" x
@@ -63,6 +72,7 @@ let ds_to_json (owner, ds) =
6372
[
6473
description ds.Ds.ds_description
6574
; [ds_owner owner]
75+
; ds_transform ds.Ds.ds_pdp_transform_function
6676
; ds_value ds.Ds.ds_value
6777
; [ds_type ds.Ds.ds_type]
6878
; [

ocaml/xcp-rrdd/lib/transport/base/rrd_protocol_v2.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,13 @@ let uninitialised_ds_of_rpc ((name, rpc) : string * Rpc.t) :
193193
let default =
194194
bool_of_string (Rrd_rpc.assoc_opt ~key:"default" ~default:"false" kvs)
195195
in
196+
let transform =
197+
Rrd_rpc.transform_of_string
198+
(Rrd_rpc.assoc_opt ~key:"transform" ~default:"identity" kvs)
199+
in
196200
let ds =
197-
Ds.ds_make ~name ~description ~units ~ty ~value ~min ~max ~default ()
201+
Ds.ds_make ~name ~description ~units ~ty ~value ~min ~max ~default
202+
~transform ()
198203
in
199204
(owner, ds)
200205

ocaml/xcp-rrdd/lib/transport/base/rrd_rpc.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,13 @@ let owner_of_string (s : string) : Rrd.ds_owner =
5353
Rrd.SR uuid
5454
| _ ->
5555
raise Rrd_protocol.Invalid_payload
56+
57+
(* Converts a string to value of ds_transform_function type. *)
58+
let transform_of_string (s : string) : Rrd.ds_transform_function =
59+
match s with
60+
| "inverse" ->
61+
Rrd.Inverse
62+
| "identity" ->
63+
Rrd.Identity
64+
| _ ->
65+
raise Rrd_protocol.Invalid_payload

ocaml/xcp-rrdd/lib/transport/base/rrd_rpc.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ val assoc_opt : key:string -> default:string -> (string * Rpc.t) list -> string
2121
val ds_ty_of_string : string -> Rrd.ds_type
2222

2323
val owner_of_string : string -> Rrd.ds_owner
24+
25+
val transform_of_string : string -> Rrd.ds_transform_function

0 commit comments

Comments
 (0)