@@ -105,9 +105,20 @@ let warn fmt = log Core.Unix.Syslog.Level.WARNING fmt
105105let error fmt = log Core.Unix.Syslog.Level. ERR fmt
106106
107107let pvs_version = " 3.0"
108- let supported_api_versions = [pvs_version; " 4.0 " ; " 5.0" ]
108+ let supported_api_versions = [pvs_version; " 5.0" ]
109109let api_max = List. fold_left ~f: max supported_api_versions ~init: " "
110110
111+ let check_plugin_version_compatible query_result =
112+ let Xapi_storage.Plugin. { name; required_api_version; _ } = query_result in
113+ if required_api_version <> api_max then
114+ warn " Using deprecated SMAPIv3 API version %s, latest is %s. Update your %s plugin!" required_api_version api_max name;
115+ if List. mem ~equal: String. equal supported_api_versions required_api_version then
116+ Deferred.Result. return ()
117+ else
118+ let msg = Printf. sprintf " %s requires unknown SMAPI API version %s, supported: %s"
119+ name required_api_version (String. concat ~sep: " ," supported_api_versions) in
120+ return (Error (Storage_interface.Exception. No_storage_plugin_for_sr msg))
121+
111122module RRD = struct
112123 open Message_switch_async.Protocol_async
113124
@@ -354,17 +365,24 @@ module Datapath_plugins = struct
354365 let table = String.Table. create ()
355366
356367 let register ~datapath_root datapath_plugin_name =
357- let script_dir = Filename. concat datapath_root datapath_plugin_name in
358- return_plugin_rpc (fun () -> Plugin_client. query (fork_exec_rpc ~script_dir ) " register" )
359- >> = fun result ->
360- match result with
361- | Ok response ->
362- info " Registered datapath plugin %s" datapath_plugin_name;
363- Hashtbl. set table ~key: datapath_plugin_name ~data: (script_dir, response);
364- return ()
365- | Error _ ->
366- info " Failed to register datapath plugin %s" datapath_plugin_name;
367- return ()
368+ let result =
369+ let script_dir = Filename. concat datapath_root datapath_plugin_name in
370+ return_plugin_rpc (fun () -> Plugin_client. query (fork_exec_rpc ~script_dir ) " register" )
371+ >>> = fun response ->
372+ check_plugin_version_compatible response >> = function
373+ | Ok () ->
374+ info " Registered datapath plugin %s" datapath_plugin_name;
375+ Hashtbl. set table ~key: datapath_plugin_name ~data: (script_dir, response);
376+ return (Ok () )
377+ | Error e ->
378+ let err_msg = Storage_interface.Exception. rpc_of_exnty e |> Jsonrpc. to_string in
379+ info " Failed to register datapath plugin %s: %s" datapath_plugin_name err_msg;
380+ return (Error e)
381+ in
382+ (* We just do not register the plugin if we've encountered any error. In
383+ the future we might want to change that, so we keep the error result
384+ above. *)
385+ result >> = fun _ -> return ()
368386
369387 let unregister datapath_plugin_name =
370388 Hashtbl. remove table datapath_plugin_name;
@@ -574,6 +592,11 @@ let process_smapiv2_requests ~volume_script_dir =
574592 let dbg = args.Args.Query.Query. dbg in
575593 return_plugin_rpc (fun () -> Plugin_client. query volume_rpc dbg)
576594 >>> = fun response ->
595+ let required_api_version =
596+ response.Xapi_storage.Plugin. required_api_version in
597+ (* the first call to a plugin must be a Query.query that sets the version *)
598+ version := Some required_api_version;
599+ check_plugin_version_compatible response >>> = fun () ->
577600 (* Convert between the xapi-storage interface and the SMAPI *)
578601 let features = List. map ~f: (function
579602 | "VDI_DESTROY" -> " VDI_DELETE"
@@ -615,8 +638,6 @@ let process_smapiv2_requests ~volume_script_dir =
615638 then " VDI_RESET_ON_BOOT/2" :: features
616639 else features in
617640 let name = response.Xapi_storage.Plugin. name in
618- let required_api_version =
619- response.Xapi_storage.Plugin. required_api_version in
620641 let response = {
621642 driver = response.Xapi_storage.Plugin. plugin;
622643 name;
@@ -628,16 +649,7 @@ let process_smapiv2_requests ~volume_script_dir =
628649 features;
629650 configuration = response.Xapi_storage.Plugin. configuration;
630651 required_cluster_stack = response.Xapi_storage.Plugin. required_cluster_stack } in
631- (* the first call to a plugin must be a Query.query that sets the version *)
632- version := Some required_api_version;
633- if required_api_version <> api_max then
634- warn " Using deprecated SMAPIv3 API version %s, latest is %s. Update your %s plugin!" required_api_version api_max name;
635- if List. mem ~equal: String. equal supported_api_versions required_api_version then
636- Deferred.Result. return (R. success (Args.Query.Query. rpc_of_response response))
637- else
638- let msg = Printf. sprintf " %s requires unknown SMAPI API version %s, supported: %s"
639- name required_api_version (String. concat ~sep: " ," supported_api_versions) in
640- return (Error (Exception. No_storage_plugin_for_sr msg))
652+ Deferred.Result. return (R. success (Args.Query.Query. rpc_of_response response))
641653 | { R. name = "Query.diagnostics" ; R. params = [ args ] } ->
642654 let open Deferred.Result.Monad_infix in
643655 let args = Args.Query.Diagnostics. request_of_rpc args in
@@ -1277,7 +1289,7 @@ let self_test_plugin ~root_dir plugin =
12771289let self_test ~root_dir =
12781290 (self_test_plugin ~root_dir " org.xen.xapi.storage.dummy"
12791291 >>> = fun () ->
1280- self_test_plugin ~root_dir " org.xen.xapi.storage.dummyv4 " )
1292+ self_test_plugin ~root_dir " org.xen.xapi.storage.dummyv5 " )
12811293 >> = function
12821294 | Ok () ->
12831295 info " test thread shutdown cleanly" ;
0 commit comments