Skip to content

Commit c264219

Browse files
authored
CA-404020: Do not fail when removing a non-existing datasource (#6199)
The latest changes in the metrics daemon changes how archived and live metrics are synchronised, and archived sources are created less often. This meant that on some cases, like SR.forget, the operations failed because they could query for existing sources, but the call to remove them failed, because the metrics only exist in live form, not archived one. (what happens with the live one, do they disappear when the SR is forgotten?) Signed-off-by: Pau Ruiz Safont <[email protected]>
2 parents 34b5b63 + e4e20ad commit c264219

File tree

5 files changed

+70
-90
lines changed

5 files changed

+70
-90
lines changed

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

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,9 @@ let rrd_add_ds_unsafe rrd timestamp newds =
621621
rrd.rrd_rras
622622
}
623623

624-
(** Add in a new DS into a pre-existing RRD. Preserves data of all the other archives
625-
and fills the new one full of NaNs. Note that this doesn't fill in the CDP values
626-
correctly at the moment!
624+
(** Add in a new DS into a pre-existing RRD. Preserves data of all the other
625+
archives and fills the new one full of NaNs. Note that this doesn't fill
626+
in the CDP values correctly at the moment!
627627
*)
628628

629629
let rrd_add_ds rrd timestamp newds =
@@ -632,28 +632,27 @@ let rrd_add_ds rrd timestamp newds =
632632
else
633633
rrd_add_ds_unsafe rrd timestamp newds
634634

635-
(** Remove the named DS from an RRD. Removes all of the data associated with it, too *)
635+
(** Remove the named DS from an RRD. Removes all of the data associated with
636+
it, too. THe function is idempotent. *)
636637
let rrd_remove_ds rrd ds_name =
637-
let n =
638-
Utils.array_index ds_name (Array.map (fun ds -> ds.ds_name) rrd.rrd_dss)
639-
in
640-
if n = -1 then
641-
raise (Invalid_data_source ds_name)
642-
else
643-
{
644-
rrd with
645-
rrd_dss= Utils.array_remove n rrd.rrd_dss
646-
; rrd_rras=
647-
Array.map
648-
(fun rra ->
649-
{
650-
rra with
651-
rra_data= Utils.array_remove n rra.rra_data
652-
; rra_cdps= Utils.array_remove n rra.rra_cdps
653-
}
654-
)
655-
rrd.rrd_rras
656-
}
638+
match Utils.find_index (fun ds -> ds.ds_name = ds_name) rrd.rrd_dss with
639+
| None ->
640+
rrd
641+
| Some n ->
642+
{
643+
rrd with
644+
rrd_dss= Utils.array_remove n rrd.rrd_dss
645+
; rrd_rras=
646+
Array.map
647+
(fun rra ->
648+
{
649+
rra with
650+
rra_data= Utils.array_remove n rra.rra_data
651+
; rra_cdps= Utils.array_remove n rra.rra_cdps
652+
}
653+
)
654+
rrd.rrd_rras
655+
}
657656

658657
(** Find the RRA with a particular CF that contains a particular start
659658
time, and also has a minimum pdp_cnt. If it can't find an
@@ -698,18 +697,17 @@ let find_best_rras rrd pdp_interval cf start =
698697
List.filter (contains_time newstarttime) rras
699698

700699
let query_named_ds rrd as_of_time ds_name cf =
701-
let n =
702-
Utils.array_index ds_name (Array.map (fun ds -> ds.ds_name) rrd.rrd_dss)
703-
in
704-
if n = -1 then
705-
raise (Invalid_data_source ds_name)
706-
else
707-
let rras = find_best_rras rrd 0 (Some cf) (Int64.of_float as_of_time) in
708-
match rras with
709-
| [] ->
710-
raise No_RRA_Available
711-
| rra :: _ ->
712-
Fring.peek rra.rra_data.(n) 0
700+
match Utils.find_index (fun ds -> ds.ds_name = ds_name) rrd.rrd_dss with
701+
| None ->
702+
raise (Invalid_data_source ds_name)
703+
| Some n -> (
704+
let rras = find_best_rras rrd 0 (Some cf) (Int64.of_float as_of_time) in
705+
match rras with
706+
| [] ->
707+
raise No_RRA_Available
708+
| rra :: _ ->
709+
Fring.peek rra.rra_data.(n) 0
710+
)
713711

714712
(******************************************************************************)
715713
(* Marshalling/Unmarshalling functions *)
@@ -876,30 +874,26 @@ let from_xml input =
876874

877875
(* Purge any repeated data sources from the RRD *)
878876
let ds_names = ds_names rrd in
879-
let ds_names_set = Utils.setify ds_names in
880-
let ds_name_counts =
881-
List.map
882-
(fun name ->
883-
let x, _ = List.partition (( = ) name) ds_names in
884-
(name, List.length x)
885-
)
886-
ds_names_set
887-
in
888-
let removals_required =
889-
List.filter (fun (_, x) -> x > 1) ds_name_counts
890-
in
891-
List.fold_left
892-
(fun rrd (name, n) ->
893-
(* Remove n-1 lots of this data source *)
894-
let rec inner rrd n =
895-
if n = 1 then
896-
rrd
897-
else
898-
inner (rrd_remove_ds rrd name) (n - 1)
899-
in
900-
inner rrd n
901-
)
902-
rrd removals_required
877+
List.sort_uniq String.compare ds_names
878+
|> List.filter_map (fun name ->
879+
match List.filter (String.equal name) ds_names with
880+
| [] | [_] ->
881+
None
882+
| x ->
883+
Some (name, List.length x)
884+
)
885+
|> List.fold_left
886+
(fun rrd (name, n) ->
887+
(* Remove n-1 lots of this data source *)
888+
let rec inner rrd n =
889+
if n = 1 then
890+
rrd
891+
else
892+
inner (rrd_remove_ds rrd name) (n - 1)
893+
in
894+
inner rrd n
895+
)
896+
rrd
903897
)
904898
input
905899

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

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ end
4747

4848
let isnan x = match classify_float x with FP_nan -> true | _ -> false
4949

50-
let array_index e a =
50+
let find_index f a =
5151
let len = Array.length a in
5252
let rec check i =
5353
if len <= i then
54-
-1
55-
else if a.(i) = e then
56-
i
54+
None
55+
else if f a.(i) then
56+
Some i
5757
else
5858
check (i + 1)
5959
in
@@ -62,23 +62,6 @@ let array_index e a =
6262
let array_remove n a =
6363
Array.append (Array.sub a 0 n) (Array.sub a (n + 1) (Array.length a - n - 1))
6464

65-
let filter_map f list =
66-
let rec inner acc l =
67-
match l with
68-
| [] ->
69-
List.rev acc
70-
| x :: xs ->
71-
let acc = match f x with Some res -> res :: acc | None -> acc in
72-
inner acc xs
73-
in
74-
inner [] list
75-
76-
let rec setify = function
77-
| [] ->
78-
[]
79-
| x :: xs ->
80-
if List.mem x xs then setify xs else x :: setify xs
81-
8265
(** C# and JS representation of special floats are 'NaN' and 'Infinity' which
8366
are different from ocaml's native representation. Caml is fortunately more
8467
forgiving when doing a float_of_string, and can cope with these forms, so

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ let merge_new_dss rrdi dss =
5151
!Rrdd_shared.enable_all_dss || ds.ds_default
5252
in
5353
let default_dss = StringMap.filter should_enable_ds dss in
54-
(* NOTE: It's enough to check if all the default datasources have been added
55-
to the RRD_INFO, because if a non-default one has been enabled at runtime,
56-
it's added to the RRD immediately and we don't need to bother *)
57-
let new_dss =
54+
(* NOTE: Only add enabled dss to the live rrd, ignoring non-default ones.
55+
This is because non-default ones are added to the RRD when they are
56+
enabled. *)
57+
let new_enabled_dss =
5858
StringMap.filter
5959
(fun ds_name _ -> not (StringMap.mem ds_name rrdi.dss))
6060
default_dss
@@ -73,7 +73,7 @@ let merge_new_dss rrdi dss =
7373
rrd_add_ds_unsafe rrd timestamp
7474
(Rrd.ds_create ds.ds_name ds.Ds.ds_type ~mrhb:300.0 Rrd.VT_Unknown)
7575
)
76-
new_dss rrdi.rrd
76+
new_enabled_dss rrdi.rrd
7777
)
7878

7979
module OwnerMap = Map.Make (struct

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ let send_host_rrd_to_master master_address =
347347
let fail_missing name = raise (Rrdd_error (Datasource_missing name))
348348

349349
(** {add_ds rrdi ds_name} creates a new time series (rrd) in {rrdi} with the
350-
name {ds_name}. The operation fails if rrdi does not contain any live
350+
name {ds_name}. The operation fails if rrdi does not contain any
351351
datasource with the name {ds_name} *)
352352
let add_ds ~rrdi ~ds_name =
353353
match Rrd.StringMap.find_opt ds_name rrdi.dss with

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,13 @@ let mutex = Mutex.create ()
7777

7878
type rrd_info = {
7979
rrd: Rrd.rrd
80+
(** Contains the live metrics, i.e. The datasources that are enabled
81+
and being collected .*)
8082
; mutable dss: (float * Ds.ds) Rrd.StringMap.t
81-
(* Important: this must contain the entire list of datasources associated
82-
with the RRD, even the ones disabled by default, as rrd_add_ds calls
83-
can enable DSs at runtime *)
83+
(** Important: this must contain the entire list of datasources
84+
associated with the RRD, even the ones disabled by default, because
85+
functions like rrd_add_ds or rrd_remove_ds expect disabled
86+
datasources to be present. e.g. to enable DSs at runtime *)
8487
; mutable domid: int
8588
}
8689

0 commit comments

Comments
 (0)