1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

Fix l3 lag test failure

Ticket: CM-1438
Reviewed By:
Testing Done: l3 lag test with help from purna

- THe down sequence in the new ifupdown was causing switchd some grief
  (wilson is looking at it). readded the topological sort which i had
removed in favor of only walking the tree. With the fix,i dont see the
switchd problem anymore.
- And another down bug was causing the bond to go away prematurely (only
  with the all depends option). Added a upperdevice list to track upperdev references
This commit is contained in:
roopa
2014-02-12 22:29:41 -08:00
parent e176f1d459
commit f321512771
4 changed files with 117 additions and 83 deletions

View File

@@ -100,15 +100,15 @@ class ifaceScheduler(ifupdownBase):
[self.run_iface_op(ifupdownobj, ifaceobj, op, cenv)
for op in ops]
def run_iface_graph(self, ifupdownobj, ifacename, ops,
def run_iface_graph(self, ifupdownobj, ifacename, ops, parent=None,
order=ifaceSchedulerFlags.POSTORDER,
followdependents=True):
""" runs interface by traversing all nodes rooted at itself """
# minor optimization. If operation is 'down', proceed only
# if interface exists in the system
if ('down' in ops[0] and
not os.path.exists('/sys/class/net/%s' %ifacename)):
if 'down' in ops[0] and not self.link_exists(ifacename):
self.logger.info('%s: does not exist' %ifacename)
return
# Each ifacename can have a list of iface objects
@@ -117,32 +117,62 @@ class ifaceScheduler(ifupdownBase):
raise Exception('%s: not found' %ifacename)
for ifaceobj in ifaceobjs:
# Deal with upperdevs first
ulist = ifaceobj.get_upperifaces()
if ulist:
self.logger.debug('%s: parent = %s, ulist = %s'
%(ifacename, parent, ulist))
tmpulist = ([u for u in ulist if u != parent] if parent
else ulist)
if tmpulist:
self.logger.debug('%s: parent = %s, tmpulist = %s'
%(ifacename, parent, tmpulist))
if 'down' in ops[0]:
# XXX: This is expensive. Find a cheaper way to do this
# if any of the upperdevs are present,
# dont down this interface
for u in tmpulist:
if self.link_exists(u):
if not ifupdownobj.ALL:
self.logger.warn('%s: skip interface '
'down upperiface %s still around'
%(ifacename, u))
return
elif 'up' in ops[0] and not ifupdownobj.ALL:
# For 'up', just warn that there is an upperdev which is
# probably not up
for u in tmpulist:
if not self.link_exists(u):
self.logger.warn('%s: upper iface %s does not'
' exist' %(ifacename, u))
if order == ifaceSchedulerFlags.INORDER:
# Run all sub operations sequentially
try:
self.run_iface_ops(ifupdownobj, ifaceobj, ops)
except Exception, e:
raise Exception(str(e))
# Run dependents
dlist = ifaceobj.get_dependents()
if dlist and len(dlist):
# If inorder, run the iface first and then its dependents
self.run_iface_ops(ifupdownobj, ifaceobj, ops)
# Run lowerifaces or dependents
dlist = ifaceobj.get_lowerifaces()
if dlist:
self.logger.info('%s:' %ifacename +
' found dependents: %s' %str(dlist))
try:
if not followdependents:
# XXX: this is yet another extra step,
# but is needed for interfaces that are
# implicit dependents
# up without dependents, but
# implicit dependents. even though we are asked to
# not follow dependents, we must follow the ones
# that dont have user given config. Because we own them
new_dlist = [d for d in dlist
if ifupdownobj.is_iface_noconfig(d)]
if new_dlist:
self.run_iface_list(ifupdownobj, new_dlist, ops,
order, followdependents,
ifacename, order,
followdependents,
continueonfailure=False)
else:
self.run_iface_list(ifupdownobj, dlist, ops,
order, followdependents,
ifacename, order,
followdependents,
continueonfailure=False)
except Exception, e:
if (self.ignore_error(str(e))):
@@ -152,21 +182,18 @@ class ifaceScheduler(ifupdownBase):
ifaceobj.set_state(ifaceState.NEW)
ifaceobj.set_status(ifaceStatus.ERROR)
raise
if order == ifaceSchedulerFlags.POSTORDER:
try:
self.run_iface_ops(ifupdownobj, ifaceobj, ops)
except Exception, e:
raise Exception(str(e))
self.run_iface_ops(ifupdownobj, ifaceobj, ops)
def run_iface_list(self, ifupdownobj, ifacenames,
ops, order=ifaceSchedulerFlags.POSTORDER,
ops, parent=None, order=ifaceSchedulerFlags.POSTORDER,
followdependents=True, continueonfailure=True):
""" Runs interface list """
for ifacename in ifacenames:
try:
self.run_iface_graph(ifupdownobj, ifacename, ops,
self.run_iface_graph(ifupdownobj, ifacename, ops, parent,
order, followdependents)
except Exception, e:
if continueonfailure:
@@ -196,24 +223,28 @@ class ifaceScheduler(ifupdownBase):
indegrees : indegree array if present is used to determine roots
of the graphs in the dependency_graph
"""
run_queue = []
# Build a list of ifaces that dont have any dependencies
if indegrees:
# use indegrees array if specified
for ifacename, degree in indegrees.items():
if not indegrees.get(ifacename):
run_queue.append(ifacename)
else:
for ifacename in dependency_graph.keys():
if not ifupdownobj.get_iface_refcnt(ifacename):
run_queue.append(ifacename)
self.logger.debug('graph roots (interfaces that dont have '
if indegrees is None:
indegrees = OrderedDict()
for ifacename in dependency_graph.keys():
indegrees[ifacename] = ifupdownobj.get_iface_refcnt(ifacename)
sorted_ifacenames = graph.topological_sort_graphs_all(dependency_graph,
dict(indegrees))
self.logger.debug('sorted ifacenames %s : ' %str(sorted_ifacenames))
# Build a list of ifaces that dont have any dependencies
for ifacename in sorted_ifacenames:
if not indegrees.get(ifacename):
run_queue.append(ifacename)
self.logger.info('graph roots (interfaces that dont have '
'dependents):' + ' %s' %str(run_queue))
return self.run_iface_list(ifupdownobj, run_queue, ops, order,
followdependents)
return self.run_iface_list(ifupdownobj, run_queue, ops,
parent=None,order=order,
followdependents=followdependents)
def run_iface(self, ifupdownobj, ifacename, ops):
@@ -328,7 +359,7 @@ class ifaceScheduler(ifupdownBase):
for ifaceobj in ifaceobjs:
# Run dependents
dlist = ifaceobj.get_dependents()
dlist = ifaceobj.get_lowerifaces()
if dlist is not None and len(dlist) > 0:
self.logger.debug('%s:' %ifacename +
' found dependents: %s' %str(dlist))