Add pmonitor() to make it easy to monitor popen objects.
This commit is contained in:
+21
-15
@@ -1,30 +1,36 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This example tests the Host.popen()/pexec() interface
|
This example monitors a number of hosts using host.popen() and
|
||||||
|
pmonitor()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from mininet.net import Mininet
|
from mininet.net import Mininet
|
||||||
from mininet.node import CPULimitedHost
|
from mininet.node import CPULimitedHost
|
||||||
from mininet.topo import SingleSwitchTopo
|
from mininet.topo import SingleSwitchTopo
|
||||||
from mininet.log import setLogLevel
|
from mininet.log import setLogLevel
|
||||||
# from mininet.cli import CLI
|
from mininet.util import custom, pmonitor
|
||||||
from mininet.util import custom
|
|
||||||
|
|
||||||
def testpopen(sched='cfs'):
|
def monitorhosts( hosts=5, sched='cfs' ):
|
||||||
"Test popen() interface"
|
"Start a bunch of pings and monitor them using popen"
|
||||||
host = custom( CPULimitedHost, cpu=.2, sched=sched )
|
mytopo = SingleSwitchTopo( hosts )
|
||||||
net = Mininet( SingleSwitchTopo( 2 ), host=host )
|
cpu = .5 / hosts
|
||||||
|
myhost = custom( CPULimitedHost, cpu=cpu, sched=sched )
|
||||||
|
net = Mininet( topo=mytopo, host=myhost )
|
||||||
net.start()
|
net.start()
|
||||||
h1 = net.get( 'h1' )
|
# Start a bunch of pings
|
||||||
# CLI(net)
|
popens = {}
|
||||||
out, err, code = h1.pexec( 'ifconfig' )
|
last = net.hosts[ -1 ]
|
||||||
print 'stdout:', out.strip()
|
for host in net.hosts:
|
||||||
print 'stderr:', err.strip()
|
popens[ host ] = host.popen( "ping -c5 %s" % last.IP() )
|
||||||
print 'exit code:', code
|
last = host
|
||||||
|
# Monitor them and print output
|
||||||
|
for host, line in pmonitor( popens ):
|
||||||
|
if host:
|
||||||
|
print "<%s>: %s" % ( host.name, line.strip() )
|
||||||
|
# Done
|
||||||
net.stop()
|
net.stop()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
setLogLevel( 'info' )
|
setLogLevel( 'info' )
|
||||||
testpopen('rt')
|
monitorhosts( hosts=5 )
|
||||||
testpopen('cfs')
|
|
||||||
|
|||||||
+47
-1
@@ -1,11 +1,14 @@
|
|||||||
"Utility functions for Mininet."
|
"Utility functions for Mininet."
|
||||||
|
|
||||||
|
from mininet.log import output, info, error
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from resource import setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
|
from resource import setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
|
||||||
from select import poll, POLLIN
|
from select import poll, POLLIN
|
||||||
from subprocess import call, check_call, Popen, PIPE, STDOUT
|
from subprocess import call, check_call, Popen, PIPE, STDOUT
|
||||||
from mininet.log import output, info, error
|
|
||||||
import re
|
import re
|
||||||
|
from fcntl import fcntl, F_GETFL, F_SETFL
|
||||||
|
from os import O_NONBLOCK
|
||||||
|
|
||||||
# Command execution support
|
# Command execution support
|
||||||
|
|
||||||
@@ -300,6 +303,49 @@ def makeNumeric( s ):
|
|||||||
else:
|
else:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
# Popen support
|
||||||
|
|
||||||
|
def pmonitor(popens, timeoutms=500, readline=True,
|
||||||
|
readmax=1024 ):
|
||||||
|
"""Monitor dict of hosts to popen objects
|
||||||
|
a line at a time
|
||||||
|
timeoutms: timeout for poll()
|
||||||
|
readline: return single line of output
|
||||||
|
yields: host, line/output (if any)
|
||||||
|
terminates: when all EOFs received"""
|
||||||
|
poller = poll()
|
||||||
|
fdToHost = {}
|
||||||
|
for host, popen in popens.iteritems():
|
||||||
|
fd = popen.stdout.fileno()
|
||||||
|
fdToHost[ fd ] = host
|
||||||
|
poller.register( fd, POLLIN )
|
||||||
|
if not readline:
|
||||||
|
# Use non-blocking reads
|
||||||
|
flags = fcntl( fd, F_GETFL )
|
||||||
|
fcntl( fd, F_SETFL, flags | O_NONBLOCK )
|
||||||
|
while True:
|
||||||
|
fds = poller.poll( timeoutms )
|
||||||
|
if fds:
|
||||||
|
for fd, _event in fds:
|
||||||
|
host = fdToHost[ fd ]
|
||||||
|
popen = popens[ host ]
|
||||||
|
if readline:
|
||||||
|
# Attempt to read a line of output
|
||||||
|
# This blocks until we receive a newline!
|
||||||
|
line = popen.stdout.readline()
|
||||||
|
else:
|
||||||
|
line = popen.stdout.read( readmax )
|
||||||
|
yield host, line
|
||||||
|
# Check for EOF
|
||||||
|
if not line:
|
||||||
|
popen.poll()
|
||||||
|
if popen.returncode is not None:
|
||||||
|
poller.unregister( fd )
|
||||||
|
del popens[ host ]
|
||||||
|
if not popens:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
yield None, ''
|
||||||
|
|
||||||
# Other stuff we use
|
# Other stuff we use
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user