Skip to content

Commit d3543cb

Browse files
committed
Merge pull request #35 from djs55/forupstream/CP-12902
Register and deregister datasources with xcp-rrdd
2 parents 3327ad5 + c4ff210 commit d3543cb

File tree

4 files changed

+103
-14
lines changed

4 files changed

+103
-14
lines changed

_oasis

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ Executable xapi_script_storage
1313
MainIs: main.ml
1414
Custom: true
1515
Install: false
16-
BuildDepends: xcp, xcp.storage, async_inotify, threads, message_switch.async (>= 0.11.0), rpclib, xapi-storage, sexplib, sexplib.syntax, rpclib, rpclib.syntax
16+
BuildDepends: xcp, xcp.storage, xcp.rrd, async_inotify, threads, message_switch.async (>= 0.11.0), rpclib, xapi-storage, sexplib, sexplib.syntax, rpclib, rpclib.syntax

_tags

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# OASIS_START
2-
# DO NOT EDIT (digest: d4caced815577ed0a5b4b8487e4f2276)
2+
# DO NOT EDIT (digest: 2c22384c8337719c5d75ab0e5fc90afb)
33
# Ignore VCS directories, you can use the same kind of rule outside
44
# OASIS_START/STOP if you want to exclude directories that contains
55
# useless stuff for the build process
@@ -24,6 +24,7 @@ true: annot, bin_annot
2424
<main.{native,byte}>: pkg_threads
2525
<main.{native,byte}>: pkg_xapi-storage
2626
<main.{native,byte}>: pkg_xcp
27+
<main.{native,byte}>: pkg_xcp.rrd
2728
<main.{native,byte}>: pkg_xcp.storage
2829
<*.ml{,i,y}>: pkg_async_inotify
2930
<*.ml{,i,y}>: pkg_message_switch.async
@@ -34,6 +35,7 @@ true: annot, bin_annot
3435
<*.ml{,i,y}>: pkg_threads
3536
<*.ml{,i,y}>: pkg_xapi-storage
3637
<*.ml{,i,y}>: pkg_xcp
38+
<*.ml{,i,y}>: pkg_xcp.rrd
3739
<*.ml{,i,y}>: pkg_xcp.storage
3840
<main.{native,byte}>: custom
3941
# OASIS_STOP

main.ml

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,35 @@ let info fmt = log Core.Syslog.Level.INFO fmt
3939
let warn fmt = log Core.Syslog.Level.WARNING fmt
4040
let 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+
4271
let _nonpersistent = "NONPERSISTENT"
4372
let _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

131160
module 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 ()
169211
end
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))

setup.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(* setup.ml generated for the first time by OASIS v0.4.4 *)
22

33
(* OASIS_START *)
4-
(* DO NOT EDIT (digest: 29609653515f2db19f5b74fca28cd6eb) *)
4+
(* DO NOT EDIT (digest: 7cbbdca01feb98c65e73ab10fd15a812) *)
55
(*
66
Regenerated by OASIS v0.4.5
77
Visit http://oasis.forge.ocamlcore.org for more information and
@@ -6741,6 +6741,7 @@ let setup_t =
67416741
[
67426742
FindlibPackage ("xcp", None);
67436743
FindlibPackage ("xcp.storage", None);
6744+
FindlibPackage ("xcp.rrd", None);
67446745
FindlibPackage ("async_inotify", None);
67456746
FindlibPackage ("threads", None);
67466747
FindlibPackage
@@ -6772,14 +6773,14 @@ let setup_t =
67726773
};
67736774
oasis_fn = Some "_oasis";
67746775
oasis_version = "0.4.5";
6775-
oasis_digest = Some "\012@\028\131\159\175G\238\214P\150/AW\151F";
6776+
oasis_digest = Some "\224\128\205S\160\162\"\236\\\2334g_\202\162\133";
67766777
oasis_exec = None;
67776778
oasis_setup_args = [];
67786779
setup_update = false
67796780
};;
67806781

67816782
let setup () = BaseSetup.setup setup_t;;
67826783

6783-
# 6784 "setup.ml"
6784+
# 6785 "setup.ml"
67846785
(* OASIS_STOP *)
67856786
let () = setup ();;

0 commit comments

Comments
 (0)