diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py
index 3d61634146e8471f96cbe1d3454f3d8112b22850..6dc909dcf75bb89e3d6124270c447568626d1d8f 100755
--- a/qa/ganeti-qa.py
+++ b/qa/ganeti-qa.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python -u
 #
 
-# Copyright (C) 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2007, 2008, 2009, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -354,30 +354,10 @@ def RunHardwareFailureTests(instance, pnode, snode):
             pnode, snode)
 
 
-@rapi.client.UsesRapiClient
-def main():
-  """Main program.
+def RunQa():
+  """Main QA body.
 
   """
-  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
-  parser.add_option('--yes-do-it', dest='yes_do_it',
-      action="store_true",
-      help="Really execute the tests")
-  (qa_config.options, args) = parser.parse_args()
-
-  if len(args) == 1:
-    (config_file, ) = args
-  else:
-    parser.error("Wrong number of arguments.")
-
-  if not qa_config.options.yes_do_it:
-    print ("Executing this script irreversibly destroys any Ganeti\n"
-           "configuration on all nodes involved. If you really want\n"
-           "to start testing, supply the --yes-do-it option.")
-    sys.exit(1)
-
-  qa_config.Load(config_file)
-
   rapi_user = "ganeti-qa"
   rapi_secret = utils.GenerateSecret()
 
@@ -476,5 +456,35 @@ def main():
   RunTestIf("cluster-destroy", qa_cluster.TestClusterDestroy)
 
 
+@rapi.client.UsesRapiClient
+def main():
+  """Main program.
+
+  """
+  parser = optparse.OptionParser(usage="%prog [options] <config-file>")
+  parser.add_option('--yes-do-it', dest='yes_do_it',
+      action="store_true",
+      help="Really execute the tests")
+  (qa_config.options, args) = parser.parse_args()
+
+  if len(args) == 1:
+    (config_file, ) = args
+  else:
+    parser.error("Wrong number of arguments.")
+
+  if not qa_config.options.yes_do_it:
+    print ("Executing this script irreversibly destroys any Ganeti\n"
+           "configuration on all nodes involved. If you really want\n"
+           "to start testing, supply the --yes-do-it option.")
+    sys.exit(1)
+
+  qa_config.Load(config_file)
+
+  qa_utils.StartMultiplexer(qa_config.GetMasterNode()["primary"])
+  try:
+    RunQa()
+  finally:
+    qa_utils.CloseMultiplexers()
+
 if __name__ == '__main__':
   main()
diff --git a/qa/qa_utils.py b/qa/qa_utils.py
index 110f4a38c1e38a1468a08257618ceb697a7db0a3..20856f9d420f68b99d3d6e4f1709eacb54a27e80 100644
--- a/qa/qa_utils.py
+++ b/qa/qa_utils.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2007 Google Inc.
+# Copyright (C) 2007, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@ import re
 import sys
 import subprocess
 import random
+import tempfile
 
 from ganeti import utils
 from ganeti import compat
@@ -42,6 +43,8 @@ _WARNING_SEQ = None
 _ERROR_SEQ = None
 _RESET_SEQ = None
 
+_MULTIPLEXERS = {}
+
 
 def _SetupColours():
   """Initializes the colour constants.
@@ -143,15 +146,18 @@ def AssertCommand(cmd, fail=False, node=None):
   return rcode
 
 
-def GetSSHCommand(node, cmd, strict=True):
+def GetSSHCommand(node, cmd, strict=True, opts=None):
   """Builds SSH command to be executed.
 
   @type node: string
   @param node: node the command should run on
   @type cmd: string
-  @param cmd: command to be executed in the node
+  @param cmd: command to be executed in the node; if None or empty
+      string, no command will be executed
   @type strict: boolean
   @param strict: whether to enable strict host key checking
+  @type opts: list
+  @param opts: list of additional options
 
   """
   args = [ 'ssh', '-oEscapeChar=none', '-oBatchMode=yes', '-l', 'root', '-t' ]
@@ -163,8 +169,15 @@ def GetSSHCommand(node, cmd, strict=True):
   args.append('-oStrictHostKeyChecking=%s' % tmp)
   args.append('-oClearAllForwardings=yes')
   args.append('-oForwardAgent=yes')
+  if opts:
+    args.extend(opts)
+  if node in _MULTIPLEXERS:
+    spath = _MULTIPLEXERS[node][0]
+    args.append('-oControlPath=%s' % spath)
+    args.append('-oControlMaster=no')
   args.append(node)
-  args.append(cmd)
+  if cmd:
+    args.append(cmd)
 
   return args
 
@@ -184,6 +197,34 @@ def StartSSH(node, cmd, strict=True):
   return StartLocalCommand(GetSSHCommand(node, cmd, strict=strict))
 
 
+def StartMultiplexer(node):
+  """Starts a multiplexer command.
+
+  @param node: the node for which to open the multiplexer
+
+  """
+  if node in _MULTIPLEXERS:
+    return
+
+  # Note: yes, we only need mktemp, since we'll remove the file anyway
+  sname = tempfile.mktemp(prefix="ganeti-qa-multiplexer.")
+  utils.RemoveFile(sname)
+  opts = ["-N", "-oControlPath=%s" % sname, "-oControlMaster=yes"]
+  print "Created socket at %s" % sname
+  child = StartLocalCommand(GetSSHCommand(node, None, opts=opts))
+  _MULTIPLEXERS[node] = (sname, child)
+
+
+def CloseMultiplexers():
+  """Closes all current multiplexers and cleans up.
+
+  """
+  for node in _MULTIPLEXERS.keys():
+    (sname, child) = _MULTIPLEXERS.pop(node)
+    utils.KillProcess(child.pid, timeout=10, waitpid=True)
+    utils.RemoveFile(sname)
+
+
 def GetCommandOutput(node, cmd):
   """Returns the output of a command executed on the given node.