]> xenbits.xensource.com Git - xcp/xen-api.git/commitdiff
CA-46955: make code robust to parallel deletions of VBDs
authorDavid Scott <dave.scott@eu.citrix.com>
Thu, 28 Oct 2010 15:51:04 +0000 (16:51 +0100)
committerDavid Scott <dave.scott@eu.citrix.com>
Thu, 28 Oct 2010 15:51:04 +0000 (16:51 +0100)
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 <dave.scott@eu.citrix.com>
ocaml/xapi/xapi_vbd_helpers.ml

index 0488d032aff64395f1c7f62b07f2f0a0a784765d..e778f3a14b85210342a2f08435d7b9d9edcaa45d 100644 (file)
@@ -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