Run more jobs in parallel if we have enough loop devices.

By default, Linux ships with 8 loop devices, so we limit to 1 job
on those machines just to conserve six of the loop devices for other
processes. On buildbots, we've increased the number of loop devices to
64, so we should be able to run more jobs in parallel (up to 29 jobs,
if we have that many CPUs.)

BUG=chromium-os:19085
TEST=Run test suite with more loop devices and see it run faster.

Change-Id: I268674c6b8b48d25a569ddca61a214f7978d9f98
Reviewed-on: http://gerrit.chromium.org/gerrit/7351
Reviewed-by: Chris Sosa <sosa@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Tested-by: David James <davidjames@chromium.org>
diff --git a/au_test_harness/cros_au_test_harness.py b/au_test_harness/cros_au_test_harness.py
index 75c6885..67279e5 100755
--- a/au_test_harness/cros_au_test_harness.py
+++ b/au_test_harness/cros_au_test_harness.py
@@ -207,6 +207,16 @@
     if os.path.exists(target_vm_image_path): os.remove(target_vm_image_path)
     if os.path.exists(base_vm_image_path): os.remove(base_vm_image_path)
 
+def _CalculateDefaultJobs():
+  """Calculate how many jobs to run in parallel by default."""
+
+  # Since each job needs loop devices, limit our number of jobs to the
+  # number of loop devices divided by two. Reserve six loop devices for
+  # other processes (e.g. archiving the build in the background.)
+  loop_count = len(glob.glob('/dev/loop*')) - 6
+  cpu_count = multiprocessing.cpu_count()
+  return max(1, min(cpu_count, loop_count / 2))
+
 
 def main():
   parser = optparse.OptionParser()
@@ -221,7 +231,7 @@
                     help='Disable using delta updates.')
   parser.add_option('--no_graphics', action='store_true',
                     help='Disable graphics for the vm test.')
-  parser.add_option('-j', '--jobs', default=1,
+  parser.add_option('-j', '--jobs', default=_CalculateDefaultJobs(),
                     type=int, help='Number of simultaneous jobs')
   parser.add_option('--public_key', default=None,
                      help='Public key to use on images and updates.')