Add ability to pause and resume any node

This commit is contained in:
Brandon Heller
2010-03-13 21:35:52 -08:00
parent 28cd95c374
commit 07aad11081
2 changed files with 80 additions and 0 deletions
+20
View File
@@ -157,6 +157,26 @@ class CLI( Cmd ):
else:
self.mn.link( *args )
def do_pause( self, args ):
"Temporarily bring a node down."
args = args.split()
if len(args) != 1:
error( 'invalid number of args: pause [node]\n' )
elif args[0] not in self.nodemap:
error( 'invalid node: %s\n' % args[0] )
else:
self.nodemap[ args[ 0 ] ].pause()
def do_resume( self, args ):
"Temporarily bring a node up."
args = args.split()
if len(args) != 1:
error( 'invalid number of args: resume [node]\n' )
elif args[0] not in self.nodemap:
error( 'invalid node: %s\n' % args[0] )
else:
self.nodemap[ args[ 0 ] ].resume()
def do_exit( self, args ):
"Exit"
return 'exited by user command'
+60
View File
@@ -337,6 +337,12 @@ class Node( object ):
"Check if an interface is up."
return 'UP' in self.cmd( 'ifconfig ' + intf )
def modIntfs( self, action ):
"""Bring all interfaces up or down.
action: string to pass to ifconfig"""
for intf in self.intfs.values():
result = self.cmd( [ 'ifconfig', intf, action ] )
# Other methods
def __str__( self ):
result = self.name + ':'
@@ -351,6 +357,16 @@ class Host( Node ):
"A host is simply a Node."
pass
# Ideally, pausing a host would pause the process. However, when one
# tries to run a command on a paused host, it leads to an exception later.
# For now, disable interfaces to "pause" the host.
def pause( self ):
"Disable interfaces."
self.modIntfs('down')
def resume( self ):
"Re-enable interfaces"
self.modIntfs('up')
class Switch( Node ):
"""A Switch is a Node that is running (or has execed?)
@@ -405,6 +421,17 @@ class UserSwitch( Switch ):
self.cmd( 'kill %ofprotocol' )
self.deleteIntfs()
def pause( self ):
"Pause ofprotocol and ofdatapath."
self.cmd( 'kill -STOP %ofdatapath' )
self.cmd( 'kill -STOP %ofprotocol' )
def resume( self ):
"Resume ofprotocol and datapath."
self.cmd( 'kill -CONT %ofdatapath' )
self.cmd( 'kill -CONT %ofprotocol' )
class KernelSwitch( Switch ):
"""Kernel-space switch.
Currently only works in root namespace."""
@@ -452,6 +479,18 @@ class KernelSwitch( Switch ):
self.cmd( 'kill %ofprotocol' )
self.deleteIntfs()
# Since kernel threads cannot receive signals like user-space processes,
# disabling the interfaces and ofdatapath is our workaround.
def pause( self ):
"Disable interfaces and pause ofprotocol."
self.cmd( 'kill -STOP %ofprotocol' )
self.modIntfs('down')
def resume( self ):
"Re-enable interfaces and resume ofprotocol."
self.cmd( 'kill -CONT %ofprotocol' )
self.modIntfs('up')
class OVSKernelSwitch( Switch ):
"""Open VSwitch kernel-space switch.
Currently only works in the root namespace."""
@@ -500,6 +539,18 @@ class OVSKernelSwitch( Switch ):
self.cmd( 'kill %ovs-openflowd' )
self.deleteIntfs()
# Since kernel threads cannot receive signals like user-space processes,
# disabling the interfaces and ofdatapath is our workaround.
def pause( self ):
"Disable interfaces and pause ovs-openflowd."
self.cmd( 'kill -STOP %ovs-openflowd' )
self.modIntfs('down')
def resume( self ):
"Re-enable interfaces and resume ovs-openflowd."
self.cmd( 'kill -CONT %ovs-openflowd' )
self.modIntfs('up')
class Controller( Node ):
"""A Controller is a Node that is running (or has execed?) an
@@ -530,6 +581,14 @@ class Controller( Node ):
self.cmd( 'kill %' + self.controller )
self.terminate()
def pause( self ):
"Pause controller."
self.cmd( 'kill -STOP %' + self.controller )
def resume( self ):
"Resume controller."
self.cmd( 'kill -CONT %' + self.controller )
def IP( self, intf=None ):
"Return IP address of the Controller"
ip = Node.IP( self, intf=intf )
@@ -537,6 +596,7 @@ class Controller( Node ):
ip = self.defaultIP
return ip
class ControllerParams( object ):
"Container for controller IP parameters."