]> xenbits.xensource.com Git - xcp/xen-api.git/commitdiff
Hosts in a pool should use the same networking backend
authorRob Hoes <rob.hoes@citrix.com>
Tue, 12 Oct 2010 09:36:09 +0000 (10:36 +0100)
committerRob Hoes <rob.hoes@citrix.com>
Tue, 12 Oct 2010 09:36:09 +0000 (10:36 +0100)
This patch adds the following restrictions in order to prevent (as much as possible) trouble caused by hosts in a pool not having the same network backends (bridge/openvswitch):
1. Block pool join if the network backend of the joining host is not the same as the master's.
2. Block tunnel.create if at least one of the hosts in the pool uses the bridging backend.

Signed-off-by: Rob Hoes <rob.hoes@citrix.com>
ocaml/idl/datamodel.ml
ocaml/xapi/xapi_pool.ml
ocaml/xapi/xapi_tunnel.ml

index a7bed6d5e8e0f09120af29b053bcfe7c50bbe4a8..e474ceffae0dfc21788e099e66bb2d8eef4618cf 100644 (file)
@@ -449,7 +449,7 @@ let _ =
     ~doc:"The specified device was not found." ();
 
   error Api_errors.openvswitch_not_active []
-    ~doc:"This operation needs the OpenVSwitch networking backend to be enabled." ();
+    ~doc:"This operation needs the OpenVSwitch networking backend to be enabled on all hosts in the pool." ();
   error Api_errors.transport_pif_not_configured ["PIF"]
     ~doc:"The tunnel transport PIF has no IP configuration set." ();
   error Api_errors.is_tunnel_access_pif ["PIF"]
index cd1793cb2b6dd07661bb4cf22ca3f338455d4710..fc162ce7e50879243af51437601964cd12b9c5e1 100644 (file)
@@ -228,7 +228,20 @@ let pre_join_checks ~__context ~rpc ~session_id ~force =
                        let pool = List.hd (Client.Pool.get_all rpc session_id) in
                        let controller = Client.Pool.get_vswitch_controller ~rpc ~session_id ~self:pool in
                        if my_controller <> controller && my_controller <> "" then
-                               raise (Api_errors.Server_error(Api_errors.operation_not_allowed, ["vswitch controller address differs"]))
+                               raise (Api_errors.Server_error(Api_errors.operation_not_allowed, ["vswitch controller address differs"]));
+
+                       (* The network backend must be the same as the remote master's backend *)
+                       let my_backend = Netdev.string_of_kind Netdev.network.Netdev.kind in
+                       let remote_master = Client.Pool.get_master ~rpc ~session_id ~self:pool in
+                       let remote_masters_backend =
+                               let v = Client.Host.get_software_version ~rpc ~session_id ~self:remote_master in
+                               if not (List.mem_assoc "network_backend" v) then
+                                       Netdev.string_of_kind Netdev.Bridge
+                               else
+                                       List.assoc "network_backend" v
+                       in
+                       if my_backend <> remote_masters_backend then
+                               raise (Api_errors.Server_error(Api_errors.operation_not_allowed, ["Network backends differ"]));
                | _ -> ()
        in
 
index de796683846272ca9ca1ceb76ab5b7363cdccec8..a979f0d8065467994d9e1e7d3e77fab937c7472e 100644 (file)
@@ -28,8 +28,13 @@ let create ~__context ~transport_PIF ~network =
        let pool = Helpers.get_pool ~__context in
        let host = Db.PIF.get_host ~__context ~self:transport_PIF in
        Xapi_pif.assert_no_other_local_pifs ~__context ~host ~network;
-       if Netdev.network.Netdev.kind <> Netdev.Vswitch then
-               raise (Api_errors.Server_error (Api_errors.openvswitch_not_active, []));
+       let hosts = Db.Host.get_all ~__context in
+       List.iter
+               (fun h ->
+                       let v = Db.Host.get_software_version ~__context ~self:h in
+                       if not (List.mem_assoc "network_backend" v && List.assoc "network_backend" v = "openvswitch") then
+                               raise (Api_errors.Server_error (Api_errors.openvswitch_not_active, []));
+               ) hosts;
        if Db.PIF.get_tunnel_access_PIF_of ~__context ~self:transport_PIF <> [] then
                raise (Api_errors.Server_error (Api_errors.is_tunnel_access_pif, [Ref.string_of transport_PIF]));
        let tunnel = Ref.make () in