Skip to content
Snippets Groups Projects
Commit 01e2ce3a authored by Iustin Pop's avatar Iustin Pop
Browse files

Fix compatibility with DRBD 8.3


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: default avatarIustin Pop <iustin@google.com>
parent 34e71fea
No related branches found
No related tags found
No related merge requests found
......@@ -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())
......
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;
}
File added
......@@ -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()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment