From eebf1d18832f690b284e652363d368061b548ab5 Mon Sep 17 00:00:00 2001 From: David Scott Date: Thu, 28 Oct 2010 16:51:04 +0100 Subject: [PATCH] CA-46955: make code robust to parallel deletions of VBDs In general we should be very careful in code like this not to expect the configuration of "other VMs" to remain static while we run. In this case a parallel thread deleted a VBD which it "owned" and this cross-talk killed this thread. Signed-off-by: David Scott --- ocaml/xapi/xapi_vbd_helpers.ml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ocaml/xapi/xapi_vbd_helpers.ml b/ocaml/xapi/xapi_vbd_helpers.ml index 0488d032..e778f3a1 100644 --- a/ocaml/xapi/xapi_vbd_helpers.ml +++ b/ocaml/xapi/xapi_vbd_helpers.ml @@ -148,9 +148,10 @@ let valid_operations ~expensive_sharing_checks ~__context record _ref' : table = if not record.Db_actions.vBD_currently_attached && expensive_sharing_checks then begin (* Perform the sharing checks *) - (* Careful to not count this VBD *) - let vbds = List.filter (fun vbd -> vbd <> _ref') vdi_record.Db_actions.vDI_VBDs in - let vbd_records = List.map (fun self -> Db.VBD.get_record_internal ~__context ~self) vbds in + (* Careful to not count this VBD and be careful to be robust to parallel deletions of unrelated VBDs *) + let vbd_records = + let vbds = List.filter (fun vbd -> vbd <> _ref') vdi_record.Db_actions.vDI_VBDs in + List.concat (List.map (fun self -> try [ Db.VBD.get_record_internal ~__context ~self ] with _ -> []) vbds) in (* Any VBD with a current_operation is said to conflict EXCEPT if I'm a control_domain (running pygrub) and the VBD is being 'attach'ed for booting *) let any p xs = try ignore(List.find p xs); true with Not_found -> false in -- 2.39.5