@@ -106,6 +106,10 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
106
106
end
107
107
end
108
108
109
+ let script root_dir name kind script = match kind with
110
+ | `Volume -> Filename. (concat (concat root_dir name) script)
111
+ | `Datapath datapath -> Filename. (concat (concat (concat (dirname root_dir) " datapath" ) datapath) script)
112
+
109
113
module Attached_SRs = struct
110
114
let sr_table : string String.Table.t ref = ref (String.Table. create () )
111
115
let state_path = ref None
@@ -146,6 +150,29 @@ module Attached_SRs = struct
146
150
return ()
147
151
end
148
152
153
+ module Datapath_plugins = struct
154
+ let table: Storage.Plugin.Types. query_result String.Table. t ref = ref (String.Table. create () )
155
+
156
+ let register root_dir name =
157
+ let args = Storage.Plugin.Types.Plugin.Query.In. make " register" in
158
+ let args = Storage.Plugin.Types.Plugin.Query.In. rpc_of_t args in
159
+ fork_exec_rpc root_dir (script root_dir name (`Datapath name) " Plugin.Query" ) args Storage.Plugin.Types.Plugin.Query.Out. t_of_rpc
160
+ >> = function
161
+ | Ok response ->
162
+ info " Registered datapath plugin %s" name
163
+ >> = fun () ->
164
+ Hashtbl. replace ! table name response;
165
+ return ()
166
+ | _ ->
167
+ info " Failed to register datapath plugin %s" name
168
+ >> = fun () ->
169
+ return ()
170
+
171
+ let unregister root_dir name =
172
+ Hashtbl. remove ! table name;
173
+ return ()
174
+ end
175
+
149
176
let vdi_of_volume x =
150
177
let open Storage_interface in {
151
178
vdi = x.Storage.Volume.Types. key;
@@ -174,10 +201,6 @@ let choose_datapath = function
174
201
| Some scheme -> return (Ok (scheme, uri, domain))
175
202
end
176
203
177
- let script root_dir name kind script = match kind with
178
- | `Volume -> Filename. (concat (concat root_dir name) script)
179
- | `Datapath datapath -> Filename. (concat (concat (concat (dirname root_dir) " datapath" ) datapath) script)
180
-
181
204
let stat root_dir name dbg sr vdi =
182
205
let args = Storage.Volume.Types.Volume.Stat.In. make dbg sr vdi in
183
206
let args = Storage.Volume.Types.Volume.Stat.In. rpc_of_t args in
@@ -692,10 +715,53 @@ let watch_volume_plugins ~root_dir ~switch_path =
692
715
loop () in
693
716
loop ()
694
717
718
+ let watch_datapath_plugins ~root_dir =
719
+ let root_dir = Filename. concat root_dir " datapath" in
720
+ let sync ~root_dir =
721
+ Sys. readdir root_dir
722
+ >> = fun names ->
723
+ let needed : string list = Array. to_list names in
724
+ let got_already : string list = Hashtbl. keys servers in
725
+ Deferred. all_ignore (List. map ~f: (Datapath_plugins. register root_dir) (diff needed got_already))
726
+ >> = fun () ->
727
+ Deferred. all_ignore (List. map ~f: (Datapath_plugins. unregister root_dir) (diff got_already needed)) in
728
+ Async_inotify. create ~recursive: false ~watch_new_dirs: false root_dir
729
+ >> = fun (watch , _ ) ->
730
+ sync ~root_dir
731
+ >> = fun () ->
732
+ let pipe = Async_inotify. pipe watch in
733
+ let open Async_inotify.Event in
734
+ let rec loop () =
735
+ ( Pipe. read pipe >> = function
736
+ | `Eof ->
737
+ info " Received EOF from inotify event pipe"
738
+ >> = fun () ->
739
+ Shutdown. exit 1
740
+ | `Ok (Created path)
741
+ | `Ok (Moved (Into path )) ->
742
+ Datapath_plugins. register root_dir (Filename. basename path)
743
+ | `Ok (Unlinked path)
744
+ | `Ok (Moved (Away path )) ->
745
+ Datapath_plugins. unregister root_dir (Filename. basename path)
746
+ | `Ok (Modified _ ) ->
747
+ return ()
748
+ | `Ok (Moved (Move (path_a , path_b ))) ->
749
+ Datapath_plugins. unregister root_dir (Filename. basename path_a)
750
+ >> = fun () ->
751
+ Datapath_plugins. register root_dir (Filename. basename path_b)
752
+ | `Ok Queue_overflow ->
753
+ sync ~root_dir
754
+ ) >> = fun () ->
755
+ loop () in
756
+ loop ()
757
+
695
758
let main ~root_dir ~state_path ~switch_path =
696
759
Attached_SRs. reload state_path
697
760
>> = fun () ->
698
- watch_volume_plugins ~root_dir ~switch_path
761
+ Deferred. all_unit [
762
+ watch_volume_plugins ~root_dir ~switch_path ;
763
+ watch_datapath_plugins ~root_dir
764
+ ]
699
765
700
766
let main ~root_dir ~state_path ~switch_path =
701
767
let (_: unit Deferred.t ) = main ~root_dir ~state_path ~switch_path in
0 commit comments