@@ -73,6 +73,26 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
7373 end
7474 end
7575
76+ module Attached_SRs = struct
77+ let sr_table = String.Table. create ()
78+
79+ let add smapiv2 plugin =
80+ Hashtbl. replace sr_table smapiv2 plugin;
81+ return (Ok () )
82+
83+ let find smapiv2 =
84+ match Hashtbl. find sr_table smapiv2 with
85+ | None ->
86+ let open Storage_interface in
87+ let exnty = Exception. Sr_not_attached smapiv2 in
88+ return (Error (Exception. rpc_of_exnty exnty))
89+ | Some sr -> return (Ok sr)
90+
91+ let remove smapiv2 =
92+ Hashtbl. remove sr_table smapiv2;
93+ return (Ok () )
94+ end
95+
7696let vdi_of_volume x =
7797 let open Storage_interface in {
7898 vdi = x.Storage.V.Types. key;
@@ -82,7 +102,7 @@ let vdi_of_volume x =
82102 ty = " " ;
83103 metadata_of_pool = " " ;
84104 is_a_snapshot = false ;
85- snapshot_time = " " ;
105+ snapshot_time = " 19700101T00:00:00Z " ;
86106 snapshot_of = " " ;
87107 read_only = not x.Storage.V.Types. read_write;
88108 virtual_size = x.Storage.V.Types. virtual_size;
@@ -127,6 +147,9 @@ let process root_dir name x =
127147 fork_exec_rpc root_dir (script root_dir name `Volume " Plugin.Query" ) args Storage.P.Types.Plugin.Query.Out. t_of_rpc
128148 >> = fun response ->
129149 (* Convert between the xapi-storage interface and the SMAPI *)
150+ let features = List. map ~f: (function
151+ | "VDI_DESTROY" -> " VDI_DELETE"
152+ | x -> x) response.Storage.P.Types. features in
130153 let response = {
131154 driver = response.Storage.P.Types. plugin;
132155 name = response.Storage.P.Types. name;
@@ -135,7 +158,7 @@ let process root_dir name x =
135158 copyright = response.Storage.P.Types. copyright;
136159 version = response.Storage.P.Types. version;
137160 required_api_version = response.Storage.P.Types. required_api_version;
138- features = response. Storage.P.Types. features ;
161+ features;
139162 configuration =
140163 (" uri" , " URI of the storage medium" ) ::
141164 response.Storage.P.Types. configuration} in
@@ -155,23 +178,35 @@ let process root_dir name x =
155178 | None ->
156179 Deferred.Result. return (R. failure (missing_uri () ))
157180 | Some (_ , uri ) ->
158- let args = Storage.V.Types.SR.Attach.In. make args.Args.SR.Attach. dbg uri in
159- let args = Storage.V.Types.SR.Attach.In. rpc_of_t args in
181+ let args' = Storage.V.Types.SR.Attach.In. make args.Args.SR.Attach. dbg uri in
182+ let args' = Storage.V.Types.SR.Attach.In. rpc_of_t args' in
160183 let open Deferred.Result.Monad_infix in
161- fork_exec_rpc root_dir (script root_dir name `Volume " SR.attach" ) args Storage.V.Types.SR.Attach.Out. t_of_rpc
184+ fork_exec_rpc root_dir (script root_dir name `Volume " SR.attach" ) args' Storage.V.Types.SR.Attach.Out. t_of_rpc
162185 >> = fun response ->
186+ (* associate the 'sr' from the plugin with the SR reference passed in *)
187+ Attached_SRs. add args.Args.SR.Attach. sr response
188+ >> = fun () ->
163189 Deferred.Result. return (R. success (Args.SR.Attach. rpc_of_response response))
164190 end
165191 | { R. name = "SR.detach" ; R. params = [ args ] } ->
166192 let args = Args.SR.Detach. request_of_rpc args in
167- let args = Storage.V.Types.SR.Detach.In. make
168- args.Args.SR.Detach. dbg
169- args.Args.SR.Detach. sr in
170- let args = Storage.V.Types.SR.Detach.In. rpc_of_t args in
171- let open Deferred.Result.Monad_infix in
172- fork_exec_rpc root_dir (script root_dir name `Volume " SR.detach" ) args Storage.V.Types.SR.Detach.Out. t_of_rpc
173- >> = fun response ->
174- Deferred.Result. return (R. success (Args.SR.Detach. rpc_of_response response))
193+ begin Attached_SRs. find args.Args.SR.Detach. sr
194+ >> = function
195+ | Error _ ->
196+ (* ensure SR.detach is idempotent *)
197+ Deferred.Result. return (R. success (Args.SR.Detach. rpc_of_response () ))
198+ | Ok sr ->
199+ let open Deferred.Result.Monad_infix in
200+ let args' = Storage.V.Types.SR.Detach.In. make
201+ args.Args.SR.Detach. dbg
202+ sr in
203+ let args' = Storage.V.Types.SR.Detach.In. rpc_of_t args' in
204+ fork_exec_rpc root_dir (script root_dir name `Volume " SR.detach" ) args' Storage.V.Types.SR.Detach.Out. t_of_rpc
205+ >> = fun response ->
206+ Attached_SRs. remove args.Args.SR.Detach. sr
207+ >> = fun () ->
208+ Deferred.Result. return (R. success (Args.SR.Detach. rpc_of_response response))
209+ end
175210 | { R. name = "SR.create" ; R. params = [ args ] } ->
176211 let args = Args.SR.Create. request_of_rpc args in
177212 let device_config = args.Args.SR.Create. device_config in
@@ -190,49 +225,57 @@ let process root_dir name x =
190225 Deferred.Result. return (R. success (Args.SR.Create. rpc_of_response response))
191226 end
192227 | { R. name = "SR.scan" ; R. params = [ args ] } ->
228+ let open Deferred.Result.Monad_infix in
193229 let args = Args.SR.Scan. request_of_rpc args in
230+ Attached_SRs. find args.Args.SR.Scan. sr
231+ >> = fun sr ->
194232 let args = Storage.V.Types.SR.Ls.In. make
195233 args.Args.SR.Scan. dbg
196- args. Args.SR.Scan. sr in
234+ sr in
197235 let args = Storage.V.Types.SR.Ls.In. rpc_of_t args in
198- let open Deferred.Result.Monad_infix in
199236 fork_exec_rpc root_dir (script root_dir name `Volume " SR.ls" ) args Storage.V.Types.SR.Ls.Out. t_of_rpc
200237 >> = fun response ->
201238 let response = List. map ~f: vdi_of_volume response in
202239 Deferred.Result. return (R. success (Args.SR.Scan. rpc_of_response response))
203240 | { R. name = "VDI.create" ; R. params = [ args ] } ->
241+ let open Deferred.Result.Monad_infix in
204242 let args = Args.VDI.Create. request_of_rpc args in
243+ Attached_SRs. find args.Args.VDI.Create. sr
244+ >> = fun sr ->
205245 let vdi_info = args.Args.VDI.Create. vdi_info in
206246 let args = Storage.V.Types.Volume.Create.In. make
207247 args.Args.VDI.Create. dbg
208- args. Args.VDI.Create. sr
248+ sr
209249 vdi_info.name_label
210250 vdi_info.name_description
211251 vdi_info.virtual_size in
212252 let args = Storage.V.Types.Volume.Create.In. rpc_of_t args in
213- let open Deferred.Result.Monad_infix in
214253 fork_exec_rpc root_dir (script root_dir name `Volume " Volume.create" ) args Storage.V.Types.Volume.Create.Out. t_of_rpc
215254 >> = fun response ->
216255 let response = vdi_of_volume response in
217256 Deferred.Result. return (R. success (Args.VDI.Create. rpc_of_response response))
218257 | { R. name = "VDI.destroy" ; R. params = [ args ] } ->
258+ let open Deferred.Result.Monad_infix in
219259 let args = Args.VDI.Destroy. request_of_rpc args in
260+ Attached_SRs. find args.Args.VDI.Destroy. sr
261+ >> = fun sr ->
220262 let args = Storage.V.Types.Volume.Destroy.In. make
221263 args.Args.VDI.Destroy. dbg
222- args. Args.VDI.Destroy. sr
264+ sr
223265 args.Args.VDI.Destroy. vdi in
224266 let args = Storage.V.Types.Volume.Destroy.In. rpc_of_t args in
225- let open Deferred.Result.Monad_infix in
226267 fork_exec_rpc root_dir (script root_dir name `Volume " Volume.destroy" ) args Storage.V.Types.Volume.Destroy.Out. t_of_rpc
227268 >> = fun response ->
228269 Deferred.Result. return (R. success (Args.VDI.Destroy. rpc_of_response response))
229270 | { R. name = "VDI.attach" ; R. params = [ args ] } ->
271+ let open Deferred.Result.Monad_infix in
230272 let args = Args.VDI.Attach. request_of_rpc args in
273+ Attached_SRs. find args.Args.VDI.Attach. sr
274+ >> = fun sr ->
231275 (* Discover the URIs using Volume.stat *)
232- let open Deferred.Result.Monad_infix in
233276 stat root_dir name
234277 args.Args.VDI.Attach. dbg
235- args. Args.VDI.Attach. sr
278+ sr
236279 args.Args.VDI.Attach. vdi
237280 >> = fun (datapath , uri , domain ) ->
238281 let args' = Storage.D.Types.Datapath.Attach.In. make
@@ -241,22 +284,24 @@ let process root_dir name x =
241284 let args' = Storage.D.Types.Datapath.Attach.In. rpc_of_t args' in
242285 fork_exec_rpc root_dir (script root_dir name (`Datapath datapath) " Datapath.attach" ) args' Storage.D.Types.Datapath.Attach.Out. t_of_rpc
243286 >> = fun response ->
244- let params = match response.Storage.D.Types. implementation with
245- | Storage.D.Types. Blkback p -> p
246- | Storage.D.Types. Qdisk p -> p
247- | Storage.D.Types. Tapdisk3 p -> p in
287+ let backend, params = match response.Storage.D.Types. implementation with
288+ | Storage.D.Types. Blkback p -> " vbd " , p
289+ | Storage.D.Types. Qdisk p -> " qdisk " , p
290+ | Storage.D.Types. Tapdisk3 p -> " vbd3 " , p in
248291 let attach_info = {
249292 params;
250- xenstore_data = [ " xenstore " , " data " ]
293+ xenstore_data = [ " backend-kind " , backend ]
251294 } in
252295 Deferred.Result. return (R. success (Args.VDI.Attach. rpc_of_response attach_info))
253296 | { R. name = "VDI.activate" ; R. params = [ args ] } ->
297+ let open Deferred.Result.Monad_infix in
254298 let args = Args.VDI.Activate. request_of_rpc args in
299+ Attached_SRs. find args.Args.VDI.Activate. sr
300+ >> = fun sr ->
255301 (* Discover the URIs using Volume.stat *)
256- let open Deferred.Result.Monad_infix in
257302 stat root_dir name
258303 args.Args.VDI.Activate. dbg
259- args. Args.VDI.Activate. sr
304+ sr
260305 args.Args.VDI.Activate. vdi
261306 >> = fun (datapath , uri , domain ) ->
262307 let args' = Storage.D.Types.Datapath.Activate.In. make
@@ -267,12 +312,14 @@ let process root_dir name x =
267312 >> = fun response ->
268313 Deferred.Result. return (R. success (Args.VDI.Activate. rpc_of_response () ))
269314 | { R. name = "VDI.deactivate" ; R. params = [ args ] } ->
315+ let open Deferred.Result.Monad_infix in
270316 let args = Args.VDI.Deactivate. request_of_rpc args in
317+ Attached_SRs. find args.Args.VDI.Deactivate. sr
318+ >> = fun sr ->
271319 (* Discover the URIs using Volume.stat *)
272- let open Deferred.Result.Monad_infix in
273320 stat root_dir name
274321 args.Args.VDI.Deactivate. dbg
275- args. Args.VDI.Deactivate. sr
322+ sr
276323 args.Args.VDI.Deactivate. vdi
277324 >> = fun (datapath , uri , domain ) ->
278325 let args' = Storage.D.Types.Datapath.Deactivate.In. make
@@ -283,12 +330,14 @@ let process root_dir name x =
283330 >> = fun response ->
284331 Deferred.Result. return (R. success (Args.VDI.Deactivate. rpc_of_response () ))
285332 | { R. name = "VDI.detach" ; R. params = [ args ] } ->
333+ let open Deferred.Result.Monad_infix in
286334 let args = Args.VDI.Detach. request_of_rpc args in
335+ Attached_SRs. find args.Args.VDI.Detach. sr
336+ >> = fun sr ->
287337 (* Discover the URIs using Volume.stat *)
288- let open Deferred.Result.Monad_infix in
289338 stat root_dir name
290339 args.Args.VDI.Detach. dbg
291- args. Args.VDI.Detach. sr
340+ sr
292341 args.Args.VDI.Detach. vdi
293342 >> = fun (datapath , uri , domain ) ->
294343 let args' = Storage.D.Types.Datapath.Detach.In. make
@@ -298,9 +347,17 @@ let process root_dir name x =
298347 fork_exec_rpc root_dir (script root_dir name (`Datapath datapath) " Datapath.detach" ) args' Storage.D.Types.Datapath.Detach.Out. t_of_rpc
299348 >> = fun response ->
300349 Deferred.Result. return (R. success (Args.VDI.Detach. rpc_of_response () ))
350+ | { R. name = "SR.stat" ; R. params = [ args ] } ->
351+ let open Deferred.Result.Monad_infix in
352+ let args = Args.SR.Stat. request_of_rpc args in
353+ Attached_SRs. find args.Args.SR.Stat. sr
354+ >> = fun sr ->
355+ (* FIXME: query the datasources xapi-storage#13 *)
356+ let response = { total_space = 0L ; free_space = 0L } in
357+ Deferred.Result. return (R. success (Args.SR.Stat. rpc_of_response response))
301358
302- | _ ->
303- Deferred.Result. return (R. failure ( R. String " hello " )))
359+ | { R. name = name } ->
360+ Deferred. return (Error (backend_error " UNIMPLEMENTED " [ name ] )))
304361 >> = function
305362 | Result. Error error ->
306363 Printf. fprintf stderr " returning %s\n %!" (Jsonrpc. string_of_response (R. failure error));
0 commit comments