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

cleanup state manager + remove some dead code

Ticket: CM-1438
Reviewed By:
Testing Done:
This commit is contained in:
roopa
2014-02-24 11:07:59 -08:00
parent e938bfeccd
commit 31a5f4c364
6 changed files with 98 additions and 194 deletions

View File

@ -125,7 +125,7 @@ start)
exclusions=$(process_exclusions)
perfoptions=$(perf_options)
log_action_begin_msg "Configuring network interfaces"
if ifup -a $verbose $perfoptions
if ifup -d -a $verbose $perfoptions
then
log_action_end_msg $?
else
@ -183,6 +183,7 @@ restart)
ifupdown_init
log_action_begin_msg "Reconfiguring network interfaces"
ifdown -a --exclude=lo $verbose --perfmode || true
set -f

View File

@ -125,9 +125,9 @@ class ifaceJsonEncoder(json.JSONEncoder):
'config' : retconfig})
class iface():
""" config flags """
AUTO = 0x1
HOT_PLUG = 0x2
""" flags """
# flag to indicate that the object was created from pickled state
PICKLED = 0x1
version = '0.1'
@ -255,6 +255,10 @@ class iface():
def set_status(self, status):
self.status = status
def set_state_n_status(self, state, status):
self.state = state
self.status = status
def state_str_to_hex(self, state_str):
return self.state_str_map.get(state_str)
@ -389,7 +393,6 @@ class iface():
del odict['status']
del odict['lowerifaces']
del odict['refcnt']
return odict
def __setstate__(self, dict):
@ -399,6 +402,7 @@ class iface():
self.refcnt = 0
self.lowerifaces = None
self.linkstate = None
self.flags |= self.PICKLED
def dump_raw(self, logger):
indent = ' '
@ -411,12 +415,13 @@ class iface():
logger.info(self.get_name() + ' : {')
logger.info(indent + 'family: %s' %self.get_addr_family())
logger.info(indent + 'method: %s' %self.get_addr_method())
logger.info(indent + 'flags: %x' %self.flags)
logger.info(indent + 'state: %s'
%ifaceState.to_str(self.get_state()))
logger.info(indent + 'status: %s'
%ifaceStatus.to_str(self.get_status()))
logger.info(indent + 'refcnt: %d' %self.get_refcnt())
d = self.get_lowerdevs()
d = self.get_lowerifaces()
if d:
logger.info(indent + 'lowerdevs: %s' %str(d))
else:

View File

@ -66,8 +66,7 @@ class ifupdownBase(object):
return os.path.exists('/sys/class/net/%s' %ifacename)
def link_up(self, ifacename):
#self.exec_command('ip link set dev %s up' %ifacename)
self.exec_command('ifconfig %s up' %ifacename)
self.exec_command('ip link set dev %s up' %ifacename)
def link_down(self, ifacename):
self.exec_command('ip link set dev %s down' %ifacename)

View File

@ -29,6 +29,7 @@ class ifupdownMain(ifupdownBase):
ALL = False
STATE_CHECK = False
COMPAT_EXEC_SCRIPTS = False
UPDATE_STATEMANAGER = True
# priv flags to mark iface objects
BUILTIN = 0x1
@ -86,9 +87,18 @@ class ifupdownMain(ifupdownBase):
if self.link_exists(ifacename):
self.link_down(ifacename)
# ifupdown object interface operation handlers
ops_handlers = OrderedDict([('up', run_up),
('down', run_down)])
def run_sched_ifaceobj_posthook(self, ifaceobj):
if self.UPDATE_STATEMANAGER:
self.statemanager.ifaceobj_sync(ifaceobj)
# ifupdown object interface scheduler pre and posthooks
sched_hooks = {'posthook' : run_sched_ifaceobj_posthook}
def __init__(self, force=False, dryrun=False, nowait=False,
perfmode=False, withdepends=False, njobs=1,
cache=False):
@ -188,17 +198,12 @@ class ifupdownMain(ifupdownBase):
self.logger.debug('setting withdepends to true')
self.WITH_DEPENDS = withdepends
def set_iface_state(self, ifaceobj, state, status):
ifaceobj.set_state(state)
ifaceobj.set_status(status)
self.statemanager.update_iface_state(ifaceobj)
def get_iface_objs(self, ifacename):
def get_ifaceobjs(self, ifacename):
return self.ifaceobjdict.get(ifacename)
def get_iface_obj_first(self, ifacename):
ifaceobjs = self.get_iface_objs(ifacename)
if ifaceobjs is not None:
def get_ifaceobj_first(self, ifacename):
ifaceobjs = self.get_ifaceobjs(ifacename)
if ifaceobjs:
return ifaceobjs[0]
return None
@ -226,16 +231,15 @@ class ifupdownMain(ifupdownBase):
return self.ifaceobjrunningdict.get(ifacename)
def get_iface_status(self, ifacename):
ifaceobjs = self.get_iface_objs(ifacename)
ifaceobjs = self.get_ifaceobjs(ifacename)
for i in ifaceobjs:
if i.get_status() != ifaceStatus.SUCCESS:
return i.get_status()
return ifaceStatus.SUCCESS
def get_iface_refcnt(self, ifacename):
max = 0
ifaceobjs = self.get_iface_objs(ifacename)
ifaceobjs = self.get_ifaceobjs(ifacename)
for i in ifaceobjs:
if i.get_refcnt() > max:
max = i.get_refcnt()
@ -286,7 +290,7 @@ class ifupdownMain(ifupdownBase):
def is_iface_noconfig(self, ifacename):
""" Returns true if iface has no config """
ifaceobj = self.get_iface_obj_first(ifacename)
ifaceobj = self.get_ifaceobj_first(ifacename)
if not ifaceobj: return True
return self.is_ifaceobj_noconfig(ifaceobj)
@ -309,7 +313,7 @@ class ifupdownMain(ifupdownBase):
del_list = []
for d in dlist:
dilist = self.get_iface_objs(d)
dilist = self.get_ifaceobjs(d)
if not dilist:
if self.is_iface_builtin_byname(d):
self.create_n_save_ifaceobj(d, self.BUILTIN | self.NOCONFIG,
@ -353,37 +357,30 @@ class ifupdownMain(ifupdownBase):
def populate_dependency_info(self, ifacenames, ops):
""" recursive function to generate iface dependency info """
if ifacenames is None:
if not ifacenames:
ifacenames = self.ifaceobjdict.keys()
self.logger.debug('populating dependency info for %s' %str(ifacenames))
iqueue = deque(ifacenames)
while iqueue:
i = iqueue.popleft()
# Go through all modules and find dependent ifaces
dlist = None
ifaceobj = self.get_iface_obj_first(i)
if ifaceobj is None:
ifaceobj = self.get_ifaceobj_first(i)
if not ifaceobj:
continue
dlist = ifaceobj.get_lowerifaces()
if dlist is None:
if not dlist:
dlist = self.query_dependents(ifaceobj, ops)
else:
continue
if dlist is not None:
if dlist:
self.preprocess_dependency_list(ifaceobj.get_name(),
dlist, ops)
self.logger.debug('%s: lowerifaces/dependents after processing: %s'
%(i, str(dlist)))
ifaceobj.set_lowerifaces(dlist)
[iqueue.append(d) for d in dlist]
if self.dependency_graph.get(i) is None:
if not self.dependency_graph.get(i):
self.dependency_graph[i] = dlist
def _save_iface(self, ifaceobj):
@ -594,24 +591,19 @@ class ifupdownMain(ifupdownBase):
returns -1 if one or more interface not found. else, returns 0
"""
err_iface = ''
for i in ifacenames:
ifaceobjs = self.get_iface_objs(i)
if ifaceobjs is None:
ifaceobjs = self.get_ifaceobjs(i)
if not ifaceobjs:
err_iface += ' ' + i
if err_iface:
self.logger.error('could not find interfaces: %s' %err_iface)
return -1
return 0
def iface_whitelisted(self, auto, allow_classes, excludepats, ifacename):
""" Checks if interface is whitelisted depending on set of parameters.
interfaces are checked against the allow_classes and auto lists.
"""
@ -620,12 +612,10 @@ class ifupdownMain(ifupdownBase):
for e in excludepats:
if re.search(e, ifacename):
return False
ifaceobjs = self.get_iface_objs(ifacename)
if ifaceobjs is None:
ifaceobjs = self.get_ifaceobjs(ifacename)
if not ifaceobjs:
self.logger.debug('iface %s' %ifacename + ' not found')
return False
# We check classes first
if allow_classes:
for i in ifaceobjs:
@ -635,13 +625,11 @@ class ifupdownMain(ifupdownBase):
if common:
return True
return False
if auto:
for i in ifaceobjs:
if i.get_auto():
return True
return False
return True
def generate_running_env(self, ifaceobj, op):
@ -673,14 +661,14 @@ class ifupdownMain(ifupdownBase):
except Exception, e:
raise
if ifacenames is not None:
if ifacenames:
# If iface list is given by the caller, always check if iface
# is present
if self.validate_ifaces(ifacenames) != 0:
raise Exception('all or some interfaces not found')
# if iface list not given by user, assume all from config file
if ifacenames is None: ifacenames = self.ifaceobjdict.keys()
if not ifacenames: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
filtered_ifacenames = [i for i in ifacenames
@ -705,10 +693,7 @@ class ifupdownMain(ifupdownBase):
# Update persistant iface states
try:
if self.ALL:
self.statemanager.flush_state(self.ifaceobjdict)
else:
self.statemanager.flush_state()
self.statemanager.save_state()
except Exception, e:
if self.logger.isEnabledFor(logging.DEBUG):
t = sys.exc_info()[2]
@ -717,35 +702,31 @@ class ifupdownMain(ifupdownBase):
def down(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None):
loaded_newconfig = False
if auto:
self.ALL = True
self.WITH_DEPENDS = True
# for down we need to look at old state
self.logger.debug('Looking at old state ..')
if self.statemanager.get_ifaceobjdict():
# Since we are using state manager objects,
# skip the updating of state manager objects
self.UPDATE_STATEMANAGER = False
self.read_old_iface_config()
else:
# If no old state available
self.logger.info('old state not available. ' +
'Loading new iface config file')
'Loading current iface config file')
try:
self.read_iface_config()
except Exception, e:
raise Exception('error reading iface config (%s)' %str(e))
loaded_newconfig = True
if ifacenames:
# If iface list is given by the caller, always check if iface
# is present
if self.validate_ifaces(ifacenames) != 0:
raise Exception('all or some interfaces not found')
# if iface list not given by user, assume all from config file
if not ifacenames: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
filtered_ifacenames = [i for i in ifacenames
if self.iface_whitelisted(auto, allow_classes,
@ -762,26 +743,23 @@ class ifupdownMain(ifupdownBase):
self.run_with_dependents(ops, filtered_ifacenames)
else:
self.run_without_dependents(ops, filtered_ifacenames)
if self.DRYRUN:
return
if loaded_newconfig:
# Update persistant iface states
try:
if self.ALL:
self.statemanager.flush_state(self.ifaceobjdict)
else:
self.statemanager.flush_state()
except Exception, e:
if self.logger.isEnabledFor(logging.DEBUG):
t = sys.exc_info()[2]
traceback.print_tb(t)
# Update persistant iface states
try:
self.statemanager.save_state()
except Exception, e:
if self.logger.isEnabledFor(logging.DEBUG):
t = sys.exc_info()[2]
traceback.print_tb(t)
self.logger.warning('error saving state (%s)' %str(e))
def query(self, ops, auto=False, allow_classes=None, ifacenames=None,
excludepats=None, printdependency=None,
format='native'):
self.UPDATE_STATEMANAGER = False
if auto:
self.logger.debug('setting flag ALL')
self.ALL = True
@ -806,7 +784,7 @@ class ifupdownMain(ifupdownBase):
raise Exception('all or some interfaces not found')
# if iface list not given by user, assume all from config file
if ifacenames is None: ifacenames = self.ifaceobjdict.keys()
if not ifacenames: ifacenames = self.ifaceobjdict.keys()
# filter interfaces based on auto and allow classes
if ops[0] == 'query-running':
@ -874,6 +852,7 @@ class ifupdownMain(ifupdownBase):
# followed by 'up' aka: reload
# old interface config is read into self.ifaceobjdict
#
self.UPDATE_STATEMANAGER = False
self.read_old_iface_config()
op = 'reload'
else:
@ -959,10 +938,8 @@ class ifupdownMain(ifupdownBase):
self.run_with_dependents(upops, filtered_ifacenames)
else:
self.run_without_dependents(upops, filtered_ifacenames)
if self.DRYRUN:
return
# Update persistant iface states
try:
if self.ALL:
@ -988,7 +965,7 @@ class ifupdownMain(ifupdownBase):
def print_ifaceobjs_raw(self, ifacenames):
for i in ifacenames:
for ifaceobj in self.get_iface_objs(i):
for ifaceobj in self.get_ifaceobjs(i):
if (self.is_ifaceobj_builtin(ifaceobj) or
not ifaceobj.is_config_present()):
continue
@ -1001,14 +978,13 @@ class ifupdownMain(ifupdownBase):
def print_ifaceobjs_pretty(self, ifacenames, format='native'):
for i in ifacenames:
for ifaceobj in self.get_iface_objs(i):
for ifaceobj in self.get_ifaceobjs(i):
if (self.is_ifaceobj_noconfig(ifaceobj)):
continue
if format == 'json':
ifaceobj.dump_json()
else:
ifaceobj.dump_pretty()
if self.WITH_DEPENDS:
dlist = ifaceobj.get_lowerifaces()
if not dlist: continue
@ -1016,7 +992,7 @@ class ifupdownMain(ifupdownBase):
def dump_ifaceobjs(self, ifacenames):
for i in ifacenames:
ifaceobjs = self.get_iface_objs(i)
ifaceobjs = self.get_ifaceobjs(i)
for i in ifaceobjs:
i.dump(self.logger)
print '\n'
@ -1055,19 +1031,16 @@ class ifupdownMain(ifupdownBase):
def print_ifaceobjsrunning_pretty(self, ifacenames, format='native'):
for i in ifacenames:
ifaceobj = self.get_iface_obj_first(i)
ifaceobj = self.get_ifaceobj_first(i)
if ifaceobj.get_status() == ifaceStatus.NOTFOUND:
print 'iface %s' %ifaceobj.get_name() + ' (not found)\n'
continue
if ifaceobj.is_config_present() == False:
if not ifaceobj.is_config_present():
continue
if format == 'json':
ifaceobj.dump_json()
else:
ifaceobj.dump_pretty()
if self.WITH_DEPENDS:
dlist = ifaceobj.get_lowerifaces()
if not dlist: continue

View File

@ -71,15 +71,12 @@ class ifaceScheduler():
err = 1
ifupdownobj.log_error(str(e))
finally:
if err == 1:
ifupdownobj.set_iface_state(ifaceobj,
ifaceState.from_str(op),
ifaceStatus.ERROR)
if err:
ifaceobj.set_state_n_status(ifaceState.from_str(op),
ifaceStatus.ERROR)
else:
ifupdownobj.set_iface_state(ifaceobj,
ifaceState.from_str(op),
ifaceStatus.SUCCESS)
ifaceobj.set_state_n_status(ifaceState.from_str(op),
ifaceStatus.SUCCESS)
if ifupdownobj.COMPAT_EXEC_SCRIPTS:
# execute /etc/network/ scripts
@ -93,16 +90,16 @@ class ifaceScheduler():
@classmethod
def run_iface_ops(cls, ifupdownobj, ifaceobj, ops):
""" Runs all sub operations on an interface """
""" Runs all operations on an interface """
cenv=None
if ifupdownobj.COMPAT_EXEC_SCRIPTS:
# For backward compatibility generate env variables
# for attributes
cenv = ifupdownobj.generate_running_env(ifaceobj, ops[0])
# Each sub operation has a module list
map(lambda op: cls.run_iface_op(ifupdownobj, ifaceobj, op, cenv), ops)
posthookfunc = ifupdownobj.sched_hooks.get('posthook')
if posthookfunc:
posthookfunc(ifupdownobj, ifaceobj)
@classmethod
def run_iface_graph(cls, ifupdownobj, ifacename, ops, parent=None,
@ -117,8 +114,8 @@ class ifaceScheduler():
return
# Each ifacename can have a list of iface objects
ifaceobjs = ifupdownobj.get_iface_objs(ifacename)
if ifaceobjs is None:
ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename)
if not ifaceobjs:
raise Exception('%s: not found' %ifacename)
for ifaceobj in ifaceobjs:
@ -180,8 +177,8 @@ class ifaceScheduler():
pass
else:
# Dont bring the iface up if children did not come up
ifaceobj.set_state(ifaceState.NEW)
ifaceobj.set_status(ifaceStatus.ERROR)
ifaceobj.set_state_n_sttaus(ifaceState.NEW,
ifacestatus.ERROR)
raise
if order == ifaceSchedulerFlags.POSTORDER:
cls.run_iface_ops(ifupdownobj, ifaceobj, ops)
@ -255,7 +252,7 @@ class ifaceScheduler():
def run_iface(cls, ifupdownobj, ifacename, ops):
""" Runs operation on an interface """
ifaceobjs = ifupdownobj.get_iface_objs(ifacename)
ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename)
for i in ifaceobjs:
cls.run_iface_ops(ifupdownobj, i, ops)
@ -281,7 +278,7 @@ class ifaceScheduler():
ifacename = iface_run_queue.pop()
try:
ifaceobjs = ifupdownobj.get_iface_objs(ifacename)
ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename)
for ifaceobj in ifaceobjs:
cenv = ifupdownobj.generate_running_env(ifaceobj, op)
cls.run_iface_op(ifupdownobj, ifaceobj, op, cenv)
@ -359,7 +356,7 @@ class ifaceScheduler():
cls.accquire_token(iface)
# Each iface can have a list of objects
ifaceobjs = ifupdownobj.get_iface_objs(ifacename)
ifaceobjs = ifupdownobj.get_ifaceobjs(ifacename)
if ifaceobjs is None:
ifupdownobj.logger.warning('%s: ' %ifacename + 'not found')
cls.release_token(ifacename)

View File

@ -11,6 +11,7 @@ from collections import OrderedDict
import logging
import os
from iface import *
import copy
class pickling():
@ -68,20 +69,12 @@ class stateManager():
# Read all ifaces from file
for ifaceobj in pickling.load(pickle_filename):
self.save_ifaceobj(ifaceobj)
#ifaceobj.set_refcnt(0)
#ifaceobj.set_dependents(None)
return 0
def get_ifaceobjdict(self):
return self.ifaceobjdict
def save_state(self, ifaceobjs, filename=None):
pickle_filename = filename
if not pickle_filename:
pickle_filename = self.state_file
pickling.save(pickle_filename, ifaceobjs)
def compare_iface_state(ifaceobj1, ifaceobj2):
ifaceobj1_state = ifaceobj1.get_state()
ifaceobj2_state = ifaceobj2.get_state()
@ -93,38 +86,6 @@ class stateManager():
elif ifaceobj1_state == ifaceobj2_state:
return 0
def compare_iface_with_old(self, ifaceobj):
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
if old_ifaceobj == None:
raise ifacenotfound(ifaceobj.get_name())
if ifaceobj.get_addr_family() != old_ifaceobj.get_addr_family():
return -1
if ifaceobj.get_method() != old_ifaceobj.get_method():
return -1
# compare config items
unmatched_item = set(ifaceobj.items()) ^ set(old_ifaceobj.items())
if unmatched_item:
return -1
return 0
def get_iface_state_old(self, ifaceobj):
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
if old_ifaceobj == None:
raise ifacenotfound(ifaceobj.get_name())
return old_ifaceobj.get_state()
def get_iface_status_old(self, ifaceobj):
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
if old_ifaceobj == None:
raise ifacenotfound(ifaceobj.get_name())
return old_ifaceobj.get_status()
def cmp_old_new_state(self, ifacename, operation):
""" compares current operation with old state """
@ -150,7 +111,7 @@ class stateManager():
return 1
def iface_obj_compare(self, ifaceobj_a, ifaceobj_b):
def ifaceobj_compare(self, ifaceobj_a, ifaceobj_b):
if ifaceobj_a.get_name() != ifaceobj_b.get_name():
return False
@ -171,60 +132,28 @@ class stateManager():
return True
def update_iface_state(self, ifaceobj):
old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
if old_ifaceobjs is None:
self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
def ifaceobj_sync(self, ifaceobj):
ifacename = ifaceobj.get_name()
self.logger.debug('%s: statemanager sync state' %ifacename)
old_ifaceobjs = self.ifaceobjdict.get(ifacename)
if not old_ifaceobjs:
self.ifaceobjdict[ifacename] = [ifaceobj]
else:
for oi in old_ifaceobjs:
if self.iface_obj_compare(ifaceobj, oi) == True:
oi.set_state(ifaceobj.get_state())
oi.set_status(ifaceobj.get_status())
return
self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
def flush_state(self, ifaceobjdict=None):
if ifaceobjdict is None:
ifaceobjdict = self.ifaceobjdict
if old_ifaceobjs[0].flags & iface.PICKLED:
del self.ifaceobjdict[ifacename]
self.ifaceobjdict[ifacename] = [ifaceobj]
else:
self.ifaceobjdict[ifacename].append(ifaceobj)
def save_state(self):
try:
with open(self.state_file, 'w') as f:
for ifaceobjs in ifaceobjdict.values():
for ifaceobjs in self.ifaceobjdict.values():
for i in ifaceobjs:
pickling.save_obj(f, i)
except:
raise
def is_valid_state_transition(self, ifaceobj, tobe_state):
if self.ifaceobjdict is None:
return True
if tobe_state == 'up':
max_tobe_state = ifaceState.POST_UP
elif tobe_state == 'down':
max_tobe_state = ifaceState.POST_DOWN
else:
return True
old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
if old_ifaceobjs is not None:
for oi in old_ifaceobjs:
if self.iface_obj_compare(ifaceobj, oi) == True:
if (oi.get_state() == max_tobe_state and
oi.get_status() == ifaceStatus.SUCCESS):
# if old state is greater than or equal to
# tobe_state
return False
else:
return True
return True
else:
return True
def print_state(self, ifaceobj, prefix, indent):
print (indent + '%s' %prefix +
'%s' %ifaceobj.get_state_str() +
@ -249,7 +178,7 @@ class stateManager():
print '\n'
def dump(self, ifacenames=None):
print 'iface state:'
self.logger.debug('statemanager iface state:')
if ifacenames:
for i in ifacenames:
ifaceobj = self.ifaces.get(i)
@ -258,5 +187,5 @@ class stateManager():
%i + ' not found')
ifaceobj.dump(self.logger)
else:
for ifacename, ifaceobj in self.ifaceobjdict.items():
ifaceobj.dump(self.logger)
for ifacename, ifaceobjs in self.ifaceobjdict.items():
[i.dump(self.logger) for i in ifaceobjs]