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

Add pmonitor() to make it easy to monitor popen objects.

parent 237a3c54
No related branches found
No related tags found
No related merge requests found
#!/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.node import CPULimitedHost
from mininet.topo import SingleSwitchTopo
from mininet.log import setLogLevel
# from mininet.cli import CLI
from mininet.util import custom
from mininet.util import custom, pmonitor
def testpopen(sched='cfs'):
"Test popen() interface"
host = custom( CPULimitedHost, cpu=.2, sched=sched )
net = Mininet( SingleSwitchTopo( 2 ), host=host )
def monitorhosts( hosts=5, sched='cfs' ):
"Start a bunch of pings and monitor them using popen"
mytopo = SingleSwitchTopo( hosts )
cpu = .5 / hosts
myhost = custom( CPULimitedHost, cpu=cpu, sched=sched )
net = Mininet( topo=mytopo, host=myhost )
net.start()
h1 = net.get( 'h1' )
# CLI(net)
out, err, code = h1.pexec( 'ifconfig' )
print 'stdout:', out.strip()
print 'stderr:', err.strip()
print 'exit code:', code
# Start a bunch of pings
popens = {}
last = net.hosts[ -1 ]
for host in net.hosts:
popens[ host ] = host.popen( "ping -c5 %s" % last.IP() )
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()
if __name__ == '__main__':
setLogLevel( 'info' )
testpopen('rt')
testpopen('cfs')
monitorhosts( hosts=5 )
"Utility functions for Mininet."
from mininet.log import output, info, error
from time import sleep
from resource import setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
from select import poll, POLLIN
from subprocess import call, check_call, Popen, PIPE, STDOUT
from mininet.log import output, info, error
import re
from fcntl import fcntl, F_GETFL, F_SETFL
from os import O_NONBLOCK
# Command execution support
......@@ -300,6 +303,49 @@ def makeNumeric( s ):
else:
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
......
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