Skip to content

Commit d5b5e3c

Browse files
committed
CA-178645: serialize SM plugin registration
which seems necessary since the SMAPIv3 refactoring. Signed-off-by: Zheng Li <[email protected]>
1 parent ed14c0f commit d5b5e3c

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

ocaml/xapi/xapi_sm.ml

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
open Listext
2222
open Xstringext
23+
open Threadext
2324
open Fun
2425

2526
(* We treat versions as '.'-separated integer lists under the usual
@@ -87,27 +88,47 @@ let update_from_query_result ~__context (self, r) query_result =
8788

8889
let is_v1 x = version_of_string x < [ 2; 0 ]
8990

91+
let _serialize_reg =
92+
let lock = Mutex.create () in
93+
let holder = ref None in
94+
begin fun f ->
95+
match !holder with
96+
| Some t when t = Thread.self () ->
97+
(* inside a nested layer where the lock is held by myself *)
98+
f ()
99+
| _ ->
100+
Mutex.execute lock begin fun () ->
101+
holder := Some (Thread.self ());
102+
Pervasiveext.finally f (fun () -> holder := None)
103+
end
104+
end
105+
90106
let unregister_plugin ~__context query_result =
91-
let open Storage_interface in
92-
let driver = String.lowercase query_result.driver in
93-
if is_v1 query_result.required_api_version then begin
94-
info "Not unregistering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version;
95-
end else begin
96-
let existing = List.map (fun (rf, rc) -> rc.API.sM_type, (rf, rc)) (Db.SM.get_all_records ~__context) in
97-
if List.mem_assoc driver existing then begin
98-
info "Unregistering SM plugin %s (version %s)" driver query_result.version;
99-
try
100-
Db.SM.destroy ~__context ~self:(fst (List.assoc driver existing))
101-
with _ -> ()
102-
end
107+
_serialize_reg begin fun () ->
108+
let open Storage_interface in
109+
let driver = String.lowercase query_result.driver in
110+
if is_v1 query_result.required_api_version then begin
111+
info "Not unregistering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version;
112+
end else
113+
List.iter
114+
(fun (rf, rc) ->
115+
if rc.API.sM_type = driver then
116+
try
117+
info "Unregistering SM plugin %s (version %s)" driver query_result.version;
118+
Db.SM.destroy ~__context ~self:rf
119+
with e ->
120+
warn "Ignore unregistering SM plugin failure: %s" (Printexc.to_string e))
121+
(Db.SM.get_all_records ~__context)
103122
end
104123

105124
let register_plugin ~__context query_result =
106-
let open Storage_interface in
107-
let driver = String.lowercase query_result.driver in
108-
if is_v1 query_result.required_api_version then begin
109-
info "Not registering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version;
110-
end else begin
111-
unregister_plugin ~__context query_result;
112-
create_from_query_result ~__context query_result
125+
_serialize_reg begin fun () ->
126+
let open Storage_interface in
127+
let driver = String.lowercase query_result.driver in
128+
if is_v1 query_result.required_api_version then begin
129+
info "Not registering SM plugin %s (required_api_version %s < 2.0)" driver query_result.required_api_version;
130+
end else begin
131+
unregister_plugin ~__context query_result;
132+
create_from_query_result ~__context query_result
133+
end
113134
end

0 commit comments

Comments
 (0)