From 10be691b86eba48fd7c730c4a52849c6a7b8843c Mon Sep 17 00:00:00 2001 From: Bob Lantz Date: Thu, 4 Jul 2013 19:27:57 -0700 Subject: [PATCH] Clean up intfs in root NS, and avoid deleting HW intfs It appears that under certain conditions, such as when a namespace exits, both ends of a veth pair may get dumped into the root namespace. We therefore now remove an interface both from its home namespace and from the root namespace. --- mininet/link.py | 7 ++++--- mininet/net.py | 10 +++++----- mininet/node.py | 19 +++++++++++-------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/mininet/link.py b/mininet/link.py index 24028ac..56bf3e6 100644 --- a/mininet/link.py +++ b/mininet/link.py @@ -25,7 +25,7 @@ Link: basic link class for creating veth pairs """ from mininet.log import info, error, debug -from mininet.util import makeIntfPair +from mininet.util import makeIntfPair, quietRun from time import sleep import re @@ -162,8 +162,9 @@ class Intf( object ): def delete( self ): "Delete interface" self.cmd( 'ip link del ' + self.name ) - # Does it help to sleep to let things run? - sleep( 0.001 ) + if self.node.inNamespace: + # Link may have been dumped into root NS + quietRun( 'ip link del ' + self.name ) def __repr__( self ): return '<%s %s>' % ( self.__class__.__name__, self.name ) diff --git a/mininet/net.py b/mininet/net.py index d056843..71c8ec0 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -372,16 +372,16 @@ class Mininet( object ): if self.terms: info( '*** Stopping %i terms\n' % len( self.terms ) ) self.stopXterms() - info( '*** Stopping %i hosts\n' % len( self.hosts ) ) - for host in self.hosts: - info( host.name + ' ' ) - host.terminate() - info( '\n' ) info( '*** Stopping %i switches\n' % len( self.switches ) ) for switch in self.switches: info( switch.name + ' ' ) switch.stop() info( '\n' ) + info( '*** Stopping %i hosts\n' % len( self.hosts ) ) + for host in self.hosts: + info( host.name + ' ' ) + host.terminate() + info( '\n' ) info( '*** Stopping %i controllers\n' % len( self.controllers ) ) for controller in self.controllers: info( controller.name + ' ' ) diff --git a/mininet/node.py b/mininet/node.py index ccf9179..ff87ca0 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -141,10 +141,10 @@ class Node( object ): def cleanup( self ): "Help python collect its garbage." - if not self.inNamespace: - for intfName in self.intfNames(): - if self.name in intfName: - quietRun( 'ip link del ' + intfName ) + # Intfs may end up in root NS + for intfName in self.intfNames(): + if self.name in intfName: + quietRun( 'ip link del ' + intfName ) self.shell = None # Subshell I/O, commands and control @@ -391,16 +391,19 @@ class Node( object ): connections += [ ( intf, link.intf1 ) ] return connections - def deleteIntfs( self ): - "Delete all of our interfaces." + def deleteIntfs( self, checkName=True ): + """Delete all of our interfaces. + checkName: only delete interfaces that contain our name""" # In theory the interfaces should go away after we shut down. # However, this takes time, so we're better off removing them # explicitly so that we won't get errors if we run before they # have been removed by the kernel. Unfortunately this is very slow, # at least with Linux kernels before 2.6.33 for intf in self.intfs.values(): - intf.delete() - info( '.' ) + # Protect against deleting hardware interfaces + if ( self.name in intf.name ) or ( not checkName ): + intf.delete() + info( '.' ) # Routing support