Browse Source

wait_for_bootstrap: fix a race condition

Two problems here:
   - The node status that we report on failure was not the same as
     the most recent status that we checked.  This meant that we
     could declare that we weren't bootstrapped, while declaring
     that every node was bootstrapped

   - In addition to sleeping between the bootstrap checks, we also
     slept after our final bootstrap check.  This would increase
     the likelihood of hitting the first bug above.
Nick Mathewson 5 years ago
parent
commit
65e53b7563
1 changed files with 11 additions and 5 deletions
  1. 11 5
      lib/chutney/TorNet.py

+ 11 - 5
lib/chutney/TorNet.py

@@ -1190,22 +1190,28 @@ class Network(object):
         delay = 0.5
         delay = 0.5
         controllers = [n.getController() for n in self._nodes]
         controllers = [n.getController() for n in self._nodes]
         elapsed = 0.0
         elapsed = 0.0
-        while elapsed < limit:
+        most_recent_status = [ None ] * len(controllers)
+        while True:
             all_bootstrapped = True
             all_bootstrapped = True
+            most_recent_status = [ ]
             for c in controllers:
             for c in controllers:
-                if not c.isBootstrapped():
+                pct, kwd, msg = c.getLastBootstrapStatus()
+                most_recent_status.append((pct, kwd, msg))
+                if pct != 100:
                     all_bootstrapped = False
                     all_bootstrapped = False
-                    break
+
             if all_bootstrapped:
             if all_bootstrapped:
                 print("Everything bootstrapped after %s sec"%elapsed)
                 print("Everything bootstrapped after %s sec"%elapsed)
                 return True
                 return True
+            if elapsed >= limit:
+                break
             time.sleep(delay)
             time.sleep(delay)
             elapsed += delay
             elapsed += delay
 
 
         print("Bootstrap failed. Node status:")
         print("Bootstrap failed. Node status:")
-        for c in controllers:
+        for c, status in zip(controllers,most_recent_status):
             c.check(listRunning=False, listNonRunning=True)
             c.check(listRunning=False, listNonRunning=True)
-            print("{}: {}".format(c.getNick(), c.getLastBootstrapStatus()))
+            print("{}: {}".format(c.getNick(), status))
 
 
         return False
         return False