From 67d101d48f5a3a31a43150d839b9ed903f8fc096 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 20 Aug 2009 17:12:59 +0200
Subject: [PATCH] Fix /proc/drbd parsing in presence of gaps

In case there are gaps in /proc/drbd related to the minors sequence,
this can lead to empty lines (see the attached data file). In this case,
we currently fail to parse the file correctly.

The patch fixes this by skipping empty lines in
bdev.BaseDRBD._MassageProcData and adds a data file and unittest for
this condition.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/bdev.py                         |  2 ++
 test/data/proc_drbd80-emptyline.txt | 10 ++++++++++
 test/ganeti.bdev_unittest.py        |  6 +++++-
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 test/data/proc_drbd80-emptyline.txt

diff --git a/lib/bdev.py b/lib/bdev.py
index a6dd45d06..5c2c8bf2f 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -770,6 +770,8 @@ class BaseDRBD(BlockDev):
     results = {}
     old_minor = old_line = None
     for line in data:
+      if not line: # completely empty lines, as can be returned by drbd8.0+
+        continue
       lresult = lmatch.match(line)
       if lresult is not None:
         if old_minor is not None:
diff --git a/test/data/proc_drbd80-emptyline.txt b/test/data/proc_drbd80-emptyline.txt
new file mode 100644
index 000000000..d7c3d58ac
--- /dev/null
+++ b/test/data/proc_drbd80-emptyline.txt
@@ -0,0 +1,10 @@
+GIT-hash: 5c9f89594553e32adb87d9638dce591782f947e3 build by root@node1.example.com, 2009-05-22 12:47:52
+ 0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---
+    ns:78728316 nr:0 dw:77675644 dr:1277039 al:254 bm:270 lo:0 pe:0 ua:0 ap:0
+        resync: used:0/61 hits:65657 misses:135 starving:0 dirty:0 changed:135
+        act_log: used:0/257 hits:11378843 misses:254 starving:0 dirty:0 changed:254
+ 1: cs:Unconfigured
+ 2: cs:Unconfigured
+
+ 5: cs:Unconfigured
+ 6: cs:Unconfigured
diff --git a/test/ganeti.bdev_unittest.py b/test/ganeti.bdev_unittest.py
index b2299b18d..eaf4c0768 100755
--- a/test/ganeti.bdev_unittest.py
+++ b/test/ganeti.bdev_unittest.py
@@ -114,10 +114,13 @@ class TestDRBD8Status(testutils.GanetiTestCase):
     """Read in txt data"""
     testutils.GanetiTestCase.setUp(self)
     proc_data = self._TestDataFilename("proc_drbd8.txt")
+    proc80e_data = self._TestDataFilename("proc_drbd80-emptyline.txt")
     proc83_data = self._TestDataFilename("proc_drbd83.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.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)
 
   def testIOErrors(self):
@@ -131,6 +134,7 @@ class TestDRBD8Status(testutils.GanetiTestCase):
     """Test not-found-minor in /proc"""
     self.failUnless(9 not in self.mass_data)
     self.failUnless(9 not in self.mass83_data)
+    self.failUnless(3 not in self.mass80e_data)
 
   def testLineNotMatch(self):
     """Test wrong line passed to DRBD8Status"""
@@ -154,7 +158,7 @@ class TestDRBD8Status(testutils.GanetiTestCase):
 
   def testMinor2(self):
     """Test unconfigured device"""
-    for data in [self.mass_data, self.mass83_data]:
+    for data in [self.mass_data, self.mass83_data, self.mass80e_data]:
       stats = bdev.DRBD8Status(data[2])
       self.failIf(stats.is_in_use)
 
-- 
GitLab