lib: speed up router shutdown stopRouter: report when a process is being killed only sleep if actually killed a process add option to not sleep or conduct -7 kill topogen stop: add wait parameter (defaults to old/wait) when stopping routers, first stop all without waiting then do a second pass where will wait if needed

Signed-off-by: Lou Berger <lberger@labn.net>
This commit is contained in:
Lou Berger 2017-12-07 13:47:22 -05:00 committed by Donald Sharp
parent 08533b7bce
commit 3a568b9ca6
2 changed files with 24 additions and 15 deletions

View File

@ -307,12 +307,16 @@ class Topogen(object):
""" """
Stops the network topology. This function will call the stop() function Stops the network topology. This function will call the stop() function
of all gears before calling the mininet stop function, so they can have of all gears before calling the mininet stop function, so they can have
their oportunity to do a graceful shutdown. their oportunity to do a graceful shutdown. stop() is called twice. The
first is a simple kill with no sleep, the second will sleep if not
killed and try with a different signal.
""" """
logger.info('stopping topology: {}'.format(self.modname)) logger.info('stopping topology: {}'.format(self.modname))
for gear in self.gears.values(): for gear in self.gears.values():
gear.stop() gear.stop(False)
for gear in self.gears.values():
gear.stop(True)
self.net.stop() self.net.stop()
@ -413,7 +417,7 @@ class TopoGear(object):
"Basic start function that just reports equipment start" "Basic start function that just reports equipment start"
logger.info('starting "{}"'.format(self.name)) logger.info('starting "{}"'.format(self.name))
def stop(self): def stop(self, wait=True):
"Basic start function that just reports equipment stop" "Basic start function that just reports equipment stop"
logger.info('stopping "{}"'.format(self.name)) logger.info('stopping "{}"'.format(self.name))
@ -633,13 +637,13 @@ class TopoRouter(TopoGear):
return result return result
def stop(self): def stop(self, wait=True):
""" """
Stop router: Stop router:
* Kill daemons * Kill daemons
""" """
self.logger.debug('stopping') self.logger.debug('stopping')
return self.tgen.net[self.name].stopRouter() return self.tgen.net[self.name].stopRouter(wait)
def vtysh_cmd(self, command, isjson=False, daemon=None): def vtysh_cmd(self, command, isjson=False, daemon=None):
""" """
@ -866,7 +870,7 @@ class TopoExaBGP(TopoHost):
self.run('chown -R exabgp:exabgp /etc/exabgp') self.run('chown -R exabgp:exabgp /etc/exabgp')
self.run('exabgp -e /etc/exabgp/exabgp.env /etc/exabgp/exabgp.cfg') self.run('exabgp -e /etc/exabgp/exabgp.env /etc/exabgp/exabgp.cfg')
def stop(self): def stop(self, wait=True):
"Stop ExaBGP peer and kill the daemon" "Stop ExaBGP peer and kill the daemon"
self.run('kill `cat /var/run/exabgp/exabgp.pid`') self.run('kill `cat /var/run/exabgp/exabgp.pid`')

View File

@ -534,23 +534,28 @@ class Router(Node):
set_sysctl(self, 'net.ipv4.ip_forward', 0) set_sysctl(self, 'net.ipv4.ip_forward', 0)
set_sysctl(self, 'net.ipv6.conf.all.forwarding', 0) set_sysctl(self, 'net.ipv6.conf.all.forwarding', 0)
super(Router, self).terminate() super(Router, self).terminate()
def stopRouter(self): def stopRouter(self, wait=True):
# Stop Running Quagga or FRR Daemons # Stop Running Quagga or FRR Daemons
rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype) rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
if rundaemons is not None: if rundaemons is not None:
numRunning = 0
for d in StringIO.StringIO(rundaemons): for d in StringIO.StringIO(rundaemons):
daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip() daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip()
if (daemonpid.isdigit() and pid_exists(int(daemonpid))): if (daemonpid.isdigit() and pid_exists(int(daemonpid))):
logger.info('killing %s %s' % (self.name, os.path.basename(d.rstrip().rsplit(".", 1)[0])))
self.cmd('kill -TERM %s' % daemonpid) self.cmd('kill -TERM %s' % daemonpid)
self.waitOutput() self.waitOutput()
sleep(2, 'waiting for router "{}" daemons to finish'.format( if pid_exists(int(daemonpid)):
self.name)) numRunning += 1
# 2nd round of kill if daemons didn't exist if wait and numRunning > 0:
for d in StringIO.StringIO(rundaemons): sleep(2)
daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip() # 2nd round of kill if daemons didn't exit
if (daemonpid.isdigit() and pid_exists(int(daemonpid))): for d in StringIO.StringIO(rundaemons):
self.cmd('kill -7 %s' % daemonpid) daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip()
self.waitOutput() if (daemonpid.isdigit() and pid_exists(int(daemonpid))):
logger.info('killing (-7) %s %s' % (self.name, os.path.basename(d.rstrip().rsplit(".", 1)[0])))
self.cmd('kill -7 %s' % daemonpid)
self.waitOutput()
def removeIPs(self): def removeIPs(self):
for interface in self.intfNames(): for interface in self.intfNames():
self.cmd('ip address flush', interface) self.cmd('ip address flush', interface)