From: Lou Berger Date: Thu, 7 Dec 2017 18:47:22 +0000 (-0500) Subject: lib: speed up router shutdown stopRouter: report when a process is being killed only... X-Git-Tag: frr-7.1-dev~151^2~194 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3a568b9ca6a63d11b281076e17ee707236b23ba3;p=mirror%2Ffrr.git 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 --- diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index 43a886befb..2ea05c9742 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -307,12 +307,16 @@ class Topogen(object): """ Stops the network topology. This function will call the stop() function 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)) for gear in self.gears.values(): - gear.stop() + gear.stop(False) + for gear in self.gears.values(): + gear.stop(True) self.net.stop() @@ -413,7 +417,7 @@ class TopoGear(object): "Basic start function that just reports equipment start" logger.info('starting "{}"'.format(self.name)) - def stop(self): + def stop(self, wait=True): "Basic start function that just reports equipment stop" logger.info('stopping "{}"'.format(self.name)) @@ -633,13 +637,13 @@ class TopoRouter(TopoGear): return result - def stop(self): + def stop(self, wait=True): """ Stop router: * Kill daemons """ 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): """ @@ -866,7 +870,7 @@ class TopoExaBGP(TopoHost): self.run('chown -R exabgp:exabgp /etc/exabgp') 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" self.run('kill `cat /var/run/exabgp/exabgp.pid`') diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 42ac62213a..487324880d 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -534,23 +534,28 @@ class Router(Node): set_sysctl(self, 'net.ipv4.ip_forward', 0) set_sysctl(self, 'net.ipv6.conf.all.forwarding', 0) super(Router, self).terminate() - def stopRouter(self): + def stopRouter(self, wait=True): # Stop Running Quagga or FRR Daemons rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype) if rundaemons is not None: + numRunning = 0 for d in StringIO.StringIO(rundaemons): daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip() 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.waitOutput() - sleep(2, 'waiting for router "{}" daemons to finish'.format( - self.name)) - # 2nd round of kill if daemons didn't exist - for d in StringIO.StringIO(rundaemons): - daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip() - if (daemonpid.isdigit() and pid_exists(int(daemonpid))): - self.cmd('kill -7 %s' % daemonpid) - self.waitOutput() + if pid_exists(int(daemonpid)): + numRunning += 1 + if wait and numRunning > 0: + sleep(2) + # 2nd round of kill if daemons didn't exit + for d in StringIO.StringIO(rundaemons): + daemonpid = self.cmd('cat %s' % d.rstrip()).rstrip() + 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): for interface in self.intfNames(): self.cmd('ip address flush', interface)