Skip to content

Commit bc1b570

Browse files
author
David Scott
committed
Watch for new datapath plugins, query their capabilities
We keep a table of the known datapath plugins so we can choose the most appropriate one to use. Signed-off-by: David Scott <[email protected]>
1 parent 0327da7 commit bc1b570

File tree

1 file changed

+71
-5
lines changed

1 file changed

+71
-5
lines changed

main.ml

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
106106
end
107107
end
108108

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+
109113
module Attached_SRs = struct
110114
let sr_table : string String.Table.t ref = ref (String.Table.create ())
111115
let state_path = ref None
@@ -146,6 +150,29 @@ module Attached_SRs = struct
146150
return ()
147151
end
148152

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+
149176
let vdi_of_volume x =
150177
let open Storage_interface in {
151178
vdi = x.Storage.Volume.Types.key;
@@ -174,10 +201,6 @@ let choose_datapath = function
174201
| Some scheme -> return (Ok (scheme, uri, domain))
175202
end
176203

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-
181204
let stat root_dir name dbg sr vdi =
182205
let args = Storage.Volume.Types.Volume.Stat.In.make dbg sr vdi in
183206
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 =
692715
loop () in
693716
loop ()
694717

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+
695758
let main ~root_dir ~state_path ~switch_path =
696759
Attached_SRs.reload state_path
697760
>>= 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+
]
699765

700766
let main ~root_dir ~state_path ~switch_path =
701767
let (_: unit Deferred.t) = main ~root_dir ~state_path ~switch_path in

0 commit comments

Comments
 (0)