ovs-xapi-sync: Cache the bridge-id value for non nicira-bridge-id too.
authorGurucharan Shetty <gshetty@nicira.com>
Sun, 16 Jun 2013 12:09:20 +0000 (05:09 -0700)
committerGurucharan Shetty <gshetty@nicira.com>
Tue, 18 Jun 2013 22:32:54 +0000 (15:32 -0700)
Currently we connect to xapi in case there are multiple
external_ids:xs-network-uuids to get the single bridge id everytime
we have a change in the database for all the interested columns in
ovs-xapi-sync. The xs-network-uuids value can also change whenever
new VLANs are added or deleted, which is a common use case. The
disadvantage with this approach is that we query XAPI more often
and set the bridge-id as "" if we don't get a valid response for
our query. This can take down the logical connectivity for all the
VMs on that xenserver.

Instead of looking at the PIF records for all the xs-network-uuids,
we can instead just look at the xapi record which has the same bridge
name as the OVS bridge name and then cache its uuid. This value will
hold true till the OVS bridge is recreated in which case we will re-read
the value.

Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
xenserver/usr_share_openvswitch_scripts_ovs-xapi-sync

index 649ddbe..46b729d 100755 (executable)
@@ -90,33 +90,14 @@ def get_network_by_bridge(br_name):
     return None
 
 # There are possibilities when multiple xs-network-uuids are set for a bridge.
-# In cases like that, we should choose the bridge-id whose PIF does not have a
-# VLAN associated with it.
-def get_single_bridge_id(bridge_ids, default=None):
+# In cases like that, we should choose the bridge-id associated with the bridge
+# name.
+def get_single_bridge_id(bridge_ids, br_name, default=None):
     global xapi_down
-    if not init_session():
-        vlog.warn("Failed to get single bridge id from %s because"
-                  "XAPI session could not be initialized" % bridge_ids)
-        return default
-
-    for bridge_id in bridge_ids:
-        try:
-            recs = session.xenapi.network.get_all_records_where(\
-                                            'field "uuid"="%s"' % bridge_id)
-            if recs:
-                pifs = recs.values()[0]['PIFs']
-                for pif in pifs:
-                    try:
-                        rec = session.xenapi.PIF.get_record(pif)
-                        if rec['VLAN'] == '-1':
-                            return bridge_id
-                    except XenAPI.Failure:
-                        vlog.warn("Could not find XAPI entry for PIF %s" % pif)
-                        continue
-
-        except XenAPI.Failure:
-            vlog.warn("Could not find XAPI entry for bridge_id %s" % bridge_id)
-            continue
+
+    rec = get_network_by_bridge(br_name)
+    if rec and rec['uuid'] in bridge_ids:
+        return rec['uuid']
 
     vlog.warn("Failed to get a single bridge id from Xapi.")
     xapi_down = True
@@ -314,24 +295,26 @@ def main():
         new_bridges = {}
         for row in idl.tables["Bridge"].rows.itervalues():
             if row.name in bridges:
-                nbd = bridges[row.name]
+                bridge_id_cache = bridges[row.name]
             else:
                 # New bridge.
                 update_fail_mode(row)
                 update_in_band_mgmt(row)
-                nbd = get_bridge_id(row.name)
+                bridge_id_cache = get_bridge_id(row.name)
 
-            bridge_id = nbd
+            bridge_id = bridge_id_cache
             if bridge_id is None:
                 bridge_id = row.external_ids.get("xs-network-uuids")
                 if bridge_id and len(bridge_id.split(";")) > 1:
                     bridge_ids = bridge_id.split(";")
-                    bridge_id = get_single_bridge_id(bridge_ids, "")
+                    bridge_id = get_single_bridge_id(bridge_ids, row.name, "")
+                if bridge_id:
+                    bridge_id_cache = bridge_id
 
             if bridge_id is not None:
                 set_external_id(row, "bridge-id", bridge_id.split(";")[0])
 
-            new_bridges[row.name] = nbd
+            new_bridges[row.name] = bridge_id_cache
         bridges = new_bridges
 
         iface_by_name = {}