[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 6 of 8] Tunnelling: synchronise tunnels with the pool master when a slave starts up


  • To: xen-api@xxxxxxxxxxxxxxxxxxx
  • From: Rob Hoes <rob.hoes@xxxxxxxxxx>
  • Date: Fri, 9 Jul 2010 15:59:52 +0100
  • Delivery-date: Fri, 09 Jul 2010 08:05:55 -0700
  • List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>

# HG changeset patch
# User Rob Hoes <rob.hoes@xxxxxxxxxx>
# Date 1278673890 -3600
# Node ID 170d86bd910a03d06f78432ab1962d71b880589b
# Parent  9e70e8fd232cc15d766362078a53571328e8f28b
Tunnelling: synchronise tunnels with the pool master when a slave starts up

Just like for bonds and VLANs, tunnels should be synchronised with the pool 
master and all pool slaves. This code ensure that tunnels are synchronised when 
xapi starts up on a slave, which is especially important after a pool join.

Signed-off-by: Rob Hoes <rob.hoes@xxxxxxxxxx>

diff -r 9e70e8fd232c -r 170d86bd910a ocaml/xapi/sync_networking.ml
--- a/ocaml/xapi/sync_networking.ml
+++ b/ocaml/xapi/sync_networking.ml
@@ -170,7 +170,54 @@
                (* for each of the master's pifs, create a corresponding one on 
this host if necessary *)
                List.iter maybe_create_vlan_pif_for_me master_vlan_pifs
        )
-                       
+
+(** Copy tunnels from master *)
+let copy_tunnels_from_master ~__context =
+       Helpers.call_api_functions ~__context (fun rpc session_id ->
+               debug "Resynchronising tunnels";
+               
+               let me = !Xapi_globs.localhost_ref in
+               let pool = List.hd (Db.Pool.get_all ~__context) in
+               let master = Db.Pool.get_master ~__context ~self:pool in
+
+               let all_pifs = Db.PIF.get_records_where ~__context 
~expr:Db_filter_types.True in
+               let all_master_pifs = List.filter (fun (_, prec) -> 
prec.API.pIF_host=master) all_pifs in
+               let my_pifs = List.filter (fun (_, pif) -> pif.API.pIF_host=me) 
all_pifs in
+
+               let master_tunnel_pifs = List.filter (fun (_,prec) -> 
prec.API.pIF_tunnel_access_PIF_of <> []) all_master_pifs in
+               let my_tunnel_pifs = List.filter (fun (_,prec) -> 
prec.API.pIF_tunnel_access_PIF_of <> []) my_pifs in
+
+               let get_network_of_transport_pif access_pif =
+                       let [tunnel] = Db.PIF.get_tunnel_access_PIF_of 
~__context ~self:access_pif in
+                       let transport_pif = Db.Tunnel.get_transport_PIF 
~__context ~self:tunnel in
+                       Db.PIF.get_network ~__context ~self:transport_pif
+               in
+               
+               let maybe_create_tunnel_for_me (master_pif_ref, master_pif_rec) 
=
+                       (* check to see if I have any existing pif(s) that for 
the specified device, network, vlan... *)
+                       let existing_pif = List.filter (fun 
(my_pif_ref,my_pif_record) -> 
+                               (* Is my VLAN PIF that we're considering 
(my_pif_ref) the one that corresponds to the master_pif we're considering 
(master_pif_ref)? *)
+                               my_pif_record.API.pIF_network = 
master_pif_rec.API.pIF_network
+                               ) my_tunnel_pifs in
+                       (* if I don't have any such pif(s) then make one: *)
+                       if List.length existing_pif = 0 
+                       then
+                               begin
+                                       (* On the master, we find the network 
the tunnel transport PIF is on *)
+                                       let network_of_transport_pif_on_master 
= get_network_of_transport_pif master_pif_ref in
+                                       match List.filter (fun (_,prec) -> 
prec.API.pIF_network=network_of_transport_pif_on_master) my_pifs with
+                                       | [] -> () (* we have no PIF on which 
to make the tunnel; do nothing *)
+                                       | [(pif_ref,_)] -> (* this is the PIF 
on which we want as transport PIF; let's make it *)
+                                               ignore (Client.Tunnel.create 
~rpc ~session_id ~transport_PIF:pif_ref
+                                                       
~network:master_pif_rec.API.pIF_network)
+                                       | _ -> () (* this should never happen 
cos we should never have more than one of _our_ pifs on the same nework *)
+                               end
+               in 
+               (* for each of the master's pifs, create a corresponding one on 
this host if necessary *)
+               List.iter maybe_create_tunnel_for_me master_tunnel_pifs
+       )
+
+
 let sync_slave_with_master ~__context () =
        if Pool_role.is_master () then () (* if master do nothing *)
        else begin
@@ -178,7 +225,8 @@
                try
                        (* Sync VLANs after bonds so we can add VLANs on top of 
bonded interfaces (but not v.v.) *)
                        copy_bonds_from_master ~__context;
-                       copy_vlans_from_master ~__context
+                       copy_vlans_from_master ~__context;
+                       copy_tunnels_from_master ~__context
                with e -> (* Errors here are non-data-corrupting hopefully, so 
we'll just carry on regardless... *)
                        error "Caught exception syncing PIFs from the master: 
%s" (ExnHelper.string_of_exn e);
                log_backtrace ()
 ocaml/xapi/sync_networking.ml |  52 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 2 deletions(-)


Attachment: xen-api.hg-6.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.