Skip to content

Commit c207cb4

Browse files
committed
Check that there are no changes during SR.scan
Currently, we are only checking that no VDIs have been removed during the SR scan performed by the SM plugin. However, there are situations where a VDI has been added, and if this VDI is not present in the list obtained from SR.scan, it will be forgotten. The checks only prevent this in the case where the VDI was added during the scan. There is still a TOCTOU situation if the issue happens after the scan, and there is room for that. Signed-off-by: Guillaume <[email protected]>
1 parent ec7baa3 commit c207cb4

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

ocaml/xapi/xapi_sr.ml

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ open Xapi_database.Db_filter_types
2929
open API
3030
open Client
3131

32+
module RefSet = Set.Make (struct
33+
type t = [`VDI] Ref.t
34+
35+
let compare = Ref.compare
36+
end)
37+
3238
(* internal api *)
3339

3440
module D = Debug.Make (struct let name = "xapi_sr" end)
@@ -778,12 +784,19 @@ let scan ~__context ~sr =
778784
Db.VDI.get_records_where ~__context
779785
~expr:(Eq (Field "SR", Literal sr'))
780786
in
787+
let string_of_l lst =
788+
List.map (fun (_, v) -> v.vDI_uuid) lst |> String.concat ","
789+
in
781790
(* It is sufficient to just compare the refs in two db_vdis, as this
782791
is what update_vdis uses to determine what to delete *)
783792
let vdis_ref_equal db_vdi1 db_vdi2 =
784-
Listext.List.set_difference (List.map fst db_vdi1)
785-
(List.map fst db_vdi2)
786-
= []
793+
let refs1 = RefSet.of_list (List.map fst db_vdi1) in
794+
let refs2 = RefSet.of_list (List.map fst db_vdi2) in
795+
(* VDIs that are in db_vdi1 but not in db_vdi2 *)
796+
let vdis_removed = RefSet.diff refs1 refs2 in
797+
(* VDIs that are in not in db_vdi1 but db_vdi2 *)
798+
let vdis_added = RefSet.diff refs2 refs1 in
799+
RefSet.is_empty vdis_removed && RefSet.is_empty vdis_added
787800
in
788801
let db_vdis_before = find_vdis () in
789802
let vs, sr_info =
@@ -797,12 +810,8 @@ let scan ~__context ~sr =
797810
"%s detected db change while scanning, before scan vdis %s, \
798811
after scan vdis %s, retry limit left %d"
799812
__FUNCTION__
800-
(List.map (fun (_, v) -> v.vDI_uuid) db_vdis_before
801-
|> String.concat ","
802-
)
803-
(List.map (fun (_, v) -> v.vDI_uuid) db_vdis_after
804-
|> String.concat ","
805-
)
813+
(string_of_l db_vdis_before)
814+
(string_of_l db_vdis_after)
806815
limit ;
807816
(scan_rec [@tailcall]) (limit - 1)
808817
) else if limit = 0 then

0 commit comments

Comments
 (0)