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