Skip to content

Commit 8f7804f

Browse files
committed
Improve the scan comparison logic
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. Signed-off-by: Vincent Liu <[email protected]>
1 parent d8baca7 commit 8f7804f

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

ocaml/xapi/xapi_sr.ml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,15 +778,33 @@ 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) then (
795+
debug
796+
"%s detected db change while scanning, before scan vdis %s, \
797+
after scan vdis %s, retry limit left %d"
798+
__FUNCTION__
799+
(List.map (fun (_, v) -> v.vDI_uuid) db_vdis_before
800+
|> String.concat ","
801+
)
802+
(List.map (fun (_, v) -> v.vDI_uuid) db_vdis_after
803+
|> String.concat ","
804+
)
805+
limit ;
788806
(scan_rec [@tailcall]) (limit - 1)
789-
else if limit = 0 then
807+
) else if limit = 0 then
790808
raise
791809
(Api_errors.Server_error
792810
(Api_errors.internal_error, ["SR.scan retry limit exceeded"])

0 commit comments

Comments
 (0)