Revision 50cebe67

View differences:

examples/popen.py
1 1
#!/usr/bin/python
2 2

  
3 3
"""
4
This example tests the Host.popen()/pexec() interface
4
This example monitors a number of hosts using host.popen() and
5
pmonitor()
5 6
"""
6 7

  
7 8
from mininet.net import Mininet
8 9
from mininet.node import CPULimitedHost
9 10
from mininet.topo import SingleSwitchTopo
10 11
from mininet.log import setLogLevel
11
# from mininet.cli import CLI
12
from mininet.util import custom
12
from mininet.util import custom, pmonitor
13 13

  
14
def testpopen(sched='cfs'):
15
    "Test popen() interface"
16
    host = custom( CPULimitedHost, cpu=.2, sched=sched )
17
    net = Mininet( SingleSwitchTopo( 2 ), host=host )
14
def monitorhosts( hosts=5, sched='cfs' ):
15
    "Start a bunch of pings and monitor them using popen"
16
    mytopo = SingleSwitchTopo( hosts )
17
    cpu = .5 / hosts
18
    myhost = custom( CPULimitedHost, cpu=cpu, sched=sched )
19
    net = Mininet( topo=mytopo, host=myhost )
18 20
    net.start()
19
    h1 = net.get( 'h1' )
20
    # CLI(net)
21
    out, err, code = h1.pexec( 'ifconfig' )
22
    print 'stdout:', out.strip()
23
    print 'stderr:', err.strip()
24
    print 'exit code:', code
21
    # Start a bunch of pings
22
    popens = {}
23
    last = net.hosts[ -1 ]
24
    for host in net.hosts:
25
        popens[ host ] = host.popen( "ping -c5 %s" % last.IP() )
26
        last = host
27
    # Monitor them and print output
28
    for host, line in pmonitor( popens ):
29
        if host:
30
            print "<%s>: %s" % ( host.name, line.strip() )
31
    # Done
25 32
    net.stop()
26 33

  
27 34
if __name__ == '__main__':
28 35
    setLogLevel( 'info' )
29
    testpopen('rt')
30
    testpopen('cfs')
36
    monitorhosts( hosts=5 )
mininet/util.py
1 1
"Utility functions for Mininet."
2 2

  
3
from mininet.log import output, info, error
4

  
3 5
from time import sleep
4 6
from resource import setrlimit, RLIMIT_NPROC, RLIMIT_NOFILE
5 7
from select import poll, POLLIN
6 8
from subprocess import call, check_call, Popen, PIPE, STDOUT
7
from mininet.log import output, info, error
8 9
import re
10
from fcntl import fcntl, F_GETFL, F_SETFL
11
from os import O_NONBLOCK
9 12

  
10 13
# Command execution support
11 14

  
......
300 303
    else:
301 304
        return s
302 305

  
306
# Popen support
307

  
308
def pmonitor(popens, timeoutms=500, readline=True,
309
             readmax=1024 ):
310
    """Monitor dict of hosts to popen objects
311
       a line at a time
312
       timeoutms: timeout for poll()
313
       readline: return single line of output
314
       yields: host, line/output (if any)
315
       terminates: when all EOFs received"""
316
    poller = poll()
317
    fdToHost = {}
318
    for host, popen in popens.iteritems():
319
        fd = popen.stdout.fileno()
320
        fdToHost[ fd ] = host
321
        poller.register( fd, POLLIN )
322
        if not readline:
323
            # Use non-blocking reads
324
            flags = fcntl( fd, F_GETFL )
325
            fcntl( fd, F_SETFL, flags | O_NONBLOCK )
326
    while True:
327
        fds = poller.poll( timeoutms )
328
        if fds:
329
            for fd, _event in fds:
330
                host = fdToHost[ fd ]
331
                popen = popens[ host ]
332
                if readline:
333
                    # Attempt to read a line of output
334
                    # This blocks until we receive a newline!
335
                    line = popen.stdout.readline()
336
                else:
337
                    line = popen.stdout.read( readmax )
338
                yield host, line
339
                # Check for EOF
340
                if not line:
341
                    popen.poll()
342
                    if popen.returncode is not None:
343
                        poller.unregister( fd )
344
                        del popens[ host ]
345
                        if not popens:
346
                            return
347
        else:
348
            yield None, ''
303 349

  
304 350
# Other stuff we use
305 351

  

Also available in: Unified diff