Skip to content
Snippets Groups Projects
Commit b7640209 authored by Bob Lantz's avatar Bob Lantz
Browse files

Changed to use class vars and method to track nodes.

Useful for monitoring the output of a set of nodes.
parent 1417fe72
No related branches found
No related tags found
No related merge requests found
......@@ -105,6 +105,8 @@ def quietRun( cmd ):
class Node( object ):
"""A virtual network node is simply a shell in a network namespace.
We communicate with it using pipes."""
inToNode = {}
outToNode = {}
def __init__( self, name, inNamespace=True ):
self.name = name
closeFds = False # speed vs. memory use
......@@ -118,8 +120,11 @@ def __init__( self, name, inNamespace=True ):
self.stdout = self.shell.stdout
self.pollOut = select.poll()
self.pollOut.register( self.stdout )
outToNode[ self.stdout ] = self
inToNode[ self.stdin ] = self
# Maintain mapping between file descriptors and nodes
# This could be useful for monitoring multiple nodes
# using select.poll()
self.outToNode[ self.stdout.fileno() ] = self
self.inToNode[ self.stdin.fileno() ] = self
self.pid = self.shell.pid
self.intfCount = 0
self.intfs = []
......@@ -127,6 +132,9 @@ def __init__( self, name, inNamespace=True ):
self.connection = {}
self.waiting = False
self.execed = False
def fdToNode( self, f ):
node = self.outToNode.get( f )
return node or self.inToNode.get( f )
def cleanup( self ):
# Help python collect its garbage
self.shell = None
......@@ -134,8 +142,8 @@ def cleanup( self ):
def read( self, max ): return os.read( self.stdout.fileno(), max )
def write( self, data ): os.write( self.stdin.fileno(), data )
def terminate( self ):
self.cleanup()
os.kill( self.pid, signal.SIGKILL )
self.cleanup()
def stop( self ): self.terminate()
def waitReadable( self ): self.pollOut.poll()
def sendCmd( self, cmd ):
......@@ -211,29 +219,19 @@ def setDefaultRoute( self, intf ):
return self.cmd( 'route add default ' + intf )
def IP( self ):
"Return IP address of first interface"
return self.ips[ self.intfs[ 0 ] ]
if len( self.intfs ) > 0:
return self.ips.get( self.intfs[ 0 ], None )
def intfIsUp( self, intf ):
"Check if one of our interfaces is up."
return 'UP' in self.cmd( 'ifconfig ' + self.intfs[ 0 ] )
# Other methods
def __str__( self ):
result = self.name
result += ": IP=" + self.IP() + " intfs=" + self.intfs
result += " waiting=", self.waiting
result += ": IP=" + self.IP() + " intfs=" + ','.join( self.intfs )
result += " waiting=" + `self.waiting`
return result
# Maintain mapping between i/o pipes and nodes
# This could be useful for monitoring multiple nodes
# using select.poll()
inToNode = {}
outToNode = {}
def outputs(): return outToNode.keys()
def nodes(): return outToNode.values()
def inputs(): return [ node.stdin for node in nodes() ]
def nodeFromFile( f ):
node = outToNode.get( f )
return node or inToNode.get( f )
class Host( Node ):
"""A host is simply a Node."""
......@@ -303,18 +301,16 @@ def stopKernelDatapath( self ):
# However, this takes time, so we're better off to remove 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.
self.cmd( 'kill %ofprotocol')
for intf in self.intfs:
quietRun( 'ip link del ' + intf )
sys.stdout.write( '.' ) ; flush()
self.cmd( 'kill %ofprotocol')
def start( self, controller ):
if self.dp is None: self.startUserDatapath( controller )
else: self.startKernelDatapath( controller )
def stop( self ):
if self.dp is None: self.stopUserDatapath()
else: self.stopKernelDatapath()
# Handle non-interaction if we've execed
self.terminate()
def sendCmd( self, cmd ):
if not self.execed: return Node.sendCmd( self, cmd )
else: print "*** Error:", self.name, "has execed and cannot accept commands"
......@@ -455,9 +451,9 @@ def configureRoutedControlNetwork( controller, switches, ips):
while not switch.intfIsUp( switch.intfs[ 0 ] ):
print "*** Waiting for ", switch.intfs[ 0 ], "to come up"
sleep( 1 )
if pingTest( hosts=[ switch, controller ] ) != 0:
print "*** Error: control network test failed"
exit( 1 )
if pingTest( hosts=[ switch, controller ] ) != 0:
print "*** Error: control network test failed"
exit( 1 )
def configHosts( hosts, ips ):
"Configure a set of hosts, starting at IP address a.b.c.d"
......@@ -535,7 +531,7 @@ def stop( self ):
print "*** Stopping switches"
for switch in self.switches:
print switch.name, ; flush()
switch.stop() ; switch.terminate()
switch.stop()
print
print "*** Stopping controller"
for controller in self.controllers:
......@@ -716,7 +712,6 @@ def iperf( hosts, verbose=False ):
"Run iperf between two hosts."
assert len( hosts ) == 2
host1, host2 = hosts[ 0 ], hosts[ 1 ]
# dumpNodes( [ host1, host2 ] )
host1.cmd( 'killall -9 iperf') # XXX shouldn't be global killall
server = host1.cmd( 'iperf -s &' )
if verbose: print server ; flush()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment