Wait for Node() shell to exit on Python 3

I'm not a fan of this, but Python 3's subprocess module
complains otherwise.

For now we're only doing this on Python 3. We should probably
quantify the slowdown however.
This commit is contained in:
Bob Lantz
2018-07-25 19:44:44 -07:00
parent f314a6626a
commit cac884a85e
+12 -3
View File
@@ -63,7 +63,7 @@ from time import sleep
from mininet.log import info, error, warn, debug from mininet.log import info, error, warn, debug
from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin, from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
numCores, retry, mountCgroups, BaseString, decode, numCores, retry, mountCgroups, BaseString, decode,
encode ) encode, Python3 )
from mininet.moduledeps import moduleDeps, pathCheck, TUN from mininet.moduledeps import moduleDeps, pathCheck, TUN
from mininet.link import Link, Intf, TCIntf, OVSIntf from mininet.link import Link, Intf, TCIntf, OVSIntf
from re import findall from re import findall
@@ -88,6 +88,9 @@ class Node( object ):
self.privateDirs = params.get( 'privateDirs', [] ) self.privateDirs = params.get( 'privateDirs', [] )
self.inNamespace = params.get( 'inNamespace', inNamespace ) self.inNamespace = params.get( 'inNamespace', inNamespace )
# Python 3 complains if we don't wait for shell exit
self.waitExited = params.get( 'waitExited', Python3==True )
# Stash configuration parameters for future reference # Stash configuration parameters for future reference
self.params = params self.params = params
@@ -203,7 +206,9 @@ class Node( object ):
params: parameters to Popen()""" params: parameters to Popen()"""
# Leave this is as an instance method for now # Leave this is as an instance method for now
assert self assert self
return Popen( cmd, **params ) popen = Popen( cmd, **params )
debug( '_popen', cmd, popen.pid )
return popen
def cleanup( self ): def cleanup( self ):
"Help python collect its garbage." "Help python collect its garbage."
@@ -212,6 +217,9 @@ class Node( object ):
# for intfName in self.intfNames(): # for intfName in self.intfNames():
# if self.name in intfName: # if self.name in intfName:
# quietRun( 'ip link del ' + intfName ) # quietRun( 'ip link del ' + intfName )
if self.waitExited and self.shell:
debug( 'waiting for', self.pid, 'to terminate\n' )
self.shell.wait()
self.shell = None self.shell = None
# Subshell I/O, commands and control # Subshell I/O, commands and control
@@ -724,6 +732,7 @@ class CPULimitedHost( Host ):
super( CPULimitedHost, self ).cleanup() super( CPULimitedHost, self ).cleanup()
retry( retries=3, delaySecs=.1, fn=self.cgroupDel ) retry( retries=3, delaySecs=.1, fn=self.cgroupDel )
_rtGroupSched = False # internal class var: Is CONFIG_RT_GROUP_SCHED set? _rtGroupSched = False # internal class var: Is CONFIG_RT_GROUP_SCHED set?
@classmethod @classmethod
@@ -1261,7 +1270,7 @@ class OVSSwitch( Switch ):
pids = ' '.join( str( switch.pid ) for switch in switches ) pids = ' '.join( str( switch.pid ) for switch in switches )
run( 'kill -HUP ' + pids ) run( 'kill -HUP ' + pids )
for switch in switches: for switch in switches:
switch.shell = None switch.terminate()
return switches return switches