Merge branch 'master' of github.com:OPENNETWORKINGLAB/ONOS
diff --git a/cluster-mgmt/bin/test-link-failure.sh b/cluster-mgmt/bin/test-link-failure.sh
index c513618..6c5f128 100755
--- a/cluster-mgmt/bin/test-link-failure.sh
+++ b/cluster-mgmt/bin/test-link-failure.sh
@@ -1,7 +1,17 @@
 #! /bin/sh
 basename=$ONOS_CLUSTER_BASENAME
+wait=10
 
 fdef="flowdef_8node_42.txt"
+
+function log()
+{
+    date > error.$1.$2.log
+    check_status.py >> error.$1.$2.log
+    dsh -w ${basename}1 "cd ONOS/web; ./get_flow.py all" >> error.$1.$2.log
+    dsh "cd ONOS/scripts; ./showflow.sh"             >> error.$1.$2.log
+}
+
 echo "all links up"
 dsh -w ${basename}1 "cd ONOS/scripts; ./all-linkup.sh"
 echo "clean up flow"
@@ -11,27 +21,35 @@
 dsh -w ${basename}1 "cd ONOS/web; ./get_flow.py all"
 dsh "cd ONOS/scripts; ./delflow.sh"
 echo "checkup status"
-./check_status.py
+check_status.py
 read -p "hit anykey> "
 
 echo "install pre-set flows"
 dsh -w ${basename}1 "cd ONOS/web; ./add_flow.py -m onos -f $fdef"
-sleep 3
+sleep 6
 echo "check"
 dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"
 
-ports=`dsh -w ${basename}1 "cd ONOS/scripts; ./listports.sh" | awk '{print $2}' |grep -v tap`
+#ports=`dsh -w ${basename}1 "cd ONOS/scripts; ./listports.sh" | awk '{print $2}' |grep -v tap`
+operation=("sw3-eth3 down" "sw4-eth4 down" "sw4-eth3 down" "sw3-eth3 up" "sw1-eth2 down" "sw4-eth4 up" "sw4-eth3 up" "sw1-eth2 up")
 
-for p in $ports; do
-  echo "port $p down"
-  read -p "hit anykey> "
-  dsh -w ${basename}1 "sudo ifconfig $p down"
-  echo "wait 3 sec"
-  sleep 3
-  dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"
-  echo "port $p up"
-  dsh -w ${basename}1 "sudo ifconfig $p up"
-  echo "wait 3 sec"
-  sleep 3
-  dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"
+((n=0))
+while [ 1 ] ; do
+  for (( i = 0; i< ${#operation[@]}; i ++)); do
+    echo "Test $n-$i"
+    p=`echo ${operation[$i]}`
+    echo "operation: $p"
+#  read -p "hit anykey> "
+    dsh -w ${basename}1 "sudo ifconfig $p"
+    echo "wait $wait sec"
+    sleep $wait 
+    result=`dsh -w ${basename}1 "cd ONOS/web; ./pingall.py $fdef"`
+    echo $result
+    nr_fail=`echo $result |grep fail | wc -l`
+    if [ $nr_fail -gt 0 ]; then
+      log $n $i
+    fi
+  done
+  ((n++))
 done
+
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 098e02f..f9177f2 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -265,6 +265,12 @@
 
     final Runnable mapReader = new Runnable() {
 	    public void run() {
+		long startTime = System.nanoTime();
+		int counterAllFlowEntries = 0;
+		int counterMyNotUpdatedFlowEntries = 0;
+		int counterAllFlowPaths = 0;
+		int counterMyFlowPaths = 0;
+
 		if (floodlightProvider == null) {
 		    log.debug("FloodlightProvider service not found!");
 		    return;
@@ -284,6 +290,7 @@
 		Iterable<IFlowEntry> allFlowEntries =
 		    conn.utils().getAllFlowEntries(conn);
 		for (IFlowEntry flowEntryObj : allFlowEntries) {
+		    counterAllFlowEntries++;
 		    String flowEntryIdStr = flowEntryObj.getFlowEntryId();
 		    String userState = flowEntryObj.getUserState();
 		    String switchState = flowEntryObj.getSwitchState();
@@ -321,6 +328,7 @@
 		//
 		boolean processed_measurement_flow = false;
 		for (Map.Entry<Long, IFlowEntry> entry : myFlowEntries.entrySet()) {
+		    counterMyNotUpdatedFlowEntries++;
 		    IFlowEntry flowEntryObj = entry.getValue();
 		    IFlowPath flowObj =
 			conn.utils().getFlowPathByFlowEntry(conn,
@@ -523,6 +531,7 @@
 		Iterable<IFlowPath> allFlowPaths = conn.utils().getAllFlowPaths(conn);
 		HashSet<IFlowPath> flowObjSet = new HashSet<IFlowPath>();
 		for (IFlowPath flowPathObj : allFlowPaths) {
+		    counterAllFlowPaths++;
 		    if (flowPathObj == null)
 			continue;
 		    String dataPathSummaryStr = flowPathObj.getDataPathSummary();
@@ -553,6 +562,21 @@
 		    Port dstPort = new Port(dstPortShort);
 		    SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
 		    SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+		    //
+		    // Use the source DPID as a heuristic to decide
+		    // which controller is responsible for maintaining the
+		    // shortest path.
+		    // NOTE: This heuristic is error-prone: if the switch
+		    // goes away and no controller is responsible for that
+		    // switch, then the original Flow Path is not cleaned-up
+		    //
+		    IOFSwitch mySwitch = mySwitches.get(srcDpid.value());
+		    if (mySwitch == null)
+			continue;	// Ignore: not my responsibility
+
+		    counterMyFlowPaths++;
+
 		    //
 		    // NOTE: Using here the regular getShortestPath() method
 		    // won't work here, because that method calls internally
@@ -576,18 +600,6 @@
 		    if (dataPathSummaryStr.equals(newDataPathSummaryStr))
 			continue;	// Nothing changed
 
-		    //
-		    // Use the source DPID as a heuristic to decide
-		    // which controller is responsible for maintaining the
-		    // shortest path.
-		    // NOTE: This heuristic is error-prone: if the switch
-		    // goes away and no controller is responsible for that
-		    // switch, then the original Flow Path is not cleaned-up
-		    //
-		    IOFSwitch mySwitch = mySwitches.get(srcDpid.value());
-		    if (mySwitch == null)
-			continue;	// Ignore: not my responsibility
-
 		    log.debug("RECONCILE: Need to Reconcile Shortest Path for FlowID {}",
 			      flowId.toString());
 		    flowObjSet.add(flowPathObj);
@@ -604,6 +616,11 @@
 			(double)estimatedTime / 1000000000 + " sec";
 		    log.debug(logMsg);
 		}
+
+		long estimatedTime = System.nanoTime() - startTime;
+		double rate = (estimatedTime > 0)? ((double)counterAllFlowPaths * 1000000000) / estimatedTime: 0.0;
+		String logMsg = "MEASUREMENT: Processed AllFlowEntries: " + counterAllFlowEntries + " MyNotUpdatedFlowEntries: " + counterMyNotUpdatedFlowEntries + " AllFlowPaths: " + counterAllFlowPaths + " MyFlowPaths: " + counterMyFlowPaths + " in " + (double)estimatedTime / 1000000000 + " sec: " + rate + " paths/s";
+		log.debug(logMsg);
 	    }
 	};
 
diff --git a/start-onos.sh b/start-onos.sh
index 58f04b8..1263b8a 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -12,11 +12,11 @@
 
 # Set JVM options
 JVM_OPTS=""
-#JVM_OPTS="$JVM_OPTS -server -d64"
-#JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
-#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
-#JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
-#JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
+JVM_OPTS="$JVM_OPTS -server -d64"
+JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
+JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
 #JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
 
 # Set classpath to include titan libs