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 <[email protected]>
---
I don't have data files for drbd 8.2, but at least we can add them for 8.3.
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#p1zt...@lxjd9z0v5jvg_esvsjao)QNAuSghMrbi$U4!yy#<
z...@qd3lwdw~e2)vVaDBQ}bK+e0Bv$aLukGZ&uo?j;MT>3det{BOg<hh`P2}XPAKv9`z
zyq8ej<4pEdN=TZ)Y*myBW*eyHMfs4+I<7ZP-$O!(h)EhJ1E2{~flNd|5HgQLYmCln
zt-x7)b;VM;o?rv_yge`k...@gjce2twhiiw#o<H{j`2tt5d#j!Apx~UAxIyTLz)KA
z6l96vx3eX3C~f$n(qXJ*7_tgOS4d%PaR%0UBoWYKtUXS52Y3$aro|##qAeS5u-a`)
z8JNgrq`XB+8l<TSq2$H;%4rn=Ywq5jcKHRF-vgYQg|Tb%gLBkgUJ)O=I=<d<eCMr>
z3co0|_g7n`;&oz0tnmlf...@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.6.2.4