From 01e2ce3a6e4ca68983f50dedaddd0d0fc7b77026 Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Tue, 5 May 2009 12:48:50 +0200 Subject: [PATCH 1/1] Fix compatibility with DRBD 8.3 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit DRBD 8.3 changes two more things compared to 8.2: - /proc/drbd format changed in multiple ways; the part we're interested is the ‘st:’ to ‘ro:‘ change (in the changelog named as “Renamed 'state' to 'role'” - “drbdsetup /dev/drbdN show” changed the ‘device’ stanza from: device "/dev/drbd0"; to: device minor 0; This patch fixes these both and adds data files and unittests for DRBD 8.3.1. Signed-off-by: Iustin Pop --- lib/bdev.py | 7 ++-- test/data/bdev-8.3-both.txt | 36 +++++++++++++++++++++ test/data/proc_drbd83.txt | Bin 0 -> 1197 bytes test/ganeti.bdev_unittest.py | 73 +++++++++++++++++++++++++++--------------- 4 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 test/data/bdev-8.3-both.txt create mode 100644 test/data/proc_drbd83.txt diff --git a/lib/bdev.py b/lib/bdev.py index 94e8ab8..9d3f08b 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -563,7 +563,7 @@ class DRBD8Status(object): """ UNCONF_RE = re.compile(r"\s*[0-9]+:\s*cs:Unconfigured$") - LINE_RE = re.compile(r"\s*[0-9]+:\s*cs:(\S+)\s+st:([^/]+)/(\S+)" + 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.*$") @@ -903,10 +903,13 @@ class DRBD8(BaseDRBD): # meta device, extended syntax meta_value = ((value ^ quoted) + pyp.Literal('[').suppress() + number + pyp.Word(']').suppress()) + # device name, extended syntax + device_value = pyp.Literal("minor").suppress() + number # a statement stmt = (~rbrace + keyword + ~lbrace + - pyp.Optional(addr_port ^ value ^ quoted ^ meta_value) + + pyp.Optional(addr_port ^ value ^ quoted ^ meta_value ^ + device_value) + pyp.Optional(defa) + semi + pyp.Optional(pyp.restOfLine).suppress()) diff --git a/test/data/bdev-8.3-both.txt b/test/data/bdev-8.3-both.txt new file mode 100644 index 0000000..bc6e741 --- /dev/null +++ b/test/data/bdev-8.3-both.txt @@ -0,0 +1,36 @@ +disk { + size 0s _is_default; # bytes + on-io-error detach; + fencing dont-care _is_default; + max-bio-bvecs 0 _is_default; +} +net { + timeout 60 _is_default; # 1/10 seconds + max-epoch-size 2048 _is_default; + max-buffers 2048 _is_default; + unplug-watermark 128 _is_default; + connect-int 10 _is_default; # seconds + ping-int 10 _is_default; # seconds + sndbuf-size 131070 _is_default; # bytes + ko-count 0 _is_default; + after-sb-0pri discard-zero-changes; + after-sb-1pri consensus; + after-sb-2pri disconnect _is_default; + rr-conflict disconnect _is_default; + ping-timeout 5 _is_default; # 1/10 seconds +} +syncer { + rate 61440k; # bytes/second + after -1 _is_default; + al-extents 257; +} +protocol C; +_this_host { + device minor 0; + disk "/dev/xenvg/test.data"; + meta-disk "/dev/xenvg/test.meta" [ 0 ]; + address ipv4 192.168.1.1:11000; +} +_remote_host { + address ipv4 192.168.1.2:11000; +} diff --git a/test/data/proc_drbd83.txt b/test/data/proc_drbd83.txt new file mode 100644 index 0000000000000000000000000000000000000000..114944c723814c8d59a9617d61f2370d59795b50 GIT binary patch literal 1197 zcmcJO(Q3jl6oz-*r#P1zteUh@lXJD9Z0v5Jvg_ESvsjao)QNAuSghMrbi$U4!yy#< z@qd3lwDW~E2)vVaDBQ}bK+e0Bv$aLukGZ&uo?j;MT>3det{BOg z3co0|_g7n`;&Oz0tNmlFlU7@r!?GP)4UG$B+jTG0?P{xolLo)2T3z3tz=6YmpyCbH VxRypeme%NPtA5D@&9nS_rca$VVDbO} literal 0 HcmV?d00001 diff --git a/test/ganeti.bdev_unittest.py b/test/ganeti.bdev_unittest.py index 2db785c..b2299b1 100755 --- a/test/ganeti.bdev_unittest.py +++ b/test/ganeti.bdev_unittest.py @@ -61,7 +61,7 @@ class TestDRBD8Runner(testutils.GanetiTestCase): """Test drbdsetup show parser creation""" bdev.DRBD8._GetShowParser() - def testParserBoth(self): + def testParserBoth80(self): """Test drbdsetup show parser for disk and network""" data = self._ReadTestData("bdev-both.txt") result = bdev.DRBD8._GetDevInfo(data) @@ -70,7 +70,18 @@ class TestDRBD8Runner(testutils.GanetiTestCase): "Wrong local disk info") self.failUnless(self._has_net(result, ("192.168.1.1", 11000), ("192.168.1.2", 11000)), - "Wrong network info") + "Wrong network info (8.0.x)") + + def testParserBoth83(self): + """Test drbdsetup show parser for disk and network""" + data = self._ReadTestData("bdev-8.3-both.txt") + result = bdev.DRBD8._GetDevInfo(data) + self.failUnless(self._has_disk(result, "/dev/xenvg/test.data", + "/dev/xenvg/test.meta"), + "Wrong local disk info") + self.failUnless(self._has_net(result, ("192.168.1.1", 11000), + ("192.168.1.2", 11000)), + "Wrong network info (8.2.x)") def testParserNet(self): """Test drbdsetup show parser for disk and network""" @@ -103,8 +114,11 @@ class TestDRBD8Status(testutils.GanetiTestCase): """Read in txt data""" testutils.GanetiTestCase.setUp(self) proc_data = self._TestDataFilename("proc_drbd8.txt") + proc83_data = self._TestDataFilename("proc_drbd83.txt") self.proc_data = bdev.DRBD8._GetProcData(filename=proc_data) + self.proc83_data = bdev.DRBD8._GetProcData(filename=proc83_data) self.mass_data = bdev.DRBD8._MassageProcData(self.proc_data) + self.mass83_data = bdev.DRBD8._MassageProcData(self.proc83_data) def testIOErrors(self): """Test handling of errors while reading the proc file.""" @@ -116,6 +130,7 @@ class TestDRBD8Status(testutils.GanetiTestCase): def testMinorNotFound(self): """Test not-found-minor in /proc""" self.failUnless(9 not in self.mass_data) + self.failUnless(9 not in self.mass83_data) def testLineNotMatch(self): """Test wrong line passed to DRBD8Status""" @@ -123,45 +138,51 @@ class TestDRBD8Status(testutils.GanetiTestCase): def testMinor0(self): """Test connected, primary device""" - stats = bdev.DRBD8Status(self.mass_data[0]) - self.failUnless(stats.is_in_use) - self.failUnless(stats.is_connected and stats.is_primary and - stats.peer_secondary and stats.is_disk_uptodate) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[0]) + self.failUnless(stats.is_in_use) + self.failUnless(stats.is_connected and stats.is_primary and + stats.peer_secondary and stats.is_disk_uptodate) def testMinor1(self): """Test connected, secondary device""" - stats = bdev.DRBD8Status(self.mass_data[1]) - self.failUnless(stats.is_in_use) - self.failUnless(stats.is_connected and stats.is_secondary and - stats.peer_primary and stats.is_disk_uptodate) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[1]) + self.failUnless(stats.is_in_use) + self.failUnless(stats.is_connected and stats.is_secondary and + stats.peer_primary and stats.is_disk_uptodate) def testMinor2(self): """Test unconfigured device""" - stats = bdev.DRBD8Status(self.mass_data[2]) - self.failIf(stats.is_in_use) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[2]) + self.failIf(stats.is_in_use) def testMinor4(self): """Test WFconn device""" - stats = bdev.DRBD8Status(self.mass_data[4]) - self.failUnless(stats.is_in_use) - self.failUnless(stats.is_wfconn and stats.is_primary and - stats.rrole == 'Unknown' and - stats.is_disk_uptodate) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[4]) + self.failUnless(stats.is_in_use) + self.failUnless(stats.is_wfconn and stats.is_primary and + stats.rrole == 'Unknown' and + stats.is_disk_uptodate) def testMinor6(self): """Test diskless device""" - stats = bdev.DRBD8Status(self.mass_data[6]) - self.failUnless(stats.is_in_use) - self.failUnless(stats.is_connected and stats.is_secondary and - stats.peer_primary and stats.is_diskless) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[6]) + self.failUnless(stats.is_in_use) + self.failUnless(stats.is_connected and stats.is_secondary and + stats.peer_primary and stats.is_diskless) def testMinor8(self): """Test standalone device""" - stats = bdev.DRBD8Status(self.mass_data[8]) - self.failUnless(stats.is_in_use) - self.failUnless(stats.is_standalone and - stats.rrole == 'Unknown' and - stats.is_disk_uptodate) + for data in [self.mass_data, self.mass83_data]: + stats = bdev.DRBD8Status(data[8]) + self.failUnless(stats.is_in_use) + self.failUnless(stats.is_standalone and + stats.rrole == 'Unknown' and + stats.is_disk_uptodate) if __name__ == '__main__': unittest.main() -- 1.7.10.4