Mininet gRPC switch startup reachability check
Just a small change to make sure the gRPC port of simple_switch_grpc
is actually opened after startup, before ONOS gets the netcfg to try
to connect to the switch. Otherwise ONOS will receive a TCP RST from
the still closed port and the connection fails, rendering the switch
devices unavailable. Also included a timeout for port opening.
Change-Id: I1338a4ba24a14be57717f636e684c91c4cb12a7c
diff --git a/tools/dev/mininet/bmv2.py b/tools/dev/mininet/bmv2.py
index 7066f61..b1824a3 100644
--- a/tools/dev/mininet/bmv2.py
+++ b/tools/dev/mininet/bmv2.py
@@ -18,8 +18,7 @@
CPU_PORT = 255
PKT_BYTES_TO_DUMP = 80
VALGRIND_PREFIX = 'valgrind --leak-check=yes'
-VALGRIND_SLEEP = 10 # seconds
-
+SWITCH_START_TIMEOUT = 5 #seconds
def parseBoolean(value):
if value in ['1', 1, 'true', 'True']:
@@ -233,11 +232,6 @@
if out:
print out
if self.netcfg:
- if self.valgrind:
- # With valgrind, it takes some time before the gRPC server is available.
- # Wait before pushing the netcfg.
- info("\n*** Waiting %d seconds before pushing the config to ONOS...\n" % VALGRIND_SLEEP)
- time.sleep(VALGRIND_SLEEP)
time.sleep(self.netcfgDelay)
try: # onos.py
@@ -246,6 +240,27 @@
clist = controllers
assert len(clist) > 0
cip = clist[0].IP()
+
+ # Wait for switch to open gRPC port, before sending ONOS the netcfg.json.
+ # Include time-out just in case something hangs.
+ if not self.dryrun:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ endtime = time.time() + SWITCH_START_TIMEOUT
+ while True:
+ result = sock.connect_ex(('127.0.0.1', self.grpcPort))
+ if result == 0:
+ # The port is open. Let's go! (Close socket first)
+ sock.close()
+ break
+ # Port is not open yet. If there is time, we wait a bit.
+ if endtime > time.time():
+ time.sleep(0.2)
+ else:
+ # Time's up.
+ raise Exception("Switch did not start before {} second timeout. Exiting.\n"
+ .format(SWITCH_START_TIMEOUT))
+ exit()
+
self.doOnosNetcfg(cip)
def stop(self, deleteIntfs=True):