diff --git a/lib/utils.py b/lib/utils.py
index 4e8cfe7e70126fc6d3b7495eeff701215336dbc8..ade6b9b5420eb6b279fa29e73ea8aaf4ddd4bd55 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1039,6 +1039,27 @@ def WriteFile(file_name, fn=None, data=None,
   return result
 
 
+def FirstFree(seq, base=0):
+  """Returns the first non-existing integer from seq.
+
+  The seq argument should be a sorted list of positive integers. The
+  first time the index of an element is smaller than the element
+  value, the index will be returned.
+
+  The base argument is used to start at a different offset,
+  i.e. [3, 4, 6] with offset=3 will return 5.
+
+  Example: [0, 1, 3] will return 2.
+
+  """
+  for idx, elem in enumerate(seq):
+    assert elem >= base, "Passed element is higher than base offset"
+    if elem > idx + base:
+      # idx is not used
+      return idx + base
+  return None
+
+
 def all(seq, pred=bool):
   "Returns True if pred(x) is True for every element in the iterable"
   for elem in itertools.ifilterfalse(pred, seq):
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index c5f8cfda68e95fabbda4c5941ac3be60f973a06f..1d9bd2f1a57c2655f092bb15e1ddf54ffdca1d9a 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -41,7 +41,7 @@ from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \
      RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
      ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
      ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
-     SetEtcHostsEntry, RemoveEtcHostsEntry
+     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree
 from ganeti.errors import LockError, UnitParseError
 
 def _ChildHandler(signal, stack):
@@ -689,6 +689,16 @@ class TestUniqueSequence(unittest.TestCase):
     self._test(["a", "b"], ["a", "b"])
     self._test(["a", "b", "a"], ["a", "b"])
 
+class TestFirstFree(unittest.TestCase):
+  """Test case for the FirstFree function"""
+
+  def test(self):
+    """Test FirstFree"""
+    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
+    self.failUnlessEqual(FirstFree([]), None)
+    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
+    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
+    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
 
 if __name__ == '__main__':
   unittest.main()