diff --git a/Makefile.am b/Makefile.am
index 444b53e26df45e6778066ca09ca0f539a527277a..3f67337ab93b4ec1f9a9960b9379f532e7073310 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -631,6 +631,8 @@ TEST_FILES = \
 	test/data/proc_drbd8.txt \
 	test/data/proc_drbd80-emptyline.txt \
 	test/data/proc_drbd83.txt \
+	test/data/proc_drbd83_sync.txt \
+	test/data/proc_drbd83_sync_krnl2.6.39.txt \
 	test/data/sys_drbd_usermode_helper.txt \
 	test/import-export_unittest-helper
 
diff --git a/NEWS b/NEWS
index a6689a3ef173d835028c499f5f240bcd4eeb1a56..9c6a1e398290ac5a2da6072400d0bb5b4a18b94f 100644
--- a/NEWS
+++ b/NEWS
@@ -136,6 +136,18 @@ Version 2.5.0 beta1
 This was the first beta release of the 2.5 series.
 
 
+Version 2.4.4
+-------------
+
+*(Released Tue, 23 Aug 2011)*
+
+Small bug-fixes:
+
+- Fixed documentation for importing with ``--src-dir`` option
+- Fixed a bug in ``ensure-dirs`` with queue/archive permissions
+- Fixed a parsing issue with DRBD 8.3.11 in the Linux kernel
+
+
 Version 2.4.3
 -------------
 
@@ -167,7 +179,7 @@ Many bug-fixes and a few small features:
 - Fixed off-by-one bug in job serial generation
 - ``gnt-node volumes``: Fix instance names
 - Fixed aliases in bash completion
-- Fixed a bug in reopening log files after beeing sent a SIGHUP
+- Fixed a bug in reopening log files after being sent a SIGHUP
 - Added a flag to burnin to allow specifying VCPU count
 - Bugfixes to non-root Ganeti configuration
 
diff --git a/doc/admin.rst b/doc/admin.rst
index b366def1026000222299ec2fe4812113ac21ae8b..665c0e638ccbe82fc4432c5f55c20ab2ec23a568 100644
--- a/doc/admin.rst
+++ b/doc/admin.rst
@@ -391,16 +391,16 @@ parameters as such:
 - ``root_path`` to a valid setting (e.g. ``/dev/xvda1``)
 - ``bootloader_path`` and ``bootloader_args`` to empty
 
-Alternatively, you can delete the kernel management to instances, and
+Alternatively, you can delegate the kernel management to instances, and
 use either ``pvgrub`` or the deprecated ``pygrub``. For this, you must
-install the kernels and initrds in the instance, and create a valid grub
+install the kernels and initrds in the instance and create a valid GRUB
 v1 configuration file.
 
 For ``pvgrub`` (new in version 2.4.2), you need to set:
 
 - ``kernel_path`` to point to the ``pvgrub`` loader present on the node
   (e.g. ``/usr/lib/xen/boot/pv-grub-x86_32.gz``)
-- ``kernel_args`` to the path to the grub config file, relative to the
+- ``kernel_args`` to the path to the GRUB config file, relative to the
   instance (e.g. ``(hd0,0)/grub/menu.lst``)
 - ``root_path`` **must** be empty
 - ``bootloader_path`` and ``bootloader_args`` to empty
diff --git a/lib/bdev.py b/lib/bdev.py
index 905ad1fc13b7f6490977776a986e6dd5d9ac95e2..604a5b4118170f22256db22353e36c09ba382be4 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -791,7 +791,10 @@ class DRBD8Status(object):
   LINE_RE = re.compile(r"\s*[0-9]+:\s*cs:(\S+)\s+(?:st|ro):([^/]+)/(\S+)"
                        "\s+ds:([^/]+)/(\S+)\s+.*$")
   SYNC_RE = re.compile(r"^.*\ssync'ed:\s*([0-9.]+)%.*"
-                       "\sfinish: ([0-9]+):([0-9]+):([0-9]+)\s.*$")
+                       # Due to a bug in drbd in the kernel, introduced in
+                       # commit 4b0715f096 (still unfixed as of 2011-08-22)
+                       "(?:\s|M)"
+                       "finish: ([0-9]+):([0-9]+):([0-9]+)\s.*$")
 
   CS_UNCONFIGURED = "Unconfigured"
   CS_STANDALONE = "StandAlone"
diff --git a/lib/utils/text.py b/lib/utils/text.py
index a4c2777ecda452f022cd63551be8a89b36f1846d..ab9c427a4ae5a23976f2d464a70cc4a1f4669b99 100644
--- a/lib/utils/text.py
+++ b/lib/utils/text.py
@@ -381,7 +381,7 @@ def UnescapeAndSplit(text, sep=","):
     e1 = slist.pop(0)
     if e1.endswith("\\"):
       num_b = len(e1) - len(e1.rstrip("\\"))
-      if num_b % 2 == 1:
+      if num_b % 2 == 1 and slist:
         e2 = slist.pop(0)
         # here the backslashes remain (all), and will be reduced in
         # the next step
diff --git a/test/data/proc_drbd83_sync.txt b/test/data/proc_drbd83_sync.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ae94186ccab349653a265a26a79ad25693609db9
Binary files /dev/null and b/test/data/proc_drbd83_sync.txt differ
diff --git a/test/data/proc_drbd83_sync_krnl2.6.39.txt b/test/data/proc_drbd83_sync_krnl2.6.39.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf3f541d3c52a7c26bf77657133ac27d15a389fd
Binary files /dev/null and b/test/data/proc_drbd83_sync_krnl2.6.39.txt differ
diff --git a/test/ganeti.bdev_unittest.py b/test/ganeti.bdev_unittest.py
index fa1433ec169ab648a08033c2c22834a50da53c54..6f8e3d40adc1616146f36fedba55cd01daee2abc 100755
--- a/test/ganeti.bdev_unittest.py
+++ b/test/ganeti.bdev_unittest.py
@@ -166,12 +166,21 @@ class TestDRBD8Status(testutils.GanetiTestCase):
     proc_data = self._TestDataFilename("proc_drbd8.txt")
     proc80e_data = self._TestDataFilename("proc_drbd80-emptyline.txt")
     proc83_data = self._TestDataFilename("proc_drbd83.txt")
+    proc83_sync_data = self._TestDataFilename("proc_drbd83_sync.txt")
+    proc83_sync_krnl_data = \
+      self._TestDataFilename("proc_drbd83_sync_krnl2.6.39.txt")
     self.proc_data = bdev.DRBD8._GetProcData(filename=proc_data)
     self.proc80e_data = bdev.DRBD8._GetProcData(filename=proc80e_data)
     self.proc83_data = bdev.DRBD8._GetProcData(filename=proc83_data)
+    self.proc83_sync_data = bdev.DRBD8._GetProcData(filename=proc83_sync_data)
+    self.proc83_sync_krnl_data = \
+      bdev.DRBD8._GetProcData(filename=proc83_sync_krnl_data)
     self.mass_data = bdev.DRBD8._MassageProcData(self.proc_data)
     self.mass80e_data = bdev.DRBD8._MassageProcData(self.proc80e_data)
     self.mass83_data = bdev.DRBD8._MassageProcData(self.proc83_data)
+    self.mass83_sync_data = bdev.DRBD8._MassageProcData(self.proc83_sync_data)
+    self.mass83_sync_krnl_data = \
+      bdev.DRBD8._MassageProcData(self.proc83_sync_krnl_data)
 
   def testIOErrors(self):
     """Test handling of errors while reading the proc file."""
@@ -251,5 +260,15 @@ class TestDRBD8Status(testutils.GanetiTestCase):
                       stats.rrole == 'Unknown' and
                       stats.is_disk_uptodate)
 
+  def testDRBD83SyncFine(self):
+    stats = bdev.DRBD8Status(self.mass83_sync_data[3])
+    self.failUnless(stats.is_in_resync)
+    self.failUnless(stats.sync_percent is not None)
+
+  def testDRBD83SyncBroken(self):
+    stats = bdev.DRBD8Status(self.mass83_sync_krnl_data[3])
+    self.failUnless(stats.is_in_resync)
+    self.failUnless(stats.sync_percent is not None)
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
diff --git a/test/ganeti.utils.text_unittest.py b/test/ganeti.utils.text_unittest.py
index 5181db4d36aa963d1f552d59650039d186d0a696..91039e173a765a1bbb6eddc09edda95b4d651d7c 100755
--- a/test/ganeti.utils.text_unittest.py
+++ b/test/ganeti.utils.text_unittest.py
@@ -350,7 +350,7 @@ class TestUnescapeAndSplit(unittest.TestCase):
 
   def setUp(self):
     # testing more that one separator for regexp safety
-    self._seps = [",", "+", "."]
+    self._seps = [",", "+", ".", ":"]
 
   def testSimple(self):
     a = ["a", "b", "c", "d"]
@@ -375,6 +375,18 @@ class TestUnescapeAndSplit(unittest.TestCase):
       b = ["a", "b\\" + sep + "c", "d"]
       self.failUnlessEqual(utils.UnescapeAndSplit(sep.join(a), sep=sep), b)
 
+  def testEscapeAtEnd(self):
+    for sep in self._seps:
+      self.assertEqual(utils.UnescapeAndSplit("\\", sep=sep), ["\\"])
+
+      a = ["a", "b\\", "c"]
+      b = ["a", "b" + sep + "c\\"]
+      self.assertEqual(utils.UnescapeAndSplit("%s\\" % sep.join(a), sep=sep), b)
+
+      a = ["\\" + sep, "\\" + sep, "c", "d\\.moo"]
+      b = [sep, sep, "c", "d.moo\\"]
+      self.assertEqual(utils.UnescapeAndSplit("%s\\" % sep.join(a), sep=sep), b)
+
 
 class TestCommaJoin(unittest.TestCase):
   def test(self):