diff --git a/Makefile.am b/Makefile.am
index 37acac0cdc745bd801675af6a9255ab10ed67a6b..e0b5c2ec72db2cf17eabb584af333926c41dc29f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -93,6 +93,7 @@ pkgpython_PYTHON = \
 	lib/bootstrap.py \
 	lib/cli.py \
 	lib/cmdlib.py \
+	lib/compat.py \
 	lib/config.py \
 	lib/constants.py \
 	lib/daemon.py \
@@ -321,6 +322,7 @@ python_tests = \
 	test/ganeti.bdev_unittest.py \
 	test/ganeti.cli_unittest.py \
 	test/ganeti.cmdlib_unittest.py \
+	test/ganeti.compat_unittest.py \
 	test/ganeti.confd.client_unittest.py \
 	test/ganeti.config_unittest.py \
 	test/ganeti.constants_unittest.py \
diff --git a/lib/bdev.py b/lib/bdev.py
index 5783a211e6d5c1bdde72915d2d4fef8390a4eacd..5469283ccc3ff3ab224697010eef7f2bbc504088 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -32,6 +32,7 @@ from ganeti import utils
 from ganeti import errors
 from ganeti import constants
 from ganeti import objects
+from ganeti import compat
 
 
 # Size of reads in _CanReadDevice
@@ -388,7 +389,7 @@ class LogicalVolume(BlockDev):
     pvs_info.reverse()
 
     pvlist = [ pv[1] for pv in pvs_info ]
-    if utils.any(pvlist, lambda v: ":" in v):
+    if compat.any(pvlist, lambda v: ":" in v):
       _ThrowError("Some of your PVs have the invalid character ':' in their"
                   " name, this is not supported - please filter them out"
                   " in lvm.conf using either 'filter' or 'preferred_names'")
@@ -462,7 +463,7 @@ class LogicalVolume(BlockDev):
     """
     if (not cls._VALID_NAME_RE.match(name) or
         name in cls._INVALID_NAMES or
-        utils.any(cls._INVALID_SUBSTRINGS, lambda x: x in name)):
+        compat.any(cls._INVALID_SUBSTRINGS, lambda x: x in name)):
       _ThrowError("Invalid LVM name '%s'", name)
 
   def Remove(self):
diff --git a/lib/cli.py b/lib/cli.py
index 892a60a9bbfd6faa52dc6fff477ca42887752c83..8de292c7b725d5f7ef623ded99dd1f2d5f53a5f6 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -37,6 +37,7 @@ from ganeti import luxi
 from ganeti import ssconf
 from ganeti import rpc
 from ganeti import ssh
+from ganeti import compat
 
 from optparse import (OptionParser, TitledHelpFormatter,
                       Option, OptionValueError)
@@ -2116,7 +2117,7 @@ class JobExecutor(object):
         ToStdout("Submitted jobs %s", utils.CommaJoin(ok_jobs))
 
     # first, remove any non-submitted jobs
-    self.jobs, failures = utils.partition(self.jobs, lambda x: x[1])
+    self.jobs, failures = compat.partition(self.jobs, lambda x: x[1])
     for idx, _, jid, name in failures:
       ToStderr("Failed to submit job for %s: %s", name, jid)
       results.append((idx, False, jid))
diff --git a/lib/compat.py b/lib/compat.py
new file mode 100644
index 0000000000000000000000000000000000000000..692ab246f9845ec7f48379049e2e835a8b325c2d
--- /dev/null
+++ b/lib/compat.py
@@ -0,0 +1,88 @@
+#
+#
+
+# Copyright (C) 2010 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Module containing backported language/library functionality.
+
+"""
+
+import itertools
+
+try:
+  import functools
+except ImportError:
+  functools = None
+
+
+def all(seq, pred=bool): # pylint: disable-msg=W0622
+  """Returns True if pred(x) is True for every element in the iterable.
+
+  Please note that this function provides a C{pred} parameter which isn't
+  available in the version included in Python 2.5 and above.
+
+  """
+  for _ in itertools.ifilterfalse(pred, seq):
+    return False
+  return True
+
+
+def any(seq, pred=bool): # pylint: disable-msg=W0622
+  """Returns True if pred(x) is True for at least one element in the iterable.
+
+  Please note that this function provides a C{pred} parameter which isn't
+  available in the version included in Python 2.5 and above.
+
+  """
+  for _ in itertools.ifilter(pred, seq):
+    return True
+  return False
+
+
+def partition(seq, pred=bool): # pylint: disable-msg=W0622
+  """Partition a list in two, based on the given predicate.
+
+  """
+  return (list(itertools.ifilter(pred, seq)),
+          list(itertools.ifilterfalse(pred, seq)))
+
+
+# Even though we're using Python's built-in "partial" function if available,
+# this one is always defined for testing.
+def _partial(func, *args, **keywords): # pylint: disable-msg=W0622
+  """Decorator with partial application of arguments and keywords.
+
+  This function was copied from Python's documentation.
+
+  """
+  def newfunc(*fargs, **fkeywords):
+    newkeywords = keywords.copy()
+    newkeywords.update(fkeywords)
+    return func(*(args + fargs), **newkeywords) # pylint: disable-msg=W0142
+
+  newfunc.func = func
+  newfunc.args = args
+  newfunc.keywords = keywords
+  return newfunc
+
+
+if functools is None:
+  partial = _partial
+else:
+  partial = functools.partial
diff --git a/lib/confd/client.py b/lib/confd/client.py
index 9bd9ef7fc692194b0e782bbf676a43519ba50b07..e2e0a13b80a46f86bfbe3bec8e6b3cffbdd8a892 100644
--- a/lib/confd/client.py
+++ b/lib/confd/client.py
@@ -61,6 +61,7 @@ from ganeti import daemon # contains AsyncUDPSocket
 from ganeti import errors
 from ganeti import confd
 from ganeti import ssconf
+from ganeti import compat
 
 
 class ConfdAsyncUDPClient(daemon.AsyncUDPSocket):
@@ -581,7 +582,7 @@ class ConfdCountingCallback:
     """Have all the registered queries received at least an answer?
 
     """
-    return utils.all(self._answers.values())
+    return compat.all(self._answers.values())
 
   def _HandleExpire(self, up):
     # if we have no answer we have received none, before the expiration.
diff --git a/lib/locking.py b/lib/locking.py
index aeafd3f7911db3830ff4b22c9d945fcd0185a067..3e25917c40f6e7388017e5a848f8f72933edb8ac 100644
--- a/lib/locking.py
+++ b/lib/locking.py
@@ -33,6 +33,7 @@ import errno
 
 from ganeti import errors
 from ganeti import utils
+from ganeti import compat
 
 
 def ssynchronized(lock, shared=0):
@@ -1216,7 +1217,7 @@ class GanetiLockManager:
     """
     # This way of checking only works if LEVELS[i] = i, which we check for in
     # the test cases.
-    return utils.any((self._is_owned(l) for l in LEVELS[level + 1:]))
+    return compat.any((self._is_owned(l) for l in LEVELS[level + 1:]))
 
   def _BGL_owned(self): # pylint: disable-msg=C0103
     """Check if the current thread owns the BGL.
diff --git a/lib/utils.py b/lib/utils.py
index 20a3b9b3f9a3937c2ec23df2cc1310f83a852ff0..be3a080d704d240ba9c47cd139cfc0cbfb1c14b3 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -55,11 +55,6 @@ except ImportError:
   import sha
   sha1 = sha.new
 
-try:
-  import functools
-except ImportError:
-  functools = None
-
 from ganeti import errors
 from ganeti import constants
 
@@ -1492,45 +1487,6 @@ def FirstFree(seq, base=0):
   return None
 
 
-def all(seq, pred=bool): # pylint: disable-msg=W0622
-  "Returns True if pred(x) is True for every element in the iterable"
-  for _ in itertools.ifilterfalse(pred, seq):
-    return False
-  return True
-
-
-def any(seq, pred=bool): # pylint: disable-msg=W0622
-  "Returns True if pred(x) is True for at least one element in the iterable"
-  for _ in itertools.ifilter(pred, seq):
-    return True
-  return False
-
-
-# Even though we're using Python's built-in "partial" function if available,
-# this one is always defined for testing.
-def _partial(func, *args, **keywords): # pylint: disable-msg=W0622
-  """Decorator with partial application of arguments and keywords.
-
-  This function was copied from Python's documentation.
-
-  """
-  def newfunc(*fargs, **fkeywords):
-    newkeywords = keywords.copy()
-    newkeywords.update(fkeywords)
-    return func(*(args + fargs), **newkeywords) # pylint: disable-msg=W0142
-
-  newfunc.func = func
-  newfunc.args = args
-  newfunc.keywords = keywords
-  return newfunc
-
-
-if functools is None:
-  partial = _partial
-else:
-  partial = functools.partial
-
-
 def SingleWaitForFdCondition(fdobj, event, timeout):
   """Waits for a condition to occur on the socket.
 
@@ -1622,12 +1578,6 @@ def WaitForFdCondition(fdobj, event, timeout):
   return result
 
 
-def partition(seq, pred=bool): # # pylint: disable-msg=W0622
-  "Partition a list in two, based on the given predicate"
-  return (list(itertools.ifilter(pred, seq)),
-          list(itertools.ifilterfalse(pred, seq)))
-
-
 def UniqueSequence(seq):
   """Returns a list with unique elements.
 
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index 1733a42374b2683c712dada5eef444680e564300..a215618f0c032e5126fba302083d5c83dff8fcff 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -40,6 +40,7 @@ from ganeti import bootstrap
 from ganeti import ssh
 from ganeti import objects
 from ganeti import uidpool
+from ganeti import compat
 
 
 @UsesRPC
@@ -423,7 +424,7 @@ def VerifyDisks(opts, args):
 
   if missing:
     for iname, ival in missing.iteritems():
-      all_missing = utils.all(ival, lambda x: x[0] in bad_nodes)
+      all_missing = compat.all(ival, lambda x: x[0] in bad_nodes)
       if all_missing:
         ToStdout("Instance %s cannot be verified as it lives on"
                  " broken nodes", iname)
diff --git a/test/ganeti.compat_unittest.py b/test/ganeti.compat_unittest.py
new file mode 100755
index 0000000000000000000000000000000000000000..19f82b7a8f26b8d225aea2c3dc8364afcc630719
--- /dev/null
+++ b/test/ganeti.compat_unittest.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+#
+
+# Copyright (C) 2010 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Script for unittesting the compat module"""
+
+import unittest
+
+from ganeti import compat
+
+import testutils
+
+
+class TestPartial(testutils.GanetiTestCase):
+  def test(self):
+    # Test standard version
+    self._Test(compat.partial)
+
+    # Test our version
+    self._Test(compat._partial)
+
+  def _Test(self, fn):
+    def _TestFunc1(x, power=2):
+      return x ** power
+
+    cubic = fn(_TestFunc1, power=3)
+    self.assertEqual(cubic(1), 1)
+    self.assertEqual(cubic(3), 27)
+    self.assertEqual(cubic(4), 64)
+
+    def _TestFunc2(*args, **kwargs):
+      return (args, kwargs)
+
+    self.assertEqualValues(fn(_TestFunc2, "Hello", "World")("Foo"),
+                           (("Hello", "World", "Foo"), {}))
+
+    self.assertEqualValues(fn(_TestFunc2, "Hello", xyz=123)("Foo"),
+                           (("Hello", "Foo"), {"xyz": 123}))
+
+    self.assertEqualValues(fn(_TestFunc2, xyz=123)("Foo", xyz=999),
+                           (("Foo", ), {"xyz": 999,}))
+
+
+if __name__ == "__main__":
+  testutils.GanetiTestProgram()
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index fa900c934a3881b6b3b0847f20870200087e48e9..6adb630b885a5074d1b9b89badb8830e604ef6b8 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -1592,32 +1592,5 @@ class TestLineSplitter(unittest.TestCase):
                              "", "x"])
 
 
-class TestPartial(testutils.GanetiTestCase):
-  def test(self):
-    self._Test(utils.partial)
-    self._Test(utils._partial)
-
-  def _Test(self, fn):
-    def _TestFunc1(x, power=2):
-      return x ** power
-
-    cubic = fn(_TestFunc1, power=3)
-    self.assertEqual(cubic(1), 1)
-    self.assertEqual(cubic(3), 27)
-    self.assertEqual(cubic(4), 64)
-
-    def _TestFunc2(*args, **kwargs):
-      return (args, kwargs)
-
-    self.assertEqualValues(fn(_TestFunc2, "Hello", "World")("Foo"),
-                           (("Hello", "World", "Foo"), {}))
-
-    self.assertEqualValues(fn(_TestFunc2, "Hello", xyz=123)("Foo"),
-                           (("Hello", "Foo"), {"xyz": 123}))
-
-    self.assertEqualValues(fn(_TestFunc2, xyz=123)("Foo", xyz=999),
-                           (("Foo", ), {"xyz": 999,}))
-
-
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
diff --git a/tools/burnin b/tools/burnin
index e9008ef937ee2fb537b366c1038e457afabf2af1..17e58500105a558eac84964b9af246346bb5ec15 100755
--- a/tools/burnin
+++ b/tools/burnin
@@ -37,6 +37,7 @@ from ganeti import cli
 from ganeti import errors
 from ganeti import utils
 from ganeti import hypervisor
+from ganeti import compat
 
 from ganeti.confd import client as confd_client
 
@@ -982,7 +983,7 @@ class Burner(object):
         self.BurnReplaceDisks2()
 
       if (opts.disk_template in constants.DTS_GROWABLE and
-          utils.any(self.disk_growth, lambda n: n > 0)):
+          compat.any(self.disk_growth, lambda n: n > 0)):
         self.BurnGrowDisks()
 
       if opts.do_failover and opts.disk_template in constants.DTS_NET_MIRROR: