@@ -39,6 +39,35 @@ let info fmt = log Core.Syslog.Level.INFO fmt
3939let warn fmt = log Core.Syslog.Level. WARNING fmt
4040let error fmt = log Core.Syslog.Level. ERR fmt
4141
42+ module RRD = struct
43+ open Protocol_async
44+
45+ let (>>|=) m f = m >> = function
46+ | `Ok x -> f x
47+ | `Error y ->
48+ let b = Buffer. create 16 in
49+ let fmt = Format. formatter_of_buffer b in
50+ Client. pp_error fmt y;
51+ Format. pp_print_flush fmt () ;
52+ raise (Failure (Buffer. contents b))
53+
54+ let switch_rpc queue_name string_of_call response_of_string call =
55+ Client. connect ~switch: queue_name () >> |= fun t ->
56+ Client. rpc ~t ~queue: queue_name ~body: (string_of_call call) () >> |= fun s ->
57+ return (response_of_string s)
58+
59+ let json_switch_rpc queue_name = switch_rpc queue_name Jsonrpc. string_of_call Jsonrpc. response_of_string
60+
61+ module Client = Rrd_interface. ClientM (struct
62+ type 'a t = 'a Deferred .t
63+ let return = return
64+ let bind = Deferred. bind
65+ let fail = raise
66+ let rpc call = json_switch_rpc ! Rrd_interface. queue_name call
67+ end )
68+
69+ end
70+
4271let _nonpersistent = " NONPERSISTENT"
4372let _clone_on_boot_key = " clone-on-boot"
4473
@@ -129,16 +158,21 @@ let script root_dir name kind script = match kind with
129158| `Datapath datapath -> Filename. (concat (concat (concat (dirname root_dir) " datapath" ) datapath) script)
130159
131160module Attached_SRs = struct
132- let sr_table : string String.Table.t ref = ref (String.Table. create () )
161+ type state = {
162+ sr : string ;
163+ uids : string list ;
164+ } with sexp
165+
166+ let sr_table : state String.Table.t ref = ref (String.Table. create () )
133167 let state_path = ref None
134168
135- let add smapiv2 plugin =
136- Hashtbl. replace ! sr_table smapiv2 plugin;
169+ let add smapiv2 plugin uids =
170+ Hashtbl. replace ! sr_table smapiv2 { sr = plugin; uids } ;
137171 ( match ! state_path with
138172 | None ->
139173 return ()
140174 | Some path ->
141- let contents = String.Table. sexp_of_t ( fun x -> Sexplib.Sexp. Atom x) ! sr_table |> Sexplib.Sexp. to_string in
175+ let contents = String.Table. sexp_of_t sexp_of_state ! sr_table |> Sexplib.Sexp. to_string in
142176 Writer. save path ~contents
143177 ) >> = fun () ->
144178 return (Ok () )
@@ -149,7 +183,15 @@ module Attached_SRs = struct
149183 let open Storage_interface in
150184 let exnty = Exception. Sr_not_attached smapiv2 in
151185 return (Error (Exception. rpc_of_exnty exnty))
152- | Some sr -> return (Ok sr)
186+ | Some { sr } -> return (Ok sr)
187+
188+ let get_uids smapiv2 =
189+ match Hashtbl. find ! sr_table smapiv2 with
190+ | None ->
191+ let open Storage_interface in
192+ let exnty = Exception. Sr_not_attached smapiv2 in
193+ return (Error (Exception. rpc_of_exnty exnty))
194+ | Some { uids } -> return (Ok uids)
153195
154196 let remove smapiv2 =
155197 Hashtbl. remove ! sr_table smapiv2;
@@ -164,7 +206,7 @@ module Attached_SRs = struct
164206 | `Yes ->
165207 Reader. file_contents path
166208 >> = fun contents ->
167- sr_table := contents |> Sexplib.Sexp. of_string |> String.Table. t_of_sexp ( function Sexplib.Sexp. Atom x -> x | _ -> assert false ) ;
209+ sr_table := contents |> Sexplib.Sexp. of_string |> String.Table. t_of_sexp state_of_sexp ;
168210 return ()
169211end
170212
@@ -362,11 +404,36 @@ let process root_dir name x =
362404 let args' = Storage.Volume.Types.SR.Attach.In. rpc_of_t args' in
363405 let open Deferred.Result.Monad_infix in
364406 fork_exec_rpc root_dir (script root_dir name `Volume " SR.attach" ) args' Storage.Volume.Types.SR.Attach.Out. t_of_rpc
365- >> = fun response ->
407+ >> = fun attach_response ->
408+ let sr = args.Args.SR.Attach. sr in
409+ (* Stat the SR to look for datasources *)
410+ let args = Storage.Volume.Types.SR.Stat.In. make
411+ args.Args.SR.Attach. dbg
412+ uri in
413+ let args = Storage.Volume.Types.SR.Stat.In. rpc_of_t args in
414+ fork_exec_rpc root_dir (script root_dir name `Volume " SR.stat" ) args Storage.Volume.Types.SR.Stat.Out. t_of_rpc
415+ >> = fun stat ->
416+ let open Deferred.Monad_infix in
417+ let rec loop acc = function
418+ | [] -> return acc
419+ | datasource :: datasources ->
420+ let uri = Uri. of_string datasource in
421+ match Uri. scheme uri with
422+ | Some "xeno+shm" ->
423+ let uid = Uri. path uri in
424+ let uid = if String. length uid > 1 then String. sub uid 1 (String. length uid - 1 ) else uid in
425+ RRD.Client.Plugin.Local. register ~uid ~info: Rrd. Five_Seconds ~protocol: Rrd_interface. V2
426+ >> = fun _ ->
427+ loop (uid :: acc) datasources
428+ | _ ->
429+ loop acc datasources in
430+ loop [] stat.Storage.Volume.Types. datasources
431+ >> = fun uids ->
432+ let open Deferred.Result.Monad_infix in
366433 (* associate the 'sr' from the plugin with the SR reference passed in *)
367- Attached_SRs. add args. Args.SR.Attach. sr response
434+ Attached_SRs. add sr attach_response uids
368435 >> = fun () ->
369- Deferred.Result. return (R. success (Args.SR.Attach. rpc_of_response response ))
436+ Deferred.Result. return (R. success (Args.SR.Attach. rpc_of_response attach_response ))
370437 end
371438 | { R. name = "SR.detach" ; R. params = [ args ] } ->
372439 let args = Args.SR.Detach. request_of_rpc args in
@@ -383,6 +450,25 @@ let process root_dir name x =
383450 let args' = Storage.Volume.Types.SR.Detach.In. rpc_of_t args' in
384451 fork_exec_rpc root_dir (script root_dir name `Volume " SR.detach" ) args' Storage.Volume.Types.SR.Detach.Out. t_of_rpc
385452 >> = fun response ->
453+ Attached_SRs. get_uids args.Args.SR.Detach. sr
454+ >> = fun uids ->
455+ let open Deferred.Monad_infix in
456+ let rec loop = function
457+ | [] -> return ()
458+ | datasource :: datasources ->
459+ let uri = Uri. of_string datasource in
460+ match Uri. scheme uri with
461+ | Some "xeno+shm" ->
462+ let uid = Uri. path uri in
463+ let uid = if String. length uid > 1 then String. sub uid 1 (String. length uid - 1 ) else uid in
464+ RRD.Client.Plugin.Local. deregister ~uid
465+ >> = fun _ ->
466+ loop datasources
467+ | _ ->
468+ loop datasources in
469+ loop uids
470+ >> = fun () ->
471+ let open Deferred.Result.Monad_infix in
386472 Attached_SRs. remove args.Args.SR.Detach. sr
387473 >> = fun () ->
388474 Deferred.Result. return (R. success (Args.SR.Detach. rpc_of_response response))
0 commit comments