Previously, when creating multiple CLI objects, each one would append the
~/.mininet_history file to readline's internal list. When writing the file back
it would be duplicated for each CLI object created. So, over a few mininet runs
the history file would grow exponentially.
This change moves the readline setup code out of the CLI constructor into a
class method and adds a flag to prevent it from being executed more than once.
This was causing controlnet.py to not clean up its interfaces, since
those interfaces were linked from the controller to the switch
rather than vice-versa!!
deleteIntfs already will only delete interfaces whose names match
our name, which should usually prevent us from accidentally deleting
a hardware interface from the root namespace!
Since we already disable job notification with +m, it doesn't
make sense to set it in the original invocation!
It's also annoying if all of the host commands end up overwriting
your regular bash_history!!
Batch startup support for OVS
Currently, every ovs-vsctl command requires reading the entire OVS
configuration database. This means that its performance gets linearly
slower as more switches and ports are added. To mitigate this, we
batch multiple configuration operations into individual, long,
ovs-vsctl commands.
This patch set makes a couple of other notable changes, including
setting printPid=False by default (avoids using mnexec unnecessarily)
and running certain commands using errRun rather than quietRun.
Additionally we no longer look for leftover links in the root
namespace, so code relying on that functionality may have to change
slightly (as in controlnet.py and sshd.py for example.) It also adds
cluster support to mn -c.
The performance result is that mn --topo linear,200 --test none now
completes in 60 seconds rather than 95 seconds (on my laptop) without
the patch (vs. 101 seconds in 2.2.0).
This is still slower than I would like - we should be able to make
some additional improvements.
If you try to use the low-level API, you are probably
not going to call batchStartup()! So, we set batch=False
by default. This means that buildFromTopo() needs to set
it to True, so we add a bit of irritatingly complex machinery
to allow this to happen. The good fallout of this is that
now customConstructor() returns a real subclass, not simply
a constructor function! We also detect errors where people
are incorrectly attempting to give parameters to a lambda
function - since none of our lambdas accept parameters!!
Note that this is a bit like functools.partial for classes -
it would be nice if functools had a true subclassing function.
Note that we are changing the interface of batchStartup/Shutdown
slightly so that the method can choose not to start some of the
switches. We might wish to refine this a bit...
This should rarely happen - in the usual case, either the
links will be shut down by Mininet.stop(), or the interfaces
will be deleted by node.stop( deleteIntfs=True ), or the
links or interfaces will be explicitly deleted or stopped
using the low-level API.
Cases that are relying on links being automatically deleted
in cleanup() will potentially find that they are now no longer
deleted, but these cases should be rare.
We should think a bit about the semantics that we want here.
The comments say "stop and clean up link" so perhaps that's
what we want. However, we could also imagine stop stopping
forwarding on the link (and possibly allowing restarts).
We warn on exited node.cmd() because we terminate the controller
before stopping/deleting the links. This makes sense to avoid a
storm of link/port down events, but since the controller's
shell has exited we cannot call link.stop() on any of its
links. We may want to simply stop the controller and not
terminate it, but at least it doesn't hang for now.