Statistics
| Branch: | Tag: | Revision:

mininet / mininet / clean.py @ 125e6697

History | View | Annotate | Download (4.25 KB)

1 8895862a Bob Lantz
"""
2
Mininet Cleanup
3
author: Bob Lantz (rlantz@cs.stanford.edu)
4 ea420ee2 Bob Lantz

5 80be5642 Bob Lantz
Unfortunately, Mininet and OpenFlow (and the Linux kernel)
6
don't always clean up properly after themselves. Until they do
7
(or until cleanup functionality is integrated into the Python
8
code), this script may be used to get rid of unwanted garbage.
9
It may also get rid of 'false positives', but hopefully
10
nothing irreplaceable!
11 ea420ee2 Bob Lantz
"""
12
13 b1ec912d Bob Lantz
from subprocess import ( Popen, PIPE, check_output as co,
14
                         CalledProcessError )
15 5c242637 Rich Lane
import time
16 ea420ee2 Bob Lantz
17 3eb5abe6 Brandon Heller
from mininet.log import info
18 ff6145c0 Bob Lantz
from mininet.term import cleanUpScreens
19 ede34b6a Brandon Heller
20 8e63e2c5 Bob Lantz
21 8895862a Bob Lantz
def sh( cmd ):
22 723d068c Brandon Heller
    "Print a command and send it to the shell"
23 3eb5abe6 Brandon Heller
    info( cmd + '\n' )
24 8895862a Bob Lantz
    return Popen( [ '/bin/sh', '-c', cmd ], stdout=PIPE ).communicate()[ 0 ]
25 723d068c Brandon Heller
26 c265deed Bob Lantz
def killprocs( pattern ):
27
    "Reliably terminate processes matching a pattern (including args)"
28
    sh( 'pkill -9 -f %s' % pattern )
29
    # Make sure they are gone
30
    while True:
31
        try:
32 b1ec912d Bob Lantz
            pids = co( [ 'pgrep', '-f', pattern ] )
33
        except CalledProcessError:
34 c265deed Bob Lantz
            pids = ''
35
        if pids:
36 b1ec912d Bob Lantz
            sh( 'pkill -9 -f %s' % pattern )
37 8e63e2c5 Bob Lantz
            time.sleep( .5 )
38 c265deed Bob Lantz
        else:
39
            break
40
41 acdcf9b6 Bob Lantz
class Cleanup( object ):
42
    "Wrapper for cleanup()"
43
44
    callbacks = []
45
46
    @classmethod
47
    def cleanup( cls):
48
        """Clean up junk which might be left over from old runs;
49
           do fast stuff before slow dp and link removal!"""
50
51 cd02954c Bob Lantz
        info( "*** Removing excess controllers/ofprotocols/ofdatapaths/"
52
              "pings/noxes\n" )
53 acdcf9b6 Bob Lantz
        zombies = 'controller ofprotocol ofdatapath ping nox_core lt-nox_core '
54
        zombies += 'ovs-openflowd ovs-controller udpbwtest mnexec ivs'
55
        # Note: real zombie processes can't actually be killed, since they
56
        # are already (un)dead. Then again,
57
        # you can't connect to them either, so they're mostly harmless.
58
        # Send SIGTERM first to give processes a chance to shutdown cleanly.
59
        sh( 'killall ' + zombies + ' 2> /dev/null' )
60
        time.sleep( 1 )
61
        sh( 'killall -9 ' + zombies + ' 2> /dev/null' )
62
63
        # And kill off sudo mnexec
64
        sh( 'pkill -9 -f "sudo mnexec"')
65
66
        info( "*** Removing junk from /tmp\n" )
67
        sh( 'rm -f /tmp/vconn* /tmp/vlogs* /tmp/*.out /tmp/*.log' )
68
69
        info( "*** Removing old X11 tunnels\n" )
70
        cleanUpScreens()
71
72
        info( "*** Removing excess kernel datapaths\n" )
73 74c3511d Bob Lantz
        dps = sh( "ps ax | egrep -o 'dp[0-9]+' | sed 's/dp/nl:/'"
74
                  ).splitlines()
75 acdcf9b6 Bob Lantz
        for dp in dps:
76
            if dp:
77
                sh( 'dpctl deldp ' + dp )
78
79 5ac113cf Bob Lantz
        info( "***  Removing OVS datapaths\n" )
80 acdcf9b6 Bob Lantz
        dps = sh("ovs-vsctl --timeout=1 list-br").strip().splitlines()
81
        if dps:
82
            sh( "ovs-vsctl " + " -- ".join( "--if-exists del-br " + dp
83
                                            for dp in dps if dp ) )
84
        # And in case the above didn't work...
85 5ac113cf Bob Lantz
        dps = sh( "ovs-vsctl --timeout=1 list-br" ).strip().splitlines()
86 acdcf9b6 Bob Lantz
        for dp in dps:
87
            sh( 'ovs-vsctl del-br ' + dp )
88
89
        info( "*** Removing all links of the pattern foo-ethX\n" )
90
        links = sh( "ip link show | "
91 cd02954c Bob Lantz
                    "egrep -o '([-_.[:alnum:]]+-eth[[:digit:]]+)'"
92
                    ).splitlines()
93 5ac113cf Bob Lantz
        # Delete blocks of links
94
        n = 1000  # chunk size
95
        for i in xrange( 0, len( links ), n ):
96
            cmd = ';'.join( 'ip link del %s' % link
97
                             for link in links[ i : i + n ] )
98
            sh( '( %s ) 2> /dev/null' % cmd )
99 acdcf9b6 Bob Lantz
100 ec9b23ba Bob Lantz
        if 'tap9' in sh( 'ip link show' ):
101
            info( "*** Removing tap9 - assuming it's from cluster edition\n" )
102
            sh( 'ip link del tap9' )
103 cd02954c Bob Lantz
104 acdcf9b6 Bob Lantz
        info( "*** Killing stale mininet node processes\n" )
105
        killprocs( 'mininet:' )
106
107
        info( "*** Shutting down stale tunnels\n" )
108
        killprocs( 'Tunnel=Ethernet' )
109
        killprocs( '.ssh/mn')
110
        sh( 'rm -f ~/.ssh/mn/*' )
111
112
        # Call any additional cleanup code if necessary
113
        for callback in cls.callbacks:
114
            callback()
115
116
        info( "*** Cleanup complete.\n" )
117
118
    @classmethod
119
    def addCleanupCallback( cls, callback ):
120
        "Add cleanup callback"
121
        if callback not in cls.callbacks:
122
            cls.callbacks.append( callback )
123
124
125
cleanup = Cleanup.cleanup
126
addCleanupCallback = Cleanup.addCleanupCallback