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>
return None
# There are possibilities when multiple xs-network-uuids are set for a bridge.
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):
- 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
vlog.warn("Failed to get a single bridge id from Xapi.")
xapi_down = True
new_bridges = {}
for row in idl.tables["Bridge"].rows.itervalues():
if row.name in bridges:
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)
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 = 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(";")
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])
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 = {}
bridges = new_bridges
iface_by_name = {}