Skip to content

Commit 4f3f08f

Browse files
authored
Improve the scan comparison logic (#6168)
For the scan retry, previously we were comparing the entire vdi data structure from the database using the (<>) operator. This is a bit wasteful and not very stable. Instead let us just compare the vdi refs, since the race here comes from `VDI.db_{introduce,forget}`, which would only add/remove vdis from the db, but not change its actual data structure. Also add a bit more logging when retrying, since this should not happen very often.
2 parents 309e7f6 + 3e70a6d commit 4f3f08f

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

ocaml/xapi/xapi_sr.ml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,15 +778,34 @@ let scan ~__context ~sr =
778778
Db.VDI.get_records_where ~__context
779779
~expr:(Eq (Field "SR", Literal sr'))
780780
in
781+
(* It is sufficient to just compare the refs in two db_vdis, as this
782+
is what update_vdis uses to determine what to delete *)
783+
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+
= []
787+
in
781788
let db_vdis_before = find_vdis () in
782789
let vs, sr_info =
783790
C.SR.scan2 (Ref.string_of task)
784791
(Storage_interface.Sr.of_string sr_uuid)
785792
in
786793
let db_vdis_after = find_vdis () in
787-
if limit > 0 && db_vdis_after <> db_vdis_before then
794+
if limit > 0 && not (vdis_ref_equal db_vdis_before db_vdis_after)
795+
then (
796+
debug
797+
"%s detected db change while scanning, before scan vdis %s, \
798+
after scan vdis %s, retry limit left %d"
799+
__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+
)
806+
limit ;
788807
(scan_rec [@tailcall]) (limit - 1)
789-
else if limit = 0 then
808+
) else if limit = 0 then
790809
raise
791810
(Api_errors.Server_error
792811
(Api_errors.internal_error, ["SR.scan retry limit exceeded"])

0 commit comments

Comments
 (0)